/*
* Copyright (C) 2015 SoftIndex LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.datakernel.http;
import io.datakernel.async.*;
import io.datakernel.bytebuf.ByteBuf;
import io.datakernel.bytebuf.ByteBufStrings;
import io.datakernel.eventloop.Eventloop;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static io.datakernel.async.AsyncRunnables.runInParallel;
import static io.datakernel.bytebuf.ByteBufPool.*;
import static io.datakernel.bytebuf.ByteBufStrings.decodeAscii;
import static io.datakernel.bytebuf.ByteBufStrings.encodeAscii;
import static io.datakernel.eventloop.FatalErrorHandlers.rethrowOnAnyError;
import static io.datakernel.http.HttpHeaders.*;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertNull;
import static org.junit.Assert.assertEquals;
public class AbstractHttpConnectionTest {
private static final int PORT = 5050;
private static final String url = "http://127.0.0.1:" + PORT;
private Eventloop eventloop = Eventloop.create().withFatalErrorHandler(rethrowOnAnyError());
private AsyncHttpClient client = AsyncHttpClient.create(eventloop);
@Test
public void testMultiLineHeader() throws Exception {
AsyncServlet servlet = new AsyncServlet() {
@Override
public void serve(HttpRequest request, ResultCallback<HttpResponse> callback) {
callback.setResult(createMultiLineHeaderWithInitialBodySpacesResponse());
}
};
final AsyncHttpServer server = AsyncHttpServer.create(eventloop, servlet)
.withListenPort(PORT);
server.listen();
final CompletionCallbackFuture future = CompletionCallbackFuture.create();
final Map<String, String> data = new HashMap<>();
client.send(HttpRequest.get(url), new ForwardingResultCallback<HttpResponse>(future) {
@Override
public void onResult(HttpResponse result) {
data.put("body", decodeAscii(result.getBody()));
data.put("header", result.getHeader(CONTENT_TYPE));
stopClientAndServer(client, server, future);
}
});
eventloop.run();
future.get();
assertEquals("text/ html", data.get("header"));
assertEquals(" <html>\n<body>\n<h1>Hello, World!</h1>\n</body>\n</html>", data.get("body"));
assertEquals(getPoolItemsString(), getCreatedItems(), getPoolItems());
}
private HttpResponse createMultiLineHeaderWithInitialBodySpacesResponse() {
HttpResponse response = HttpResponse.ok200();
response.addHeader(DATE, "Mon, 27 Jul 2009 12:28:53 GMT");
response.addHeader(CONTENT_TYPE, "text/\n html");
response.setBody(ByteBufStrings.wrapAscii(" <html>\n<body>\n<h1>Hello, World!</h1>\n</body>\n</html>"));
return response;
}
@Test
public void testGzipCompression() throws Exception {
AsyncServlet servlet = new AsyncServlet() {
boolean first = true;
@Override
public void serve(HttpRequest request, ResultCallback<HttpResponse> callback) {
HttpResponse response = HttpResponse.ok200();
if (!first) {
response.withBody((ByteBuf) null);
callback.setResult(response);
assertNull(response.getHeaderValue(CONTENT_ENCODING));
} else {
first = false;
response.withBody(encodeAscii("Test message"));
callback.setResult(response);
assertNotNull(response.getHeaderValue(CONTENT_ENCODING));
}
}
};
final AsyncHttpServer server = AsyncHttpServer.create(eventloop, servlet)
.withGzipResponses(true)
.withListenPort(PORT);
server.listen();
final CompletionCallbackFuture future = CompletionCallbackFuture.create();
client.send(HttpRequest.get(url).withHeader(ACCEPT_ENCODING, "gzip"),
new ForwardingResultCallback<HttpResponse>(future) {
@Override
protected void onResult(HttpResponse result) {
assertNotNull(result.getHeaderValue(CONTENT_ENCODING));
client.send(HttpRequest.get(url), new ForwardingResultCallback<HttpResponse>(future) {
@Override
protected void onResult(HttpResponse result) {
assertNull(result.getHeaderValue(CONTENT_ENCODING));
stopClientAndServer(client, server, future);
}
});
}
}
);
eventloop.run();
future.get();
assertEquals(getPoolItemsString(), getCreatedItems(), getPoolItems());
}
private void stopClientAndServer(final AsyncHttpClient client, final AsyncHttpServer server,
CompletionCallbackFuture callback) {
runInParallel(
eventloop,
new AsyncRunnable() {
@Override
public void run(CompletionCallback callback) {
server.close(callback);
}
},
new AsyncRunnable() {
@Override
public void run(CompletionCallback callback) {
client.stop(callback);
}
})
.run(callback);
}
}