Skip to content

Simple web server based on com.sun.net.httpserver

Notifications You must be signed in to change notification settings

ivan-lorenz/httpserver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

httpserver

Simple web server based on com.sun.net.httpserver. This is an exercise of a web server implementation using only JAVA SE 8 classes. Only tests have external dependencies which are JUnit and Apache HttpClient.

Description

The server has three private pages page1.html, page2.html and page3.html and a login page, login.html. One administrator (admin:admin) and three users have been created for testing purposes. User (user1) has access to page1, (user2) to page2 and (user3) to page3. The static resources are:

  • /login.html
  • /page1.html
  • /page2.html
  • /page3.html

Once log in, users are granted a session token which flow from browser to server using cookies. Sessions expire after 5 minutes of inactivity.

There is also a REST API at endpoint /api/user. The administrator user can create, update and delete users. It must be authenticated through basic authentication The operations are as follows:

  • POST /api/user/user4?password=user4&role=PAGE_1,PAGE_2
  • PUT /api/user/user4?role=PAGE_3
  • DELETE /api/user/user4

All the authenticated users can also read the REST API:

  • GET /api/user/user4

Installation

You need Maven to launch tests, compile and build the jar. And obviously the JVM. The application targets Java 1.8. You can download JAVA 8 SE here.

To pass the tests, compile and build the jar, once in the project directory, type:

  • $ mvn test
  • $ mvn compile
  • $ mvn jar:jar

You will find the jar located at "target" directory, named "test-web-application.jar". You can launch the server with an argument for the port to bind like this:

  • $ java -jar target/test-web-application.jar 8001

Design considerations

Simple web server is a week-end training exercise where to apply the common design patterns for a web application. It is also a work in progress with some "TODO" left for future sessions.

The core pattern for the application is a Model-View-Controller Pattern with the views as static resources. I used TDD Red-Green-Refactor cycle to implement the solution, mainly integration more than unit testing due to the nature of classes and methods. All the classes dependencies are handled manually by a Dependency Injection Container implemented in the Context, RunContext and TestContext classes, which is a must if you want to drive your development with TDD and inject mocks and different configurations for testing purposes. See the usage of IClock interface both in Test and Run configuration to investigate an example of that.

The main controller (Front Controller) ServerHandler is an HttpHandler and implements a Mediator Pattern. There is also a ServerAction for each controller action. ServerAction follows Strategy Pattern and its creation is left to a ServerActionFactory. This factory uses a router class, ServerRouter, which maps all the endpoints to the appropriate ServerAction and stores access rights for each endpoint. These are mainly the most important patterns used.

We manage authorization through an Authenticator, which is a proprietary class of com.sun.net.httpserver package. We implement a class named ServerAuthenticator which extends Authenticator and manage all the roles and access rights for the web server using also ServerRouter. We manage session cookies for the static web pages and Basic Authentication for the REST API.

A lot of refactor is already needed to get rid of Arrow code anti-pattern scattered through the action classes and also to honor Single Responsibility Principle for some classes like ServerRouter, which is managing both the endpoint mapping to actions and the access rights. Also a best use of Java 8 Optional type, which is difficult to use if you have to deal with side effects, when only we have "ifPresent" implemented and not "ifNotPresent" which will arrive in Java 9. The lifecycle of HttpExchange (which is a mutable class encapsulating both the request and the response) across the application leave to few room for immutability and functional programming, but I have tried to use Optional and lambdas when possible, where they make a cleaner code. Maybe sometimes I achieve just the opposite.

About

Simple web server based on com.sun.net.httpserver

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published