Package org.astrogrid.samp.httpd
Class HttpServer
- java.lang.Object
-
- org.astrogrid.samp.httpd.HttpServer
-
- Direct Known Subclasses:
CorsHttpServer
public class HttpServer extends java.lang.Object
Simple modular HTTP server. One thread is started per request. Connections are not kept open between requests. Suitable for very large response bodies, but not for very large request bodies. Add one or moreHttpServer.Handler
s to serve actual requests. The protocol version served is HTTP/1.0.This class is completely self-contained, so that it can easily be lifted out and used in other packages if required.
- Since:
- 21 Aug 2008
- Author:
- Mark Taylor
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interface
HttpServer.Handler
Implemented to serve data for some URLs.private static class
HttpServer.HttpException
Convenience class for representing an error whose content should be returned to the user as an HTTP erro response of some kind.(package private) static class
HttpServer.HttpHeaderMap
Map implementation suitable for storing HTTP headers.static class
HttpServer.Request
Represents a parsed HTTP client request.static class
HttpServer.Response
Represents a response to an HTTP request.
-
Field Summary
Fields Modifier and Type Field Description private java.net.URL
baseUrl_
private java.util.List
handlerList_
private static java.lang.String
HDR_CONTENT_LENGTH
static java.lang.String
HDR_CONTENT_TYPE
Header string for MIME content type.private static java.util.regex.Pattern
HEADER_PATTERN
private static java.lang.String
HTTP_TOKEN_REGEX
private static java.lang.String
HTTP_VERSION_REGEX
private boolean
isDaemon_
private static java.util.logging.Logger
logger_
private static java.util.regex.Pattern
REQUEST_LINE_PATTERN
private java.net.ServerSocket
serverSocket_
private static java.util.regex.Pattern
SIMPLE_REQUEST_PATTERN
private boolean
started_
static int
STATUS_OK
Status code for OK (200).private boolean
stopped_
private static java.lang.String
URI_REGEX
-
Constructor Summary
Constructors Constructor Description HttpServer()
Constructs a server based on a default socket, on any free port.HttpServer(java.net.ServerSocket socket)
Constructs a server based on a given socket.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
addHandler(HttpServer.Handler handler)
Adds a handler which can serve some requests going through this server.static HttpServer.Response
create405Response(java.lang.String[] supportedMethods)
Creates an HTTP response indicating that the requested method (GET, POST, etc) is not supported.static HttpServer.Response
createErrorResponse(int code, java.lang.String phrase)
Utility method to create an error response.static HttpServer.Response
createErrorResponse(int code, java.lang.String phrase, java.lang.Throwable e)
Utility method to create an error response given an exception.java.net.URL
getBaseUrl()
Returns the base URL for this server.static java.lang.String
getHeader(java.util.Map headerMap, java.lang.String key)
Returns a header value from a header map.java.net.ServerSocket
getSocket()
Returns the socket on which this server listens.boolean
isRunning()
Indicates whether this server is currently running.private static HttpServer.Request
parseRequest(java.io.InputStream in, java.net.SocketAddress remoteAddress)
Takes the input stream from a client connection and turns it into a Request object.private static java.lang.String[]
readHeaderLines(java.io.InputStream is)
Reads the header lines from an HTTP client connection input stream.void
removeHandler(HttpServer.Handler handler)
Removes a handler previously added byaddHandler(org.astrogrid.samp.httpd.HttpServer.Handler)
.HttpServer.Response
serve(HttpServer.Request request)
Does the work for providing output corresponding to a given HTTP request.protected void
serveRequest(java.net.Socket sock)
Called by the server thread for each new connection.void
setDaemon(boolean isDaemon)
Determines whether the server thread will be a daemon thread or not.void
start()
Starts the server if it is not already started.void
stop()
Stops the server if it is currently running.
-
-
-
Field Detail
-
serverSocket_
private final java.net.ServerSocket serverSocket_
-
isDaemon_
private boolean isDaemon_
-
handlerList_
private java.util.List handlerList_
-
baseUrl_
private final java.net.URL baseUrl_
-
started_
private volatile boolean started_
-
stopped_
private volatile boolean stopped_
-
HDR_CONTENT_TYPE
public static final java.lang.String HDR_CONTENT_TYPE
Header string for MIME content type.- See Also:
- Constant Field Values
-
HDR_CONTENT_LENGTH
private static final java.lang.String HDR_CONTENT_LENGTH
- See Also:
- Constant Field Values
-
STATUS_OK
public static final int STATUS_OK
Status code for OK (200).- See Also:
- Constant Field Values
-
URI_REGEX
private static final java.lang.String URI_REGEX
- See Also:
- Constant Field Values
-
HTTP_VERSION_REGEX
private static final java.lang.String HTTP_VERSION_REGEX
- See Also:
- Constant Field Values
-
HTTP_TOKEN_REGEX
private static final java.lang.String HTTP_TOKEN_REGEX
- See Also:
- Constant Field Values
-
SIMPLE_REQUEST_PATTERN
private static final java.util.regex.Pattern SIMPLE_REQUEST_PATTERN
-
REQUEST_LINE_PATTERN
private static final java.util.regex.Pattern REQUEST_LINE_PATTERN
-
HEADER_PATTERN
private static final java.util.regex.Pattern HEADER_PATTERN
-
logger_
private static final java.util.logging.Logger logger_
-
-
Constructor Detail
-
HttpServer
public HttpServer(java.net.ServerSocket socket)
Constructs a server based on a given socket.- Parameters:
socket
- listening socket
-
HttpServer
public HttpServer() throws java.io.IOException
Constructs a server based on a default socket, on any free port.- Throws:
java.io.IOException
-
-
Method Detail
-
addHandler
public void addHandler(HttpServer.Handler handler)
Adds a handler which can serve some requests going through this server.- Parameters:
handler
- handler to add
-
removeHandler
public void removeHandler(HttpServer.Handler handler)
Removes a handler previously added byaddHandler(org.astrogrid.samp.httpd.HttpServer.Handler)
.- Parameters:
handler
- handler to remove
-
getSocket
public java.net.ServerSocket getSocket()
Returns the socket on which this server listens.- Returns:
- server socket
-
getBaseUrl
public java.net.URL getBaseUrl()
Returns the base URL for this server.- Returns:
- base URL
-
serve
public HttpServer.Response serve(HttpServer.Request request)
Does the work for providing output corresponding to a given HTTP request. This implementation calls each Handler in turn and the first one to provide a non-null response is used.- Parameters:
request
- represents an HTTP request that has been received- Returns:
- represents the content of an HTTP response that should be sent
-
setDaemon
public void setDaemon(boolean isDaemon)
Determines whether the server thread will be a daemon thread or not. Must be called beforestart()
to have an effect. The default is true.- Parameters:
isDaemon
- whether server thread will be daemon- See Also:
Thread.setDaemon(boolean)
-
start
public void start()
Starts the server if it is not already started.
-
stop
public void stop()
Stops the server if it is currently running. Processing of any requests which have already been received is completed.
-
isRunning
public boolean isRunning()
Indicates whether this server is currently running.- Returns:
- true if running
-
serveRequest
protected void serveRequest(java.net.Socket sock) throws java.io.IOException
Called by the server thread for each new connection.- Parameters:
sock
- client connection socket- Throws:
java.io.IOException
-
parseRequest
private static HttpServer.Request parseRequest(java.io.InputStream in, java.net.SocketAddress remoteAddress) throws java.io.IOException
Takes the input stream from a client connection and turns it into a Request object. As a special case, if the input stream has no content at all, null is returned.- Parameters:
in
- input streamremoteAddress
- address of requesting client- Returns:
- parsed request, or null
- Throws:
java.io.IOException
-
readHeaderLines
private static java.lang.String[] readHeaderLines(java.io.InputStream is) throws java.io.IOException
Reads the header lines from an HTTP client connection input stream. All lines are read up to the first CRLF, which is when the body starts. The input stream is left in a state ready to read the first body line. As a special case, if the input stream has no content at all, null is returned.- Parameters:
is
- socket input stream- Returns:
- array of header lines (including initial request line); the terminal blank line is not included, or null
- Throws:
java.io.IOException
-
getHeader
public static java.lang.String getHeader(java.util.Map headerMap, java.lang.String key)
Returns a header value from a header map. Key value is case-insensitive. In the (undesirable) case that multiple keys with the same case-insensitive value exist, the values are concatenated with comma separators, as per RFC2616 section 4.2.- Parameters:
headerMap
- mapkey
- header key- Returns:
- value of map entry with case-insensitive match for key
-
createErrorResponse
public static HttpServer.Response createErrorResponse(int code, java.lang.String phrase)
Utility method to create an error response.- Parameters:
code
- status codephrase
- status phrase- Returns:
- new response object
-
create405Response
public static HttpServer.Response create405Response(java.lang.String[] supportedMethods)
Creates an HTTP response indicating that the requested method (GET, POST, etc) is not supported.- Parameters:
supportedMethods
- list of the methods which are supported- Returns:
- error response
-
createErrorResponse
public static HttpServer.Response createErrorResponse(int code, java.lang.String phrase, java.lang.Throwable e)
Utility method to create an error response given an exception.- Parameters:
code
- status codephrase
- status phrasee
- exception which caused the trouble- Returns:
- new response object
-
-