Skip to content
Permalink
Browse files
8277459: Add jwebserver tool
Reviewed-by: michaelm, dfuchs, ihse
  • Loading branch information
FrauBoes committed Dec 1, 2021
1 parent 84aa0a1 commit f505396cccdd00a284b516dee1e314d1bf285f9e
Showing 17 changed files with 1,028 additions and 70 deletions.
@@ -0,0 +1,30 @@
#
# Copyright (c) 2021, 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
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#

include LauncherCommon.gmk

$(eval $(call SetupBuildLauncher, jwebserver, \
MAIN_CLASS := sun.net.httpserver.simpleserver.JWebServer, \
))
@@ -104,12 +104,12 @@
* server.start();
* }</pre>
*
* <h2>Main entry point</h2>
* <h2>jwebserver Tool</h2>
*
* <p>A <a id="server-impl">simple HTTP file server implementation</a> is
* provided via the
* <a href="{@docRoot}/jdk.httpserver/module-summary.html#entry-point">main entry point</a>
* of the {@code jdk.httpserver} module.
* <p>A simple HTTP file server implementation is provided via the
* {@code jwebserver} tool.
*
* @toolGuide jwebserver
*
* @since 18
*/
@@ -31,6 +31,24 @@
Any HTTP functionality not provided by this API can be implemented by application code
using the API.
<p>
* The main components are:
* <ul>
* <li>the {@link com.sun.net.httpserver.HttpExchange} class that describes a
* request and response pair,</li>
* <li>the {@link com.sun.net.httpserver.HttpHandler} interface to handle
* incoming requests, plus the {@link com.sun.net.httpserver.HttpHandlers} class
* that provides useful handler implementations,</li>
* <li>the {@link com.sun.net.httpserver.HttpContext} class that maps a URI path
* to a {@code HttpHandler},</li>
* <li>the {@link com.sun.net.httpserver.HttpServer} class to listen for
* connections and dispatch requests to handlers,</li>
* <li>the {@link com.sun.net.httpserver.Filter} class that allows pre- and post-
* processing of requests.</li></ul>
* <p>
* The {@link com.sun.net.httpserver.SimpleFileServer} class offers a simple
* HTTP-only file server (intended for testing, development and debugging purposes
* only). A default implementation is provided via the {@code jwebserver} tool.
<p>
Programmers must implement the {@link com.sun.net.httpserver.HttpHandler} interface. This interface
provides a callback which is invoked to handle incoming requests from clients.
A HTTP request and its response is known as an exchange. HTTP exchanges are
@@ -120,13 +138,6 @@ public void configure (HttpsParameters params) {
}
});
</pre></blockquote>
<p>
The {@link com.sun.net.httpserver.SimpleFileServer} class offers a simple
HTTP file server (intended for testing, development and debugging purposes
only). A default implementation is provided via the
<a href="{@docRoot}/jdk.httpserver/module-summary.html#entry-point">main entry point</a>
of the {@code jdk.httpserver} module.
@since 1.6
*/
package com.sun.net.httpserver;
@@ -24,41 +24,21 @@
*/

/**
* Defines the JDK-specific HTTP server API.
* <p>
* A basic high-level API for building embedded servers. Both HTTP and
* HTTPS are supported.
* <p>
* The main components are:
* <ul>
* <li>the {@link com.sun.net.httpserver.HttpExchange} class that describes a
* request and response pair,</li>
* <li>the {@link com.sun.net.httpserver.HttpHandler} interface to handle
* incoming requests, plus the {@link com.sun.net.httpserver.HttpHandlers} class
* that provides useful handler implementations,</li>
* <li>the {@link com.sun.net.httpserver.HttpContext} class that maps a URI path
* to a {@code HttpHandler},</li>
* <li>the {@link com.sun.net.httpserver.HttpServer} class to listen for
* connections and dispatch requests to handlers,</li>
* <li>the {@link com.sun.net.httpserver.Filter} class that allows pre- and post-
* processing of requests.</li></ul>
* <p>
* The {@link com.sun.net.httpserver.SimpleFileServer} class offers a simple
* HTTP file server (intended for testing, development and debugging purposes
* only). A default implementation is provided via the <a id="entry-point"></a>
* main entry point of the {@code jdk.httpserver} module, which can be used on
* the command line as such:
* <pre>{@code
* Usage: java -m jdk.httpserver [-b bind address] [-p port] [-d directory]
* [-o none|info|verbose] [-h to show options]
* Options:
* -b, --bind-address - Address to bind to. Default: 127.0.0.1 or ::1 (loopback).
* For all interfaces use "-b 0.0.0.0" or "-b ::".
* -d, --directory - Directory to serve. Default: current directory.
* -o, --output - Output format. none|info|verbose. Default: info.
* -p, --port - Port to listen on. Default: 8000.
* -h, -?, --help - Print this help message.
* }</pre>
* Defines the JDK-specific HTTP server API, and provides the jwebserver tool
* for running a minimal HTTP server.
*
* <p>The {@link com.sun.net.httpserver} package defines a high-level API for
* building servers that support HTTP and HTTPS. The SimpleFileServer class
* implements a simple HTTP-only file server intended for testing, development
* and debugging purposes. A default implementation is provided via the
* {@code jwebserver} tool and the main entry point of the module, which can
* also be invoked with {@code java -m jdk.httpserver}.
*
* <p>The {@link com.sun.net.httpserver.spi} package specifies a Service Provider
* Interface (SPI) for locating HTTP server implementations based on the
* {@code com.sun.net.httpserver} API.
*
* @toolGuide jwebserver
*
* @uses com.sun.net.httpserver.spi.HttpServerProvider
*
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2021, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package sun.net.httpserver.simpleserver;

import java.io.PrintWriter;
import static java.nio.charset.StandardCharsets.UTF_8;

/**
* Programmatic entry point to start the jwebserver tool.
*
* <p><b> This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interface are subject to change or deletion
* without notice.</b>
*/
public class JWebServer {

/**
* This constructor should never be called.
*/
private JWebServer() { throw new AssertionError(); }

/**
* The main entry point.
*
* <p> The command line arguments are parsed and the server is started. If
* started successfully, the server will run on a new non-daemon thread,
* and this method will return. Otherwise, if the server is not started
* successfully, e.g. an error is encountered while parsing the arguments
* or an I/O error occurs, the server is not started and this method invokes
* System::exit with an appropriate exit code.
*
* @param args the command-line options
* @throws NullPointerException if {@code args} is {@code null}, or if there
* are any {@code null} values in the {@code args} array
*/
public static void main(String... args) {
int ec = SimpleFileServerImpl.start(new PrintWriter(System.out, true, UTF_8), "jwebserver", args);
if (ec != 0) {
System.exit(ec);
} // otherwise, the server has either been started successfully and
// runs in another non-daemon thread, or -h or -version have been
// passed and the main thread has exited normally.
}
}
@@ -27,7 +27,7 @@
import static java.nio.charset.StandardCharsets.UTF_8;

