Menu
Forums
All threads
Latest threads
New posts
Trending threads
New posts
Search forums
Trending
What's new
New posts
New profile posts
Latest activity
Members
Current visitors
New profile posts
Search profile posts
Upgrades
Log in
Register
What's new
Search
Search
Search titles only
By:
All threads
Latest threads
New posts
Trending threads
New posts
Search forums
Menu
Log in
Register
Navigation
Install the app
Install
More options
Contact us
Close Menu
Forums
Software Development
Programming
[Library] DuckHTTPD - Scalable HTTP web server API written in Java
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an
alternative browser
.
Reply to thread
Message
<blockquote data-quote="Quackster" data-source="post: 422238" data-attributes="member: 971"><p><strong><span style="font-size: 26px">duckHTTPD</span></strong></p><p></p><p>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.</p><p></p><p><a href="https://github.com/Quackster/duckHTTPD" target="_blank">https://github.com/Quackster/duckHTTPD</a></p><p></p><p><span style="font-size: 18px">Features</span></p><p>* Scalable non-blocking web server</p><p>* Customised route handling</p><p>* Template hooking</p><p>* Default web page handling</p><p>* Ability to serve static files such as pictures, media content, CSS, js, etc!</p><p>* Error handling</p><p>* POST request handling</p><p>* GET request handling</p><p>* Cookie handling (set and get cookies)</p><p>* 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).</p><p>* Page redirection</p><p>* Internally supports Keep-Alive connections</p><p></p><p><span style="font-size: 18px">Example</span></p><p>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.</p><p></p><p>[code]int port = Integer.parseInt(args[0]);</p><p>System.out.println("Starting duckhttpd service on port " + port);</p><p></p><p>RouteManager.addRoute("/example", new Route() {</p><p> @Override</p><p> public void handleRoute(WebConnection client) throws Exception {</p><p> client.setResponse(ResponseBuilder.create("<h2>Hello, World!</h2>"));</p><p> }</p><p>});</p><p></p><p>WebServer server = new WebServer(port);</p><p>try {</p><p> server.start();</p><p>} catch (InterruptedException e) {</p><p> e.printStackTrace();</p><p>}[/code]</p><p>This server will listen on the specified port given by the arguments, and the URL request <a href="http://localhost/example" target="_blank">http://localhost/example</a> will preview</p><p></p><p><strong><span style="font-size: 18px">Hello, World!</span></strong></p><p></p><p>...*and that's the example finished! (For now anyways)*</p><p></p><p><span style="font-size: 18px">Route Handling</span></p><p>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.</p><p></p><p>Make sure you import <strong>RouteManager</strong> class from the duckHTTPD package.</p><p></p><p><strong>NOTE:</strong> Routes being handled always take first priority over static files and directories in the Site directory setting.</p><p></p><p>[code]RouteManager.addRoute("/news", SiteController::news);</p><p>RouteManager.addRoute("/about", SiteController::about);[/code]</p><p>The SiteController class should look like this below:</p><p></p><p>[code]public class SiteController {</p><p></p><p> public static void news(WebConnection client) {</p><p> client.setResponse(ResponseBuilder.create("<p>The news page!</p>"));</p><p> }</p><p> </p><p> public static void about(WebConnection client) {</p><p> client.setResponse(ResponseBuilder.create("<p>The about page!</p>"));</p><p> }[/code]</p><p>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.</p><p></p><p><span style="font-size: 18px">Error Handling</span></p><p>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.</p><p></p><p>[code] Settings settings = Settings.getInstance();</p><p> settings.setResponses(new CustomWebResponses());[/code]</p><p>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.</p><p></p><p>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.</p><p></p><p>[code]public class CustomWebResponses implements WebResponses {</p><p></p><p> @Override</p><p> public FullHttpResponse getForbiddenResponse(WebConnection client) {</p><p> return null;</p><p> }</p><p></p><p> @Override</p><p> public FullHttpResponse getNotFoundResponse(WebConnection client) {</p><p> return null;</p><p> }</p><p></p><p> @Override</p><p> public FullHttpResponse getInternalServerErrorResponse(WebConnection client, Throwable cause) {</p><p> return null;</p><p> }</p><p></p><p> @Override</p><p> public FullHttpResponse getErrorResponse(WebConnection client, String header, String message) {</p><p> return null;</p><p> }</p><p>}[/code]</p><p>If you want to use the default response for one of these methods, simply use the <strong>DefaultWebResponse</strong> class and return the method it gaves, it will never be null.</p><p></p><p>[code]@Override</p><p>public FullHttpResponse getForbiddenResponse(WebConnection client) {</p><p> return new DefaultWebResponse().getForbiddenResponse(client);</p><p>}[/code]</p><p></p><p><span style="font-size: 18px">Static Files</span></p><p>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.</p><p></p><p>[code]Settings settings = Settings.getInstance();</p><p>settings.setSiteDirectory("tools/www");[/code]</p><p>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.</p><p></p><p>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.</p><p></p><p>So lets say you have a CSS file called <strong>example.css</strong> and it's located in "/tools/www/css/" then it means that accessing <a href="http://localhost/css/example.css" target="_blank">http://localhost/css/example.css</a> will return that CSS file, if it exists, otherwise it will return a 404.</p><p></p><p><strong>NOTE:</strong> Routes being handled always take first priority over static files and directories in the Site directory setting.</p><p></p><p><span style="font-size: 18px">Template Hooking</span></p><p>Another feature of duckHTTPD is hooking a template system into the HTTP server. You need to tell <strong>Settings</strong> the template hook class.</p><p></p><p>[code]Settings settings = Settings.getInstance();</p><p>settings.setTemplateHook(ExampleTemplate.class);[/code]</p><p>This class we specified must extend <strong>Template</strong> class from the duckHTTPD package. Your class should by default appear like the example below:</p><p></p><p>[code]public class ExampleTemplate extends Template {</p><p></p><p> public ExampleTemplate(WebConnection webConnection) {</p><p> super(webConnection);</p><p> }</p><p></p><p> @Override</p><p> public void start(String templateFile) throws Exception {</p><p> </p><p> }</p><p></p><p> @Override</p><p> public void set(String key, Object value) {</p><p></p><p> }</p><p></p><p> @Override</p><p> public void render() {</p><p> return null;</p><p> }</p><p>}[/code]</p><p>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.</p><p></p><p>[code]File file = Paths.get("www-tpl", view + ".tpl").toFile();[/code]</p><p></p><p>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.</p><p></p><p>The "render()" method <strong>must</strong> set the response to the <strong>WebConnection</strong> client by using <strong>ResponseBuilder</strong> on the remaining HTML, like below, when using JTwig for example:</p><p></p><p>[code] @Override</p><p> public void render() {</p><p> FullHttpResponse response = ResponseBuilder.create(this.template.render(this.model));</p><p> this.webConnection.setResponse(response);</p><p> }[/code]</p><p>And in your controller it should be handled like below.</p><p></p><p>[code] public static void news(WebConnection client) throws Exception {</p><p> Template tpl = client.template("news");</p><p> tpl.set("text", "value here");</p><p> tpl.render();</p><p> }[/code]</p><p></p><p></p><p><span style="font-size: 18px">Integrate into Gradle</span></p><p>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.</p><p></p><p>[code]/projects</p><p> ../DuckHTTPD</p><p> ../ExampleProject[/code]</p><p>In settings.gradle add this</p><p></p><p>[code]// https://github.com/Quackster/duckHTTPD/</p><p>include 'duckHTTPD'</p><p>project(":duckHTTPD").projectDir = file("../duckHTTPD")[/code]</p><p>And in your project's build.gradle, add this</p><p></p><p>[code]dependencies {</p><p> // https://github.com/Quackster/duckHTTPD/</p><p> compile project(':duckHTTPD')</p><p>}[/code]</p><p></p><p></p><p><span style="font-size: 18px">Or just download the JAR</span></p><p>All the JAR releases can be found here: <a href="https://github.com/Quackster/duckHTTPD/releases" target="_blank">https://github.com/Quackster/duckHTTPD/releases</a></p></blockquote><p></p>
[QUOTE="Quackster, post: 422238, member: 971"] [B][SIZE=7]duckHTTPD[/SIZE][/B] 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. [URL]https://github.com/Quackster/duckHTTPD[/URL] [SIZE=5]Features[/SIZE] * 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 [SIZE=5]Example[/SIZE] 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(); }[/code] This server will listen on the specified port given by the arguments, and the URL request [URL]http://localhost/example[/URL] will preview [B][SIZE=5]Hello, World![/SIZE][/B] ...*and that's the example finished! (For now anyways)* [SIZE=5]Route Handling[/SIZE] 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 [B]RouteManager[/B] class from the duckHTTPD package. [B]NOTE:[/B] 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] The SiteController class should look like this below: [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>")); }[/code] 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. [SIZE=5]Error Handling[/SIZE] 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());[/code] 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. [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] If you want to use the default response for one of these methods, simply use the [B]DefaultWebResponse[/B] class and return the method it gaves, it will never be null. [code]@Override public FullHttpResponse getForbiddenResponse(WebConnection client) { return new DefaultWebResponse().getForbiddenResponse(client); }[/code] [SIZE=5]Static Files[/SIZE] 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");[/code] 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 [B]example.css[/B] and it's located in "/tools/www/css/" then it means that accessing [URL]http://localhost/css/example.css[/URL] will return that CSS file, if it exists, otherwise it will return a 404. [B]NOTE:[/B] Routes being handled always take first priority over static files and directories in the Site directory setting. [SIZE=5]Template Hooking[/SIZE] Another feature of duckHTTPD is hooking a template system into the HTTP server. You need to tell [B]Settings[/B] the template hook class. [code]Settings settings = Settings.getInstance(); settings.setTemplateHook(ExampleTemplate.class);[/code] This class we specified must extend [B]Template[/B] class from the duckHTTPD package. Your class should by default appear like the example below: [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] 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. [code]File file = Paths.get("www-tpl", view + ".tpl").toFile();[/code] 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 [b]must[/b] set the response to the [b]WebConnection[/b] client by using [b]ResponseBuilder[/b] 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] And in your controller it should be handled like below. [code] public static void news(WebConnection client) throws Exception { Template tpl = client.template("news"); tpl.set("text", "value here"); tpl.render(); }[/code] [SIZE=5]Integrate into Gradle[/SIZE] 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] In settings.gradle add this [code]// https://github.com/Quackster/duckHTTPD/ include 'duckHTTPD' project(":duckHTTPD").projectDir = file("../duckHTTPD")[/code] And in your project's build.gradle, add this [code]dependencies { // https://github.com/Quackster/duckHTTPD/ compile project(':duckHTTPD') }[/code] [SIZE=5]Or just download the JAR[/SIZE] All the JAR releases can be found here: [URL]https://github.com/Quackster/duckHTTPD/releases[/URL] [/QUOTE]
Insert quotes…
Verification
Post reply
Forums
Software Development
Programming
[Library] DuckHTTPD - Scalable HTTP web server API written in Java
Top