- Joined
- Dec 11, 2010
- Messages
- 2,955
- Reaction score
- 2,688
duckHTTPD
duckHTTPD is a small scalable HTTP web server API written in Java that uses libraries like Netty, this server can easily be hooked into for customised control of requests and handling. duckHTTPD also supports templating and file requests with the correct MIME type.
Features
* Scalable non-blocking web server
* Customised route handling
* Template hooking
* Default web page handling
* Ability to serve static files such as pictures, media content, CSS, js, etc!
* Error handling
* POST request handling
* GET request handling
* Cookie handling (set and get cookies)
* Session data handling (keep data persistent for as long as the browser is open, securely and server-side only, simillar to PHP's $_SESSION variable).
* Page redirection
* Internally supports Keep-Alive connections
Example
A simple implementation of the API is found below, please note, this is an extremely basic example and if you wish use more features then I recommend you keep scrolling down.
This server will listen on the specified port given by the arguments, and the URL request
Hello, World!
...*and that's the example finished! (For now anyways)*
Route Handling
To manipulate the incoming requests and to decide what should be sent back, you just simply need to register a route shown in the example above. With Java 8 it's possible to use Lambda functions to decide which specific methods in a class will handle each request.
Make sure you import RouteManager class from the duckHTTPD package.
NOTE: Routes being handled always take first priority over static files and directories in the Site directory setting.
The SiteController class should look like this below:
To have a global hook into ALL routes, just use "addRoute("", SiteController::global)" and every single route will be passed through this function, before it's actual route gets handled.
Error Handling
By default, there will be default error pages for HTTP responses, 404 (Not Found), 403 (Forbidden) and 500 (Internal Server Error). You can hook into the error handling class by using the example provided below, by using the Settings.java class provided by the API.
You should then proceed to implement four methods, the first three being default error handlers where you can find the Exception management for the Internal Server Error handler.
The last method is not called automatically by the server, this is just a generic method that can be used by the person (you, hopefully) that will use this API.
If you want to use the default response for one of these methods, simply use the DefaultWebResponse class and return the method it gaves, it will never be null.
Static Files
If you want to use files such as CSS and JS files to create the rest of your website, duckHTTPD will take care of that, all that's required is for you to define where that directory is to help locate the files when a HTTP request is sent.
The example below shows that it will look inside the tools/www folder (relative to this server's working directory) and it will return any files over HTTP that's been requested.
If what's been requested is only a directory, the HTTP server will return a 403 Forbidden response, there is absolutely no way for people to look inside directories, or any other directories outside of www/tools.
So lets say you have a CSS file called example.css and it's located in "/tools/www/css/" then it means that accessing
NOTE: Routes being handled always take first priority over static files and directories in the Site directory setting.
Template Hooking
Another feature of duckHTTPD is hooking a template system into the HTTP server. You need to tell Settings the template hook class.
This class we specified must extend Template class from the duckHTTPD package. Your class should by default appear like the example below:
The the first parameter in the "start(String templateFile)" method is for the template file it's looking for. I recommend for something like below to search for the specific file.
Which means it will search in "www-tpl/<filename>.tpl" directory. The start() method should load the file data and save it as a field. The"set(String key, Object value)" should manipulate its field by the key and set it by value.
The "render()" method must set the response to the WebConnection client by using ResponseBuilder on the remaining HTML, like below, when using JTwig for example:
And in your controller it should be handled like below.
Integrate into Gradle
Make sure the DuckHTTPD project files are in the folder above your project, example shown below, where ExampleProject is your main product that is using DuckHTTPD API.
In settings.gradle add this
And in your project's build.gradle, add this
Or just download the JAR
All the JAR releases can be found here:
duckHTTPD is a small scalable HTTP web server API written in Java that uses libraries like Netty, this server can easily be hooked into for customised control of requests and handling. duckHTTPD also supports templating and file requests with the correct MIME type.
You must be registered to see links
Features
* Scalable non-blocking web server
* Customised route handling
* Template hooking
* Default web page handling
* Ability to serve static files such as pictures, media content, CSS, js, etc!
* Error handling
* POST request handling
* GET request handling
* Cookie handling (set and get cookies)
* Session data handling (keep data persistent for as long as the browser is open, securely and server-side only, simillar to PHP's $_SESSION variable).
* Page redirection
* Internally supports Keep-Alive connections
Example
A simple implementation of the API is found below, please note, this is an extremely basic example and if you wish use more features then I recommend you keep scrolling down.
Code:
int port = Integer.parseInt(args[0]);
System.out.println("Starting duckhttpd service on port " + port);
RouteManager.addRoute("/example", new Route() {
@Override
public void handleRoute(WebConnection client) throws Exception {
client.setResponse(ResponseBuilder.create("<h2>Hello, World!</h2>"));
}
});
WebServer server = new WebServer(port);
try {
server.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
You must be registered to see links
will previewHello, World!
...*and that's the example finished! (For now anyways)*
Route Handling
To manipulate the incoming requests and to decide what should be sent back, you just simply need to register a route shown in the example above. With Java 8 it's possible to use Lambda functions to decide which specific methods in a class will handle each request.
Make sure you import RouteManager class from the duckHTTPD package.
NOTE: Routes being handled always take first priority over static files and directories in the Site directory setting.
Code:
RouteManager.addRoute("/news", SiteController::news);
RouteManager.addRoute("/about", SiteController::about);
Code:
public class SiteController {
public static void news(WebConnection client) {
client.setResponse(ResponseBuilder.create("<p>The news page!</p>"));
}
public static void about(WebConnection client) {
client.setResponse(ResponseBuilder.create("<p>The about page!</p>"));
}
Error Handling
By default, there will be default error pages for HTTP responses, 404 (Not Found), 403 (Forbidden) and 500 (Internal Server Error). You can hook into the error handling class by using the example provided below, by using the Settings.java class provided by the API.
Code:
Settings settings = Settings.getInstance();
settings.setResponses(new CustomWebResponses());
The last method is not called automatically by the server, this is just a generic method that can be used by the person (you, hopefully) that will use this API.
Code:
public class CustomWebResponses implements WebResponses {
@Override
public FullHttpResponse getForbiddenResponse(WebConnection client) {
return null;
}
@Override
public FullHttpResponse getNotFoundResponse(WebConnection client) {
return null;
}
@Override
public FullHttpResponse getInternalServerErrorResponse(WebConnection client, Throwable cause) {
return null;
}
@Override
public FullHttpResponse getErrorResponse(WebConnection client, String header, String message) {
return null;
}
}
Code:
@Override
public FullHttpResponse getForbiddenResponse(WebConnection client) {
return new DefaultWebResponse().getForbiddenResponse(client);
}
Static Files
If you want to use files such as CSS and JS files to create the rest of your website, duckHTTPD will take care of that, all that's required is for you to define where that directory is to help locate the files when a HTTP request is sent.
Code:
Settings settings = Settings.getInstance();
settings.setSiteDirectory("tools/www");
If what's been requested is only a directory, the HTTP server will return a 403 Forbidden response, there is absolutely no way for people to look inside directories, or any other directories outside of www/tools.
So lets say you have a CSS file called example.css and it's located in "/tools/www/css/" then it means that accessing
You must be registered to see links
will return that CSS file, if it exists, otherwise it will return a 404.NOTE: Routes being handled always take first priority over static files and directories in the Site directory setting.
Template Hooking
Another feature of duckHTTPD is hooking a template system into the HTTP server. You need to tell Settings the template hook class.
Code:
Settings settings = Settings.getInstance();
settings.setTemplateHook(ExampleTemplate.class);
Code:
public class ExampleTemplate extends Template {
public ExampleTemplate(WebConnection webConnection) {
super(webConnection);
}
@Override
public void start(String templateFile) throws Exception {
}
@Override
public void set(String key, Object value) {
}
@Override
public void render() {
return null;
}
}
Code:
File file = Paths.get("www-tpl", view + ".tpl").toFile();
Which means it will search in "www-tpl/<filename>.tpl" directory. The start() method should load the file data and save it as a field. The"set(String key, Object value)" should manipulate its field by the key and set it by value.
The "render()" method must set the response to the WebConnection client by using ResponseBuilder on the remaining HTML, like below, when using JTwig for example:
Code:
@Override
public void render() {
FullHttpResponse response = ResponseBuilder.create(this.template.render(this.model));
this.webConnection.setResponse(response);
}
Code:
public static void news(WebConnection client) throws Exception {
Template tpl = client.template("news");
tpl.set("text", "value here");
tpl.render();
}
Integrate into Gradle
Make sure the DuckHTTPD project files are in the folder above your project, example shown below, where ExampleProject is your main product that is using DuckHTTPD API.
Code:
/projects
../DuckHTTPD
../ExampleProject
Code:
// https://github.com/Quackster/duckHTTPD/
include 'duckHTTPD'
project(":duckHTTPD").projectDir = file("../duckHTTPD")
Code:
dependencies {
// https://github.com/Quackster/duckHTTPD/
compile project(':duckHTTPD')
}
Or just download the JAR
All the JAR releases can be found here:
You must be registered to see links