/**
* Programmatic entry point to start the simpleserver tool.
* Programmatic entry point to start "java -m jdk.httpserver".
*
* <p><b> This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
@@ -56,10 +56,11 @@ public class Main {
* are any {@code null} values in the {@code args} array
*/
public static void main(String... args) {
int ec = SimpleFileServerImpl.start(new PrintWriter(System.out, true, UTF_8), args);
if (ec != 0)
int ec = SimpleFileServerImpl.start(new PrintWriter(System.out, true, UTF_8), "java", args);
if (ec != 0) {
System.exit(ec);
// otherwise the server has been started successfully and runs in
// another non-daemon thread.
} // otherwise, the server has either been started successfully and
// runs in another non-daemon thread, or -h or -version have been
// passed and the main thread has exited normally.
}
}
@@ -71,11 +71,12 @@ final class SimpleFileServerImpl {
*
* @param writer the writer to which output should be written
* @param args the command line options
* @param launcher the launcher the server is started from
* @throws NullPointerException if any of the arguments are {@code null},
* or if there are any {@code null} values in the {@code args} array
* @return startup status code
*/
static int start(PrintWriter writer, String[] args) {
static int start(PrintWriter writer, String launcher, String[] args) {
Objects.requireNonNull(args);
for (var arg : args) {
Objects.requireNonNull(arg);
@@ -96,7 +97,11 @@ static int start(PrintWriter writer, String[] args) {
option = options.next();
switch (option) {
case "-h", "-?", "--help" -> {
out.showHelp();
out.showHelp(launcher);
return Startup.OK.statusCode;
}
case "-version", "--version" -> {
out.showVersion(launcher);
return Startup.OK.statusCode;
}
case "-b", "--bind-address" -> {
@@ -115,7 +120,7 @@ static int start(PrintWriter writer, String[] args) {
}
} catch (AssertionError ae) {
out.reportError(ResourceBundleHelper.getMessage("err.unknown.option", option));
out.showUsage();
out.showUsage(launcher);
return Startup.CMDERR.statusCode;
} catch (NoSuchElementException nsee) {
out.reportError(ResourceBundleHelper.getMessage("err.missing.arg", option));
@@ -169,12 +174,16 @@ void printStartMessage(Path root, HttpServer server)
}
}

void showUsage() {
writer.println(ResourceBundleHelper.getMessage("usage"));
void showUsage(String launcher) {
writer.println(ResourceBundleHelper.getMessage("usage." + launcher));
}

void showVersion(String launcher) {
writer.println(ResourceBundleHelper.getMessage("version", launcher, System.getProperty("java.version")));
}

void showHelp() {
writer.println(ResourceBundleHelper.getMessage("usage"));
void showHelp(String launcher) {
writer.println(ResourceBundleHelper.getMessage("usage." + launcher));
writer.println(ResourceBundleHelper.getMessage("options", LOOPBACK_ADDR.getHostAddress()));
}

@@ -23,9 +23,18 @@
# questions.
#

usage=\
usage.java=\
Usage: java -m jdk.httpserver [-b bind address] [-p port] [-d directory]\n\
\ [-o none|info|verbose] [-h to show options]
\ [-o none|info|verbose] [-h to show options]\n\
\ [-version to show version information]

usage.jwebserver=\
Usage: jwebserver [-b bind address] [-p port] [-d directory]\n\
\ [-o none|info|verbose] [-h to show options]\n\
\ [-version to show version information]

version=\
{0} {1}

options=\
Options:\n\
@@ -34,7 +43,8 @@ Options:\n\
-d, --directory - Directory to serve. Default: current directory.\n\
-o, --output - Output format. none|info|verbose. Default: info.\n\
-p, --port - Port to listen on. Default: 8000.\n\
-h, -?, --help - Print this help message.\n\
-h, -?, --help - Prints this help message and exits.\n\
-version, --version - Prints version information and exits.\n\
To stop the server, press Ctrl + C.

opt.bindaddress=\

1 comment on commit f505396

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on f505396 Dec 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.