JLHTTP - Java Lightweight HTTP Server (Web Server)
What is the Java Lightweight HTTP Server?The Java Lightweight HTTP Server is an open-source implementation of an HTTP Server (a.k.a. web server). It is lightweight, i.e. small and efficient, yet provides various useful features commonly found in heavier HTTP servers. It can be used both as a standalone web server, and as an easily embedded server for integration into existing applications. This is commonly used to provide a convenient GUI (Graphical User Interface) which can be viewed across the network in a cross-platform manner from any computer with a web browser (just about all of them).
This server implements all functionality required by RFC 2616 ("Hypertext Transfer Protocol -- HTTP/1.1"), as well as some of the optional functionality (this is termed "conditionally compliant" in the RFC).
Feature highlights are:
- RFC compliant - correctness is not sacrificed for the sake of size
- Virtual hosts - multiple domains and subdomains per server
- File serving - built-in handler to serve files and folders from disk
- Mime type mappings - configurable via API or a standard mime.types file
- Directory index generation - enables browsing folder contents
- Welcome files - configurable default filename (e.g. index.html)
- All HTTP methods supported - GET/HEAD/OPTIONS/TRACE/POST/PUT/DELETE/custom
- Conditional statuses - ETags and If-* header support
- Chunked transfer encoding - for serving dynamically-generated data streams
- Gzip/deflate compression - reduces bandwidth and download time
- HTTPS - secures all server communications
- Partial content - download continuation (a.k.a. byte range serving)
- File upload - multipart/form-data handling as stream or iterator
- Multiple context handlers - a different handler method per URL path
- @Context annotations - auto-detection of context handler methods
- Parameter parsing - from query string or multipart/form-data body
- A single source file - super-easy to integrate into any application
- Standalone - no dependencies other than the Java runtime
- Small footprint - standard jar is ~50K, stripped jar is ~35K
- Extensible design - easy to override, add or remove functionality
- Reusable utility methods to simplify your custom code
- Extensive documentation of API and implementation (>40% of source lines)
What can the Java Lightweight HTTP Server be used for?Being a lightweight, standalone, easily embeddable and tiny-footprint server, it is well-suited for:
- Resource-constrained environments such as embedded devices. For really extreme constraints, you can easily remove unneeded functionality to make it even smaller (also make sure to compile without debug info and strip the jar of unnecessary files)
- Unit and integration tests - fast setup/teardown times, small overhead and simple context handler setup make it a great web server for testing client components under various server response conditions.
- Embedding a web console into any headless application for administration, monitoring, or a full portable GUI.
- A full-fledged standalone web server serving static files, dynamically-generated content, REST APIs, pseudo-streaming, etc.
- A good reference for learning how HTTP works under the hood.
How do I use the Java Lightweight HTTP Server?This server is intentionally written as a single source file, in order to make it as easy as possible to integrate into any existing project - by simply adding this single file to the project sources. It can also be used like any other library, by including the jar file in the application classpath.
It is also available on Maven Central at the artifact coordinates
See the javadocs in the source file for the full API details. Examining the source code of the main method can be a good starting point for understanding how to embed the server in your application, as well.
The server can also be run as a standalone application from the command
line using the command
'java -jar jlhttp-2.3.jar' to serve files under
a specified directory with no need for additional configuration.
FAQMake sure to read the FAQ, which includes additional information and sample code.
What's New?In version 2.3:
- Fixed missing welcome page when accessing non-root base context path without trailing slash.
- Added context to Request.
- Added path to ContextInfo.
- Removed redundant context path from FileContextHandler (now taken from request).
- Simplified and optimized VirtualHost.getContext method.
- Optimized Request.getVirtualHost and Request.getContext lookups.
In version 2.2:
- Fixed graceful socket closing error handling.
- Changed ETag generated for string content to be weak.
- Changed If-None-Match ETag handling to use weak matching algorithm.
- Added Vary Accept-Encoding header to responses.
- Added accessors for MultipartIterator.Part class fields.
- Added setSocketTimeout setter.
In version 2.1:
- Set setReuseAddress (SO_REUSEADDR) on server socket for quicker restarts.
- Set setTcpNoDelay (TCP_NODELAY) on sockets for lower latency.
- Added connection close header when responding to request that sent it.
- Added connection close header when closing connection due to error.
- Changed connection to close if response contains connection close header.
- Removed error response when client disconnects between requests.
- Fixed clearing existing headers when sending generic 500 error response.
- Changed handleConnection to always close response, even on error after headers sent.
- Added graceful socket closing (half-close and consume input before final close).
- Added 408 Request Timeout support.
- Optimized formatDate by reimplementing it without SimpleDateFormat.
- Optimized bulk writes to response body stream.
- Optimized ISO-8859-1/US-ASCII string encoding using getBytes utility method.
- Optimized Request.getBaseURL reuse by caching parsed value.
- Replaced Headers.iterator implementation to avoid extra 1.5K class file.
- Changed transfer method to accept null OutputStream for discarding output.
- Optimized transfer when discarding empty output.
- Removed SocketHandlerThread constructor.
- Removed Request.consumeBody method.
- Improved javadocs and misc. minor refactorings.
In version 2.0:
- Changed ChunkedOutputStream to write a chunk per standard write method invocation.
- Added ChunkedOutputStream.close which writes trailing chunk if necessary.
- Changed Response.sendHeaders to add chunked transfer encoding if length is unknown.
- Changed Response.getBody to create encoding streams automatically according to headers.
- Added Response.getOutputStream to get raw unencoded output stream.
- Removed Response.getChunkedBody method.
- Removed Response.isDiscardBody method.
- Changed Response to implement Closeable for closing and flushing all streams.
- Added gzip/deflate response compression support.
- Added HTTPS support.
- Fixed uncaught exception handling, error response and connection termination.
- Removed persistent connections for HTTP/1.0 requests.
- Changed connection persistence to work even if request/response body streams are closed.
- Added isCompressible method to determine which content types can be compressed.
- Added parameter to splitElements for converting elements to lowercase.
- Changed lower-case conversions to ignore system locale.
- Changed Response.sendHeaders to throw exception if headers were already sent.
- Improved Transfer-Encoding header parsing.
- Improved javadocs and misc. minor refactorings.
In version 1.3:
- Added support for content type mapping via standard mime.types file.
- Added full support for different HTTP method handlers per context.
- Improved compliance of built-in HTTP method handling: OPTIONS *, Allow header, 405 status, etc.
- Replaced parseParams utility method with parseParamsList for access to multi-valued parameters.
- Fixed MultipartInputStream handling of several valid and invalid inputs.
- Fixed MultipartInputStream.fill when reading form a very slow input stream.
- Optimized MultipartInputStream buffer fill using partial boundary detection.
- Optimized MultipartInputStream latency by returning data as soon as it is available.
- Optimized MultipartInputStream performance by reducing in-memory copying.
- Updated Server response header string and version number.
- Fixed formatDate GMT time calculation.
- Fixed serving non-directory files ending with a slash.
- Changed Range header to be ignored if content is empty (return 200 instead of 416).
- Changed files starting with dot to return 404 on all platforms.
- Changed handleConnection method to accept input/output streams instead of socket.
- Changed split method to support multiple delimiters.
- Added Request.getParamsList method.
- Added toMap and join utility methods.
- Added sample dynamic context handler to main method.
- Migrated to Maven build system, directory structure and artifact conventions.
- Added OSGi headers to jar manifest.
- Fixed javadoc errors when building with JDK 8.
- Revamped HTTPServer class documentation with feature list, use cases and getting started sections.
- Improved javadocs and misc. minor refactorings.
In version 1.2:
- Split handleTransaction into preprocessTransaction and handleMethod, making it easier for subclasses to add filters.
- Added MultipartIterator.Part.getString() convenience method to get a form input value as a string.
- Added Response.getChunkedBody helper method to encourage proper use when body length is unknown.
- Renamed utility method parseULong (parseLong) and changed it to treat sign characters as invalid.
- Renamed utility methods trimLeft (ltrim), trimRight (rtrim), and toSizeApproxString (toSizeString).
- Added @Override annotations.
- Changed index and error pages HTML markup to use the HTML5 doctype.
- Added explanation on how to support file uploads (via MultipartIterator).
- Improved documentation and misc. minor refactorings.
In version 1.1:
- Made jar file executable (added Main-Class attribute to manifest).
- Fixed generated index date format on non-US locale (always use US).
- Fixed Request.parseParams() preserving of parameter order.
- Added no-arg constructor and setPort() method to allow post-construction port setting.
- Fixed serveFile() appending of relative path to base directory.
- Fixed double-slash when accessing root folder.
- Added file upload support using the MultipartInputStream and MultipartIterator classes.
- Added ltrim utility method.
- Added parseParameters() method for easy header parameter handling.
- Fixed sendError() default text for success statuses.
- Changed default error text to include both status code and status description.
- Improved documentation.
In version 1.0:
- This is the first release of the Java Lightweight HTTP Server.
LicenseThe JLHTTP Package is provided under the GNU General Public License agreement.
For non-GPL commercial licensing please contact the author.
DonateIf you like it, why not give something back?
ContactYou can contact the author via e-mail at:
Please write in with any bugs, suggestions, fixes, contributions, or just to drop a good word and let me know you've found the JLHTTP Package useful and you'd like it to keep being maintained.
For updates and additional information, you can always visit the website at: