Features & Restrictions

This server was written with two things in mind:

  1. Compliance with the specifications, and
  2. Efficiency: High speed & Low memory usage

Every design decision in this project considered these two points.

Below are listed the notable features and minor restrictions of this server.

Notable Features

There are a number of features that serparate this server from the pack. These include:
  • Conditionally HTTP/1.1 compilant.
  • Servlet 2.2 compilant (minus some minor things specified in restrictions).
  • Persistent connections.
  • Understands the "Chunked" transfer-coding.
  • Basic and Digest authentication.
  • Multiline headers.
  • Support for nonstandard HTTP methods.
  • URL rewriting for sessions.
  • Quoted cookie values.
  • Authenticated servlets do not require any change to the code other than changing the superclass from HttpServlet to com.qindesign.servlet.AuthenticatedHttpServlet.
  • Remote server shutdown.
  • Optional servlet reloading for firmware 1.1 and above.
  • Pays attention to UnavailableExceptions.
  • Template processing.
  • The author's goal is compilance with the specifications.


This server was designed explicitly for the TINI, a very powerful, yet small, embedded device. Hence, there are a few minor restrictions that must be considered and accounted for in your designs.

Servlet 2.2 Restrictions

  • Response buffer size of 0. This means that simply retrieving an output stream or writer will commit the response.
  • The response is not "closed" after HttpServletResponse.sendError, HttpServletResponse.sendRedirect, RequestDispatcher.forward, or when the amount of content specified in the "Content-Length" header has been written to the response.
    Except for the case of exceeding the specified content length, there are no checks performed that catch a servlet writing out content after these events.
  • No JSP.
  • Currently only one ServletContext for all requested paths.
  • Must add cookies and sessions before the response is committed.
  • Does not pay attention to the time indicated by UnavailableException. A "Retry-After" header is sent when servicing, but the container does not wait to recreate the servlet for another request during initialization.
  • The javax.servlet.context.tempdir context attribute is not set if a valid directory is not specified in the servlet.tempdir configuration property.
  • Any class a servlet uses is a candidate for dynamic classloading, however, only the servlet class is checked for freshness. In other words, classes are only reloaded when the servlet class changes.
  • When servlet reloading is enabled, servlet authors should take care to stop all threads and clean up any resources in the destroy method. The reason is that TINIClassLoader.unloadClasses is used when a servlet is reloaded, and this forces all the class memory to be cleared, potentially causing other objects to point to invalid references.
  • When servlet reloading is not enabled, the destroy method is called on a servlet immediately after a permanent UnavailableException is detected. This means that the servlet author should take care to properly synchronize and manage any resources used during the service method.
  • There is a similar note for when the server is shut down. When servlet reloading is not enabled, the destroy method is called immediately, and any threads running in the service method are not given a chance to complete. In other words, the server defined time limit is zero.

HTTP/1.1 Restrictions

  • The "Expect" header is not fully supported: Only a (case-insensitive) value of "100-continue" is recognized, and if this is encountered, a 100 (Continue) status is sent right away.
  • Persistent connections are not used with the "chunked" transfer encoding.

Misc. Notes

  • If a different crystal is used to drive the TINI, then the server time will not always be correct. This is because the timekeeping mechanism relies on TINIOS.uptimeMillis() and not System.currentTimeMillis(). The second method uses the real-time clock and will be correct always, but it is also much slower.