mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8278353: Provide Duke as default favicon in Simple Web Server
Reviewed-by: dfuchs
This commit is contained in:
parent
466a21d864
commit
7b79426a1d
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,3 +24,5 @@
|
||||
#
|
||||
|
||||
DISABLED_WARNINGS_java += missing-explicit-ctor this-escape
|
||||
|
||||
COPY += .ico
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -57,6 +57,9 @@ public final class FileServerHandler implements HttpHandler {
|
||||
private static final List<String> SUPPORTED_METHODS = List.of("HEAD", "GET");
|
||||
private static final List<String> UNSUPPORTED_METHODS =
|
||||
List.of("CONNECT", "DELETE", "OPTIONS", "PATCH", "POST", "PUT", "TRACE");
|
||||
private static final String FAVICON_RESOURCE_PATH =
|
||||
"/sun/net/httpserver/simpleserver/resources/favicon.ico";
|
||||
private static final String FAVICON_LAST_MODIFIED = "Mon, 23 May 1995 11:11:11 GMT";
|
||||
|
||||
private final Path root;
|
||||
private final UnaryOperator<String> mimeTable;
|
||||
@ -250,6 +253,31 @@ public final class FileServerHandler implements HttpHandler {
|
||||
return Files.exists(html) ? html : Files.exists(htm) ? htm : null;
|
||||
}
|
||||
|
||||
private static boolean isFavIconRequest(HttpExchange exchange) {
|
||||
return "/favicon.ico".equals(exchange.getRequestURI().getPath());
|
||||
}
|
||||
|
||||
private void serveDefaultFavIcon(HttpExchange exchange, boolean writeBody)
|
||||
throws IOException
|
||||
{
|
||||
var respHdrs = exchange.getResponseHeaders();
|
||||
try (var stream = getClass().getModule().getResourceAsStream(FAVICON_RESOURCE_PATH)) {
|
||||
var bytes = stream.readAllBytes();
|
||||
respHdrs.set("Content-Type", "image/x-icon");
|
||||
respHdrs.set("Last-Modified", FAVICON_LAST_MODIFIED);
|
||||
if (writeBody) {
|
||||
exchange.sendResponseHeaders(200, bytes.length);
|
||||
try (OutputStream os = exchange.getResponseBody()) {
|
||||
os.write(bytes);
|
||||
}
|
||||
} else {
|
||||
respHdrs.set("Content-Length", Integer.toString(bytes.length));
|
||||
exchange.sendResponseHeaders(200, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void serveFile(HttpExchange exchange, Path path, boolean writeBody)
|
||||
throws IOException
|
||||
{
|
||||
@ -371,17 +399,26 @@ public final class FileServerHandler implements HttpHandler {
|
||||
assert List.of("GET", "HEAD").contains(exchange.getRequestMethod());
|
||||
try (exchange) {
|
||||
discardRequestBody(exchange);
|
||||
boolean isHeadRequest = exchange.getRequestMethod().equals("HEAD");
|
||||
Path path = mapToPath(exchange, root);
|
||||
if (path != null) {
|
||||
exchange.setAttribute("request-path", path.toString()); // store for OutputFilter
|
||||
if (!Files.exists(path) || !Files.isReadable(path) || isHiddenOrSymLink(path)) {
|
||||
handleNotFound(exchange);
|
||||
} else if (exchange.getRequestMethod().equals("HEAD")) {
|
||||
} else if (isHeadRequest) {
|
||||
handleHEAD(exchange, path);
|
||||
} else {
|
||||
handleGET(exchange, path);
|
||||
}
|
||||
} else {
|
||||
if (isFavIconRequest(exchange)) {
|
||||
try {
|
||||
serveDefaultFavIcon(exchange, !isHeadRequest);
|
||||
return;
|
||||
} catch (IOException ignore) {
|
||||
// fall through to send the not-found response
|
||||
}
|
||||
}
|
||||
exchange.setAttribute("request-path", "could not resolve request URI path");
|
||||
handleNotFound(exchange);
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -76,6 +76,8 @@ public class SimpleFileServerTest {
|
||||
static final boolean ENABLE_LOGGING = true;
|
||||
static final Logger LOGGER = Logger.getLogger("com.sun.net.httpserver");
|
||||
|
||||
static final String EXPECTED_LAST_MODIFIED_OF_FAVICON = "Mon, 23 May 1995 11:11:11 GMT";
|
||||
|
||||
@BeforeTest
|
||||
public void setup() throws IOException {
|
||||
if (ENABLE_LOGGING) {
|
||||
@ -142,6 +144,65 @@ public class SimpleFileServerTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFavIconGET() throws Exception {
|
||||
var root = Files.createDirectory(TEST_DIR.resolve("testFavIconGET"));
|
||||
|
||||
var server = SimpleFileServer.createFileServer(LOOPBACK_ADDR, root, OutputLevel.VERBOSE);
|
||||
server.start();
|
||||
try {
|
||||
// expect built-in icon
|
||||
var client = HttpClient.newBuilder().proxy(NO_PROXY).build();
|
||||
var request = HttpRequest.newBuilder(uri(server, "favicon.ico")).build();
|
||||
var response = client.send(request, BodyHandlers.ofString());
|
||||
assertEquals(response.statusCode(), 200);
|
||||
assertEquals(response.headers().firstValue("content-type").get(), "image/x-icon");
|
||||
assertEquals(response.headers().firstValue("last-modified").get(), EXPECTED_LAST_MODIFIED_OF_FAVICON);
|
||||
|
||||
// expect custom (and broken) icon
|
||||
var file = Files.writeString(root.resolve("favicon.ico"), "broken icon", CREATE);
|
||||
try {
|
||||
var lastModified = getLastModified(file);
|
||||
var expectedLength = Long.toString(Files.size(file));
|
||||
response = client.send(request, BodyHandlers.ofString());
|
||||
assertEquals(response.statusCode(), 200);
|
||||
assertEquals(response.headers().firstValue("content-type").get(), "application/octet-stream");
|
||||
assertEquals(response.headers().firstValue("content-length").get(), expectedLength);
|
||||
assertEquals(response.headers().firstValue("last-modified").get(), lastModified);
|
||||
} finally {
|
||||
Files.delete(file);
|
||||
}
|
||||
|
||||
// expect built-in icon
|
||||
response = client.send(request, BodyHandlers.ofString());
|
||||
assertEquals(response.statusCode(), 200);
|
||||
assertEquals(response.headers().firstValue("content-type").get(), "image/x-icon");
|
||||
assertEquals(response.headers().firstValue("last-modified").get(), EXPECTED_LAST_MODIFIED_OF_FAVICON);
|
||||
} finally {
|
||||
server.stop(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFavIconHEAD() throws Exception {
|
||||
var root = Files.createDirectory(TEST_DIR.resolve("testFavIconHEAD"));
|
||||
|
||||
var server = SimpleFileServer.createFileServer(LOOPBACK_ADDR, root, OutputLevel.VERBOSE);
|
||||
server.start();
|
||||
try {
|
||||
var client = HttpClient.newBuilder().proxy(NO_PROXY).build();
|
||||
var request = HttpRequest.newBuilder(uri(server, "favicon.ico"))
|
||||
.method("HEAD", BodyPublishers.noBody()).build();
|
||||
var response = client.send(request, BodyHandlers.ofString());
|
||||
assertEquals(response.statusCode(), 200);
|
||||
assertEquals(response.headers().firstValue("content-type").get(), "image/x-icon");
|
||||
assertEquals(response.headers().firstValue("last-modified").get(), EXPECTED_LAST_MODIFIED_OF_FAVICON);
|
||||
assertEquals(response.body(), "");
|
||||
} finally {
|
||||
server.stop(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileHEAD() throws Exception {
|
||||
var root = Files.createDirectory(TEST_DIR.resolve("testFileHEAD"));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user