blob: 4dddb18573c98643ece673245e306cce6f3d7de8 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.netbeans.html.presenters.browser;
import java.io.IOException;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import static org.testng.Assert.*;
import org.testng.annotations.Test;
public class SimpleServerTest {
public SimpleServerTest() {
}
@Test(dataProviderClass = ServerFactories.class, dataProvider = "serverFactories")
public void testConnectionToTheServer(String name, Supplier<HttpServer<?,?,?,?>> serverProvider) throws IOException {
if (serverProvider == null) {
return;
}
int min = 42343;
int max = 49343;
HttpServer<?, ?, ?, ?> server = serverProvider.get();
server.init(min, max);
server.addHttpHandler(new HttpServer.Handler() {
@Override
<Request, Response> void service(HttpServer<Request, Response, ?, ?> server, Request rqst, Response rspns) throws IOException {
assertEquals(server.getServerName(rqst), "localhost", "Connecting from localhost");
assertEquals(server.getServerPort(rqst), server.getPort(), "Connecting via local port");
assertEquals(server.getMethod(rqst), "GET", "Requesting GET");
server.setCharacterEncoding(rspns, "UTF-8");
server.setContentType(rspns, "text/x-test");
Browser.cors(server, rspns);
try (Writer w = server.getWriter(rspns)) {
final String n = server.getParameter(rqst, "name");
final String reply;
switch (server.getRequestURI(rqst)) {
case "/reply/hi": reply = "Ahoj " + n + "!"; break;
case "/reply/tchus": reply = "Ciao " + n + "!"; break;
default: reply = "What?";
}
w.write(reply);
}
}
}, "/reply");
server.start();
int realPort = server.getPort();
assertTrue(realPort <= max && realPort >= min, "Port from range (" + min + ", " + max + ") selected: " + realPort);
final String baseUri = "http://localhost:" + realPort;
assertURL("Ahoj John!", baseUri, "/reply/hi?name=John");
assertURL("Ciao John!", baseUri, "/reply/tchus?name=John");
server.shutdownNow();
}
private static void assertURL(String msg, String baseUri, final String path) throws IOException, MalformedURLException {
URL url = new URL(baseUri + path);
URLConnection conn = url.openConnection();
final String contentAndAttribs = conn.getContentType();
assertNotNull(contentAndAttribs, "Content-Type specified");
int semicolon = contentAndAttribs.indexOf(';');
final String content = semicolon == -1 ? contentAndAttribs : contentAndAttribs.substring(0, semicolon);
assertEquals(content, "text/x-test");
byte[] arr = new byte[8192];
int len = conn.getInputStream().read(arr);
assertNotEquals(len, -1, "Something shall be read");
String txt = new String(arr, 0, len, StandardCharsets.UTF_8);
assertEquals(txt, msg, "Message from the handler delivered");
assertEquals(conn.getHeaderField("Access-Control-Allow-Origin"), "*");
}
@Test(dataProviderClass = ServerFactories.class, dataProvider = "serverFactories")
public void testHeadersAndBody(String name, Supplier<HttpServer<?,?,?,?>> serverProvider) throws IOException {
if (serverProvider == null) {
return;
}
int min = 42343;
int max = 49343;
HttpServer<?, ?, ?, ?> server = serverProvider.get();
server.init(min, max);
server.addHttpHandler(new HttpServer.Handler() {
@Override
<Request, Response> void service(HttpServer<Request, Response, ?, ?> server, Request rqst, Response rspns) throws IOException {
StringBuilder sb = new StringBuilder(server.getBody(rqst));
server.setCharacterEncoding(rspns, "UTF-8");
server.setContentType(rspns, "text/plain");
try (Writer w = server.getWriter(rspns)) {
final String action = server.getHeader(rqst, "action");
assertNotNull(action, "action is specified");
String reply;
switch (action) {
case "reverse": reply = sb.reverse().toString(); break;
case "upper": reply = sb.toString().toUpperCase(); break;
default: reply = "What?";
}
w.write(reply);
}
}
}, "/action");
server.start();
int realPort = server.getPort();
assertTrue(realPort <= max && realPort >= min, "Port from range (" + min + ", " + max + ") selected: " + realPort);
final String baseUri = "http://localhost:" + realPort;
assertReadURL("reverse", "Ahoj", baseUri, "johA");
assertReadURL("upper", "Ahoj", baseUri, "AHOJ");
server.shutdownNow();
}
private static void assertReadURL(String action, String data, String baseUri, final String exp) throws IOException, MalformedURLException {
URL url = new URL(baseUri + "/action");
URLConnection conn = url.openConnection();
conn.addRequestProperty("action", action);
conn.setDoOutput(true);
conn.connect();
conn.getOutputStream().write(data.getBytes());
final String contentAndAttribs = conn.getContentType();
assertNotNull(contentAndAttribs, "Content-Type specified");
int semicolon = contentAndAttribs.indexOf(';');
final String content = semicolon == -1 ? contentAndAttribs : contentAndAttribs.substring(0, semicolon);
assertEquals(content, "text/plain");
byte[] arr = new byte[8192 * 8];
int offset = 0;
for (;;) {
int len = conn.getInputStream().read(arr, offset, arr.length - offset);
if (len == -1) {
break;
}
offset += len;
}
assertNotEquals(offset, 0, "Something shall be read");
String txt = new String(arr, 0, offset, StandardCharsets.UTF_8);
assertEquals(txt, exp, "Message from the handler delivered");
}
@Test(dataProviderClass = ServerFactories.class, dataProvider = "serverFactories")
public void testWaitForData(String name, Supplier<HttpServer<?,?,?,?>> serverProvider) throws IOException {
if (serverProvider == null) {
return;
}
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
int min = 32343;
int max = 33343;
HttpServer<?, ?, ?, ?> server = serverProvider.get();
server.init(min, max);
class HandlerImpl extends HttpServer.Handler {
@Override
<Request, Response> void service(HttpServer<Request, Response, ?, ?> server, Request rqst, Response rspns) throws IOException {
server.setCharacterEncoding(rspns, "UTF-8");
server.setContentType(rspns, "text/x-test");
Browser.cors(server, rspns);
server.suspend(rspns);
exec.schedule((Callable <Void>) () -> {
server.resume(rspns, () -> {
Writer w = server.getWriter(rspns);
try {
w.write("Finished!");
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
});
return null;
}, 1, TimeUnit.SECONDS);
}
}
server.addHttpHandler(new HandlerImpl(), "/async");
server.start();
int realPort = server.getPort();
assertTrue(realPort <= max && realPort >= min, "Port from range (" + min + ", " + max + ") selected: " + realPort);
final String baseUri = "http://localhost:" + realPort;
assertURL("Finished!", baseUri, "/async");
exec.shutdown();
server.shutdownNow();
}
@Test(dataProviderClass = ServerFactories.class, dataProvider = "serverFactories")
public void testEnormousBody(String name, Supplier<HttpServer<?,?,?, ?>> serverProvider) throws IOException {
if (serverProvider == null) {
return;
}
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
int min = 32343;
int max = 33343;
HttpServer<?, ?, ?, ?> server = serverProvider.get();
server.init(min, max);
String id = veryLongId();
class HandlerImpl extends HttpServer.Handler {
@Override
<Request, Response> void service(HttpServer<Request, Response, ?, ?> server, Request rqst, Response rspns) throws IOException {
server.setCharacterEncoding(rspns, "UTF-8");
server.setContentType(rspns, "text/plain");
Browser.cors(server, rspns);
assertEquals("lower", server.getHeader(rqst, "action"));
String gotId = server.getBody(rqst);
if (!gotId.equals(id)) {
fail("Id as expected by " + server + " isn't the same " + id.length() + " != " + gotId.length());
}
server.getWriter(rspns).write(gotId.toLowerCase());
}
}
server.addHttpHandler(new HandlerImpl(), "/action");
server.start();
int realPort = server.getPort();
assertTrue(realPort <= max && realPort >= min, "Port from range (" + min + ", " + max + ") selected: " + realPort);
final String baseUri = "http://localhost:" + realPort;
assertReadURL("lower", id, baseUri, id.toLowerCase());
exec.shutdown();
server.shutdownNow();
}
private static String veryLongId() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
final int max = 'Z' - 'A';
int ch = 'A' + (i % max);
sb.append((char) ch);
}
return sb.toString();
}
}