test/org/openjdk/jigsaw/TrivialWebServer.java
Print this page
@@ -25,18 +25,19 @@
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.net.*;
+import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import com.sun.net.httpserver.*;
import static java.lang.System.out;
-import static java.lang.System.err;
import static java.net.HttpURLConnection.*;
+import static java.util.concurrent.TimeUnit.*;
public class TrivialWebServer {
private boolean debug = System.getenv("TWS_DEBUG") != null;
@@ -54,17 +55,20 @@
for (Map.Entry<String,List<String>> e : hs.entrySet()) {
log.format(" %s : %s%n", e.getKey(), e.getValue());
}
}
- private static final SimpleDateFormat HTTP_DATE;
-
- static {
- HTTP_DATE = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'",
- Locale.US);
- HTTP_DATE.setTimeZone(TimeZone.getTimeZone("GMT"));
+ private static final String pattern = "EEE, dd MMM yyyy HH:mm:ss zzz";
+ private static final TimeZone gmtTZ = TimeZone.getTimeZone("GMT");
+ private static final ThreadLocal<DateFormat> HTTP_DATE =
+ new ThreadLocal<DateFormat>() {
+ @Override protected DateFormat initialValue() {
+ DateFormat df = new SimpleDateFormat(pattern, Locale.US);
+ df.setTimeZone(gmtTZ);
+ return df;
}
+ };
private class Handler
implements HttpHandler
{
@@ -78,10 +82,12 @@
}
private void notFound(HttpExchange hx, URI hxu)
throws IOException
{
+ if (debug)
+ log.format("HTTP_NOT_FOUND");
byte[] err
= ("<b>Not found: " + hxu + "</b>").getBytes("ASCII");
hx.sendResponseHeaders(HTTP_NOT_FOUND, err.length);
OutputStream os = hx.getResponseBody();
os.write(err);
@@ -98,11 +104,11 @@
URI hxu = hx.getRequestURI();
URI u = root.resolve(BARE_ROOT.relativize(hxu));
Path p = Paths.get(u);
if (debug) {
- log.format("%s --> %s%n", hxu, p);
+ log.format("%s %s --> %s%n", hx.getRequestMethod(), hxu, p);
dump("req", hx.getRequestHeaders());
}
if (!Files.exists(p)) {
notFound(hx, hxu);
return;
@@ -115,10 +121,12 @@
if (ba.isDirectory()) {
String us = hxu.toString();
if (!us.endsWith("/")) {
Headers ahs = hx.getResponseHeaders();
ahs.put("Location", Arrays.asList(us + "/"));
+ if (debug)
+ dump("HTTP_MOVED_PERM", ahs);
hx.sendResponseHeaders(HTTP_MOVED_PERM, -1);
return;
}
p = p.resolve("index.html");
if (!Files.exists(p)) {
@@ -130,45 +138,53 @@
if (debug)
log.format("%s --> %s%n", hxu, p);
// Check Last-Modified/ETag headers
//
- long mtime = ba.lastModifiedTime().toMillis();
+ DateFormat df = HTTP_DATE.get();
+ long mtime = ba.lastModifiedTime().to(TimeUnit.SECONDS);
String etag = etag(ba.fileKey());
Headers rhs = hx.getRequestHeaders();
String rmtime = rhs.getFirst("If-Modified-Since");
boolean condget = false;
boolean sendit = false;
if (rmtime != null) {
condget = true;
- long rmt = HTTP_DATE.parse(rmtime).getTime();
+ long rmt = SECONDS.convert(df.parse(rmtime).getTime(),
+ MILLISECONDS);
sendit = mtime > rmt;
}
String retag = rhs.getFirst("If-None-Match");
- boolean tagChanged = true;
if (retag != null) {
condget = true;
sendit = sendit || !retag.equals(etag);
}
if (condget && !sendit) {
+ if (debug)
+ out.format("HTTP_NOT_MODIFIED%n");
hx.sendResponseHeaders(HTTP_NOT_MODIFIED, -1);
return;
}
// Send content
//
Headers ahs = hx.getResponseHeaders();
ahs.set("Content-Type", "application/octet-stream");
ahs.set("Last-Modified",
- HTTP_DATE.format(new Date(mtime)));
+ df.format(new Date(MILLISECONDS.convert(mtime, SECONDS))));
if (etag != null)
ahs.set("ETag", etag);
if (debug)
- dump("ans", hx.getResponseHeaders());
+ dump("HTTP_OK", ahs);
+ if ("HEAD".equalsIgnoreCase(hx.getRequestMethod())) {
+ // HEAD: manually set the c-l and write no response body
+ ahs.set("Content-length", Long.toString(ba.size()));
+ hx.sendResponseHeaders(HTTP_OK, -1);
+ } else {
hx.sendResponseHeaders(HTTP_OK, ba.size());
Files.copy(p, hx.getResponseBody());
-
+ }
} catch (Exception x) {
x.printStackTrace(out);
} finally {
hx.close();
}