/*
* 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;
import io.datakernel.async.IgnoreCompletionCallback;
import io.datakernel.async.ResultCallback;
import io.datakernel.eventloop.Eventloop;
import io.datakernel.exception.ParseException;
import io.datakernel.http.*;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.net.InetAddress;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.concurrent.ExecutionException;
import static io.datakernel.bytebuf.ByteBufPool.*;
import static io.datakernel.eventloop.FatalErrorHandlers.rethrowOnAnyError;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@SuppressWarnings("ConstantConditions")
public class HttpApiTest {
public static final int PORT = 5568;
private static final InetAddress GOOGLE_PUBLIC_DNS = HttpUtils.inetAddress("8.8.8.8");
private Eventloop eventloop;
private AsyncHttpServer server;
private AsyncHttpClient client;
// request
private List<AcceptMediaType> requestAcceptContentTypes = new ArrayList<>();
private List<AcceptCharset> requestAcceptCharsets = new ArrayList<>();
private Date requestDate = createDate(1999, 1, 1);
private Date dateIMS = createDate(2012, 18, 1);
private Date dateIUMS = createDate(1972, 0, 1);
private MediaType requestMime = MediaTypes.ANY_TEXT;
private ContentType requestContentType = ContentType.of(requestMime);
private List<HttpCookie> requestCookies = new ArrayList<>();
// response
private Date responseDate = createDate(2000, 11, 17);
private Date expiresDate = createDate(2011, 2, 22);
private Date lastModified = createDate(2099, 11, 13);
private MediaType responseMime = MediaType.of("font/woff2");
private Charset responseCharset = StandardCharsets.UTF_16LE;
private ContentType responseContentType = ContentType.of(responseMime, responseCharset);
private List<HttpCookie> responseCookies = new ArrayList<>();
private int age = 10_000;
@Before
public void setUp() {
eventloop = Eventloop.create().withFatalErrorHandler(rethrowOnAnyError());
AsyncServlet servlet = new AsyncServlet() {
@Override
public void serve(HttpRequest request, ResultCallback<HttpResponse> callback) {
try {
testRequest(request);
HttpResponse response = createResponse();
callback.setResult(response);
} catch (ParseException e) {
callback.setException(e);
}
}
};
server = AsyncHttpServer.create(eventloop, servlet).withListenPort(PORT);
client = AsyncHttpClient.create(eventloop);
// setup request and response data
requestAcceptContentTypes.add(AcceptMediaType.of(MediaTypes.ANY_AUDIO, 90));
requestAcceptContentTypes.add(AcceptMediaType.of(MediaTypes.ANY));
requestAcceptContentTypes.add(AcceptMediaType.of(MediaTypes.ATOM));
requestAcceptContentTypes.add(AcceptMediaType.of(MediaType.of("hello/world")));
requestAcceptCharsets.add(AcceptCharset.of(Charset.forName("UTF-8")));
requestAcceptCharsets.add(AcceptCharset.of(Charset.forName("ISO-8859-5"), 10));
requestAcceptCharsets.add(AcceptCharset.of(Charset.forName("ISO-8859-2"), 10));
requestAcceptCharsets.add(AcceptCharset.of(Charset.forName("ISO-8859-3"), 10));
HttpCookie cookie2 = HttpCookie.of("name1", "value1");
requestCookies.add(cookie2);
HttpCookie cookie3 = HttpCookie.of("name3");
requestCookies.add(cookie3);
HttpCookie cookie1 = HttpCookie.of("name2", "value2");
cookie1.setMaxAge(123);
cookie1.setExpirationDate(new Date());
responseCookies.add(cookie1);
}
@Test
public void test() throws IOException, ExecutionException, InterruptedException {
server.listen();
HttpRequest request = createRequest();
client.send(request, new ResultCallback<HttpResponse>() {
@Override
protected void onResult(HttpResponse result) {
try {
testResponse(result);
} catch (ParseException e) {
fail("Invalid response");
}
server.close(IgnoreCompletionCallback.create());
client.stop(IgnoreCompletionCallback.create());
}
@Override
protected void onException(Exception e) {
fail("Should not end here");
server.close(IgnoreCompletionCallback.create());
client.stop(IgnoreCompletionCallback.create());
}
});
eventloop.run();
assertEquals(getPoolItemsString(), getCreatedItems(), getPoolItems());
}
private HttpResponse createResponse() {
HttpResponse response = HttpResponse.ok200();
response.withDate(responseDate);
response.withExpires(expiresDate);
response.withContentType(responseContentType);
response.withCookies(responseCookies);
response.withLastModified(lastModified);
response.withAge(age);
return response;
}
private HttpRequest createRequest() {
return HttpRequest.get("http://127.0.0.1:" + PORT)
.withAccept(requestAcceptContentTypes)
.withAcceptCharsets(requestAcceptCharsets)
.withDate(requestDate)
.withContentType(requestContentType)
.withIfModifiedSince(dateIMS)
.withIfUnModifiedSince(dateIUMS)
.withCookies(requestCookies);
}
private void testResponse(HttpResponse response) throws ParseException {
assertEquals(responseContentType.toString(), response.getContentType().toString());
assertEquals(responseCookies.toString(), response.getCookies().toString());
assertEquals(responseDate.toString(), response.getDate().toString());
assertEquals(age, response.getAge());
assertEquals(expiresDate.toString(), response.getExpires().toString());
assertEquals(lastModified.toString(), response.getLastModified().toString());
}
private void testRequest(HttpRequest request) throws ParseException {
assertEquals(requestAcceptContentTypes.toString(), request.getAccept().toString());
assertEquals(requestAcceptCharsets.toString(), request.getAcceptCharsets().toString());
assertEquals(requestDate.toString(), request.getDate().toString());
assertEquals(dateIMS.toString(), request.getIfModifiedSince().toString());
assertEquals(dateIUMS.toString(), request.getIfUnModifiedSince().toString());
assertEquals(requestContentType.toString(), request.getContentType().toString());
assertEquals(requestCookies.toString(), request.getCookies().toString());
}
private static Date createDate(int year, int month, int day) {
return new GregorianCalendar(year, month, day).getTime();
}
}