HTTP Server

Danube's HTTP server is actually a combination of implementations of Connection and ConnectionHandler. Interface HTTPConnection (extension of Connection ) and its implementation HTTPConnectionImpl represent both HTTP request and response (similarity to java.net.HttpURLConnection).

Internals

An object of class HTTPServerConnectionHandler creates HTTPConnections and invokes the processing of headers and parameters. This class handles HTTP/1.1 and HTTP/1.0 requests. It sets a minimal set of required headers.

Matching resources

/images/danube/http3.all.png

Selector goes through a supplied list of Matchers that in turn inspect HTTPConnection (mostly for request URI) and decide whether or not to pass control to the ConnectionHandler they are pointing to.

There are two supplied important implementations of the Matcher interface: Prefix and Pattern.

Prefix checks if the supplied string is a prefix of the current request URI and, if it is, the case then removes it from current request URI in HTTPConnection and passes control to the ConnectionHandler it points to.

Pattern uses regular expressions to match against the current request URI. If it matches it passes control to the ConnectionHandler it points to.

The Matcher interface supplies one more pieces of information to the Selector class to enable it to determine whether it should stop on the first match or alternatively continue with the list even if a match is found. The default value is true, which prevents the Selector going further down the list. Setting that value to false would provide filter-like functionality, where ConnectionHandler can act as a filter and enable the Selector to continue with other matches.

When using Selector with Prefix matchers it is possible for standard J2EE application behaviour to be simulated: Firstly, a Selector (HTTPServerConnectionHandler) and its Prefix matchers are like applications. Prefix matchers should in this case point to their instances of Selector with Prefix matchers that serve as servlet paths.

For more complex matching, Pattern matchers should be used. However, care must be taken to ensure that changes are not made to the current request URI (which is what a Prefix matcher would do). Also, it is posible for custom (dynamically assigned) Prefix implementations to be introduced for more complex logic involving the matching of incoming URIs.

There is one more, special, case of the Matcher interface implementation: WelcomeFile. This matcher matches only "/" paths. Also, when matched it adds value of welcomeFile property as componentResourcePath of current connection. If, for instance, linked with ReadOnlyFileConnectionHandler it acts as would welcome files in some web servers.

Handling requests

/images/danube/http4.png

As already mentioned, ConnectionHandler implementations are actually handling the requests. There are only handful of such implementations supplied with this distribution:

  • the previously mentioned Selector
  • and its extension HTTPServerConnectionHandler
  • additionally, the ErrorConnectionHandler class handles exceptions which are not handled anywhere else. It displays a HTTP error code with an explanatory message. If request parameters have an entry with the name "_exception" of type Throwable , then it will be displayed as well.
  • and ReadOnlyFileConnectionHandler, which processes simple files (and directories). This handles and knows how to render directories in a HTML page and can return the contents of selected files. Files' mime types are read from FileTypeMap.
  • Implementing own ConnectionHandler. is simple as there is only one method to be implemented: handleConnection. To obtain HTTPConnection use:
HTTPConnection httpConnection = (HTTPConnection)connection.adapt(HTTPConnection.class);

Integrations and MVC

/images/danube/mvc1.png

Apart from these basic implementations there is one important, "integration" implementation of ConnectionHandler: MVCConnectionHandler. It is a very simple implementation. It passes requests (Connection) to an implementation of the Controller interface that is intended to return a ModelAndView object. Following this an implementation of a View interface is invoked with a Connection and ModelAndView object.

Note: This way of modelling the MVC is inspired by the Spring_ framework.

The ModelAndView object contains two fields only: the name of the view to be selected by the View implementation and the Map that represents the model. Various view layer technologies (Velocity, Freemarker, etc) have adopted such an approach. Even the JSTL tag library for JSP s can use this as the subset of scopes it caters for.