Skip to content

Commit

Permalink
Update the JreAppServer to use HttpHandlers
Browse files Browse the repository at this point in the history
  • Loading branch information
shs96c committed Jul 4, 2019
1 parent d062f62 commit 644776d
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 165 deletions.
25 changes: 25 additions & 0 deletions java/client/test/org/openqa/selenium/environment/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
load("//java:rules.bzl", "java_test_suite")

java_library(
name = "environment",
srcs = glob(
Expand Down Expand Up @@ -42,3 +44,26 @@ java_binary(
":environment",
],
)

java_library(
name = "test-base",
srcs = ["webserver/AppServerTestBase.java"],
deps = [
":environment",
"//java/client/src/org/openqa/selenium:core",
"//java/client/src/org/openqa/selenium/remote/http",
"//java/client/src/org/openqa/selenium/support",
"//java/client/test/org/openqa/selenium/testing/drivers",
"//third_party/java/junit",
],
)

java_test_suite(
name = "MediumTests",
size = "medium",
srcs = glob(["**/*Test.java"]),
deps = [
":environment",
":test-base",
]
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.openqa.selenium.remote.http.Contents.string;

import org.junit.After;
import org.junit.AfterClass;
Expand Down Expand Up @@ -119,13 +120,6 @@ public void manifestHasCorrectMimeType() throws IOException {
assertUrlHasContentType(server.whereIs("html5/test.appcache"), APPCACHE_MIME_TYPE);
}

@Test
public void manifestHasCorrectMimeTypeUnderJavascript() throws IOException {
String appcacheUrl =
server.whereIs("/javascript/atoms/test/html5/testdata/with_fallback.appcache");
assertUrlHasContentType(appcacheUrl, APPCACHE_MIME_TYPE);
}

@Test
public void uploadsFile() throws Throwable {
String FILE_CONTENTS = "Uploaded file";
Expand All @@ -150,6 +144,8 @@ private void assertUrlHasContentType(String url, String appcacheMimeType) throws
HttpClient client = factory.createClient(new URL(url));
HttpResponse response = client.execute(new HttpRequest(HttpMethod.GET, url));

System.out.printf("Content for %s was %s\n", url, string(response));

assertTrue(StreamSupport.stream(response.getHeaders("Content-Type").spliterator(), false)
.anyMatch(header -> header.contains(appcacheMimeType)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,27 @@

package org.openqa.selenium.environment.webserver;

import static java.nio.charset.StandardCharsets.UTF_16LE;
import static org.openqa.selenium.remote.http.Contents.string;

import org.openqa.selenium.remote.http.HttpHandler;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.util.function.BiConsumer;
import java.io.UncheckedIOException;

import static java.nio.charset.StandardCharsets.UTF_16LE;
import static org.openqa.selenium.remote.http.Contents.string;

public class EncodingHandler implements BiConsumer<HttpRequest, HttpResponse> {
public class EncodingHandler implements HttpHandler {

@Override
public void accept(HttpRequest request, HttpResponse response) {
// Data should be transferred using UTF-8. Pick a different encoding
response.setHeader("Content-Type", "text/html;charset=UTF-16LE");

public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
String text = "<html><title>Character encoding (UTF 16)</title>"
+ "<body><p id='text'>"
+ "\u05E9\u05DC\u05D5\u05DD" // "Shalom"
+ "</p></body></html>";
response.setContent(string(text, UTF_16LE));
+ "<body><p id='text'>"
+ "\u05E9\u05DC\u05D5\u05DD" // "Shalom"
+ "</p></body></html>";

// Data should be transferred using UTF-8. Pick a different encoding
return new HttpResponse()
.setHeader("Content-Type", "text/html;charset=UTF-16LE")
.setContent(string(text, UTF_16LE));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,13 @@

package org.openqa.selenium.environment.webserver;

import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
import static com.google.common.net.MediaType.JSON_UTF_8;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;
import static org.openqa.selenium.build.InProject.locate;
import static org.openqa.selenium.remote.http.Contents.bytes;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.Contents.utf8String;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

import com.google.common.collect.ImmutableMap;

import com.google.common.io.ByteStreams;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpServer;

import org.openqa.selenium.json.Json;
import org.openqa.selenium.net.PortProber;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpMethod;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.http.*;

import java.io.IOException;
import java.io.InputStream;
Expand All @@ -49,25 +32,27 @@
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
import static com.google.common.net.MediaType.JSON_UTF_8;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;
import static org.openqa.selenium.build.InProject.locate;
import static org.openqa.selenium.remote.http.Contents.bytes;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.Route.*;

public class JreAppServer implements AppServer {

private final HttpServer server;
private final Map<Predicate<HttpRequest>, BiConsumer<HttpRequest, HttpResponse>> mappings =
new LinkedHashMap<>(); // Insert order matters.
private HttpHandler handler;

public JreAppServer() {
try {
Expand All @@ -77,51 +62,40 @@ public JreAppServer() {
server.createContext(
"/", httpExchange -> {
HttpRequest req = new SunHttpRequest(httpExchange);
HttpResponse resp = new SunHttpResponse(httpExchange);

List<Predicate<HttpRequest>> reversedKeys = new ArrayList<>(mappings.keySet());
Collections.reverse(reversedKeys);

reversedKeys.stream()
.filter(pred -> pred.test(req))
.findFirst()
.map(mappings::get)
.orElseGet(() -> (in, out) -> {
out.setStatus(404);
out.setContent(utf8String(""));
})
.accept(req, resp);
});

emulateJettyAppServer();

HttpResponse res = handler.execute(req);

res.getHeaderNames().forEach(
name -> res.getHeaders(name).forEach(value -> httpExchange.getResponseHeaders().add(name, value)));
httpExchange.sendResponseHeaders(res.getStatus(), 0);

try (InputStream in = res.getContent().get();
OutputStream out = httpExchange.getResponseBody()) {
ByteStreams.copy(in, out);
}
});

setHandler(emulateJettyAppServer());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

protected JreAppServer emulateJettyAppServer() {
String common = locate("common/src/web").toAbsolutePath().toString();
// Listed first, so considered last
addHandler(
GET,
"/",
new StaticContent(
path -> Paths.get(common + path)));

addHandler(GET, "/encoding", new EncodingHandler());
addHandler(GET, "/page", new PageHandler());
addHandler(GET, "/redirect", new RedirectHandler(whereIs("/")));
addHandler(GET, "/sleep", new SleepingHandler());
addHandler(POST, "/upload", new UploadHandler());

return this;
public Route emulateJettyAppServer() {
Path common = locate("common/src/web").toAbsolutePath();
System.out.printf("Common is: '%s'\n", common);

return Route.combine(
matching(req -> true).to(() -> new StaticContent(path -> Paths.get(common + path), common::resolve)),
get("/encoding").to(EncodingHandler::new),
matching(req -> req.getUri().startsWith("/page/")).to(PageHandler::new),
get("/redirect").to(() -> new RedirectHandler(whereIs("/"))),
get("/sleep").to(SleepingHandler::new),
post("/upload").to(UploadHandler::new));
}

public JreAppServer addHandler(
HttpMethod method,
String url,
BiConsumer<HttpRequest, HttpResponse> handler) {
mappings.put(req -> req.getMethod().equals(method) && req.getUri().startsWith(url), handler);
public JreAppServer setHandler(HttpHandler handler) {
this.handler = Objects.requireNonNull(handler);
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,30 @@

package org.openqa.selenium.environment.webserver;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.openqa.selenium.remote.http.Contents.utf8String;

import org.openqa.selenium.remote.http.HttpHandler;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.util.function.BiConsumer;
import java.io.UncheckedIOException;

import static org.openqa.selenium.remote.http.Contents.utf8String;

public class PageHandler implements BiConsumer<HttpRequest, HttpResponse> {
public class PageHandler implements HttpHandler {

@Override
public void accept(HttpRequest request, HttpResponse response) {
response.setHeader("Content-Type", "text/html");
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {

int lastIndex = request.getUri().lastIndexOf('/');
int lastIndex = req.getUri().lastIndexOf('/');
String pageNumber =
(lastIndex == -1 ? "Unknown" : request.getUri().substring(lastIndex + 1));
String res = String.format("<html><head><title>Page%s</title></head>" +
(lastIndex == -1 ? "Unknown" : req.getUri().substring(lastIndex + 1));
String body = String.format("<html><head><title>Page%s</title></head>" +
"<body>Page number <span id=\"pageNumber\">%s</span>" +
"<p><a href=\"../xhtmlTest.html\" target=\"_top\">top</a>" +
// "<script>var s=''; for (var i in window) {s += i + ' -> ' + window[i] + '<p>';} document.write(s);</script>"
// +
"</body></html>",
pageNumber, pageNumber);

response.setContent(utf8String(res));
return new HttpResponse()
.setHeader("Content-Type", "text/html")
.setContent(utf8String(body));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@

package org.openqa.selenium.environment.webserver;

import static java.net.HttpURLConnection.HTTP_MOVED_TEMP;
import static org.openqa.selenium.remote.http.Contents.utf8String;

import org.openqa.selenium.remote.http.HttpHandler;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.util.function.BiConsumer;
import java.io.UncheckedIOException;

import static java.net.HttpURLConnection.HTTP_MOVED_TEMP;
import static org.openqa.selenium.remote.http.Contents.utf8String;

public class RedirectHandler implements BiConsumer<HttpRequest, HttpResponse> {
public class RedirectHandler implements HttpHandler {

private final String root;

Expand All @@ -34,9 +35,10 @@ public RedirectHandler(String root) {
}

@Override
public void accept(HttpRequest request, HttpResponse response) {
response.setStatus(HTTP_MOVED_TEMP);
response.setHeader("Location", root + "resultPage.html");
response.setContent(utf8String(""));
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
return new HttpResponse()
.setStatus(HTTP_MOVED_TEMP)
.setHeader("Location", root + "resultPage.html")
.setContent(utf8String(""));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,33 @@

package org.openqa.selenium.environment.webserver;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.openqa.selenium.remote.http.Contents.utf8String;

import org.openqa.selenium.remote.http.HttpHandler;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.util.function.BiConsumer;
import java.io.UncheckedIOException;

public class SleepingHandler implements BiConsumer<HttpRequest, HttpResponse> {
import static org.openqa.selenium.remote.http.Contents.utf8String;

public class SleepingHandler implements HttpHandler {

private static final String RESPONSE_STRING_FORMAT =
"<html><head><title>Done</title></head><body>Slept for %ss</body></html>";

@Override
public void accept(HttpRequest request, HttpResponse response) {
String duration = request.getQueryParameter("time");
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
String duration = req.getQueryParameter("time");
long timeout = Long.valueOf(duration) * 1000;

reallySleep(timeout);

response.setHeader("Content-Type", "text/html");
//Dont Cache Anything at the browser
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
response.setHeader("Expires", "0");

response.setContent(utf8String(String.format(RESPONSE_STRING_FORMAT, duration)));
return new HttpResponse()
.setHeader("Content-Type", "text/html")
//Dont Cache Anything at the browser
.setHeader("Cache-Control","no-cache")
.setHeader("Pragma","no-cache")
.setHeader("Expires", "0")
.setContent(utf8String(String.format(RESPONSE_STRING_FORMAT, duration)));
}

private void reallySleep(long timeout) {
Expand Down
Loading

0 comments on commit 644776d

Please sign in to comment.