Skip to content

Instantly share code, notes, and snippets.

@TanyaGaleyev
Last active May 18, 2017 13:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TanyaGaleyev/fe143077fc635cc9adf73e8b0779adf1 to your computer and use it in GitHub Desktop.
Save TanyaGaleyev/fe143077fc635cc9adf73e8b0779adf1 to your computer and use it in GitHub Desktop.
Vertx HttpServer and no-message-body responses
package org.ivan.vertx.nobody;
import io.vertx.core.Vertx;
import org.junit.Assert;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
public class NoBodyResponseTest {
@Test
public void headMustNotHaveIncorrectContentLength() throws Exception {
int port = startServer();
URL url = new URL("http", "localhost", port, "/length");
URLConnection initialConnection = url.openConnection();
String contentLength = initialConnection.getHeaderField("Content-Length");
byte[] bytes = new byte[1024];
while (initialConnection.getInputStream().read(bytes) != -1);
HttpURLConnection connection = ((HttpURLConnection) url.openConnection());
connection.setRequestMethod("HEAD");
connection.getHeaderFields().forEach((name, values) -> {
values.forEach(value -> System.out.println(name + ": " + value));
});
Optional<String> headContentLength = Optional.ofNullable(connection.getHeaderField("Content-Length"));
if (headContentLength.isPresent()) {
Assert.assertEquals(contentLength, headContentLength.get());
}
}
@Test
public void headMustNotHaveContentAndContentLength() throws Exception {
int port = startServer();
head(port, "/chunked");
}
@Test
public void headMustNotHaveContentAndContentLength2() throws Exception {
int port = startServer();
head(port, "/chunked2");
}
private int startServer() {
int port = 8888;
CompletableFuture<Void> serverStarted = new CompletableFuture<>();
Vertx.vertx().createHttpServer()
.requestHandler(new ServerHandler())
.listen(port, ar -> serverStarted.complete(null));
serverStarted.join();
return port;
}
private void head(int port, String path) throws IOException {
Map<String, String> headers = new LinkedHashMap<>();
int contentLines = 0;
try (Socket socket = new Socket("localhost", port)) {
PrintStream writer = new PrintStream(socket.getOutputStream(), true);
writer.print("HEAD " + path + " HTTP/1.1\r\n");
writer.print("Host: localhost: " + port + "\r\n");
writer.print("\r\n");
BufferedReader reader = new BufferedReader(new InputStreamReader(
socket.getInputStream(), StandardCharsets.UTF_8));
String line;
// read response line
System.out.println(reader.readLine());
// read first header (possibly empty)
System.out.println(readHeader(reader, headers));
// read remaining headers
while ((line = readHeader(reader, headers)) != null) {
System.out.println(line);
if (line.isEmpty()) break;
}
while ((line = reader.readLine()) != null) {
System.out.println(line);
contentLines++;
}
}
Assert.assertNull(headers.get("content-length"));
Assert.assertEquals(0, contentLines);
}
private String readHeader(BufferedReader reader, Map<String, String> headers) throws IOException {
String header = reader.readLine();
if (header != null && !header.isEmpty()) {
int i = header.indexOf(":");
headers.put(
header.substring(0, i).trim().toLowerCase(),
header.substring(i + 1, header.length()).trim());
}
return header;
}
}
package org.ivan.vertx.nobody;
import io.vertx.core.Handler;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
public class ServerHandler implements Handler<HttpServerRequest> {
@Override
public void handle(HttpServerRequest request) {
HttpServerResponse response = request.response();
switch (request.method()) {
case HEAD:
setResponseHeaders(request, response);
response.end();
break;
case GET:
setResponseHeaders(request, response);
response.end(generateContent());
break;
default:
response.setStatusCode(405);
break;
}
request.connection().close();
}
private String generateContent() {
return new Object().toString();
}
private void setResponseHeaders(HttpServerRequest request, HttpServerResponse response) {
response.putHeader("Server", "TestVertxServer/1.0");
if (request.uri().equals("/chunked")) {
response.setChunked(true);
} else if (request.uri().equals("/chunked2")) {
response.putHeader("Transfer-Encoding", "chunked");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment