The Util Module

From MircWiki
Revision as of 21:55, 13 December 2012 by Johnperry (talk | contribs) (→‎Example)
Jump to navigation Jump to search

The Util module includes the embedded server, common servlets, and a collection of utility classes used in CTP, MIRC2 (TFS), Geneva, FileSender and other MIRC tools. This article describes the theory of operation of the packages contained in the Util module. The intended audience for this article is software engineers extending or maintaining CTP and TFS or any of the other MIRC software that uses it.

See Setting Up a MIRC Development Environment for information on obtaining and building the Util module.

The Util module contains five packages:

  • org.rsna.server contains an embedded servlet container, with user authentication and servlet mapping from requested resource paths.
  • org.rsna.multipart provides built-in support for multipart forms.
  • org.rsna.service contains code that simplifies the implemention of HTTP services.
  • org.rsna.servlets contains the Servlet base class and servlets that are used for authentication and system management.
  • org.rsna.util contains utility classes.

Each of these packages will be described in separate sections below, with example code where necessary to illustrate the theory of operation. I recommend that you get the code and build it so you can reference the Javadocs as you go along.

1 org.rsna.server

The embedded servlet container is implemented in the in the HttpServer class. The implementation is not W3C-compliant; it is designed to minimize the need for configuration outside the application program within which it is embedded.

The HttpServer constructor requires a boolean indicating whether the server is to operate in SSL, the port on which the server is to listen, and an instance of the ServetSelector class.

The ServletSelector provides a mapping between requested resource paths and servlets. It also defines the root of the server file tree for served files. Servlets are added into the ServetSelector programmatically. Adding servlets can be done while the server is running.

When the server receives a connection, it creates an instance of the HttpHandler class to service the request. The instance is managed by an instance of java.util.concurrent.ExecutorService set to handle a maximum of 20 concurrent threads. When the HttpHandler is instantiated, it creates instances of the HttpRequest and HttpResponse classes. It then calls the ServletSelector to obtain an instance of the servlet that matches the requested resource. If no servlet matches the request, the ServletSelector returns the Servlet base class, which acts as a web server. The HttpHandler then calls the servlet's method specified in the HttpRequest.

The HttpRequest parses the request and calls the Authenticator to authenticate the user.

The Authenticator supports three methods of authentication:

  • If the RSNASESSION cookie is contained in the request, it is used as an index into a session table.
  • If no session is found for the request, the Authorization header is used to obtain credentials via basic authorization.
  • If the user cannot be authenticated by the Authorization header, the RSNA header is used to obtain credentials. This header is supported only for backward compatibility with obsolete MIRC software. No current MIRC software uses the RSNA header to pass credentials.

When authenticating credentials, the Authenticator calls the Users implementation to do the actual authentication. The Users class is the base class for classes that represent users. There are two Users class implementations:

  • org.rsna.server.UsersXmlFileImpl represents users in an XML file (users.xml).
  • org.rsna.server.UsersLdapFileImpl represents users in an XML file (users.xml), but uses an external LDAP server to authenticate the users' credentials.

In both Users implementations, the user's roles are represented in the XML file.

1.1 Example

This is an example of how to instantiate an HttpServer. It is loosely based on the way CTP starts the server, and it uses the CTP Configuration class to access the configured values for the Users implementation, the SSL boolean, and the server port.

//Instantiate the singleton Users class
Users users = Users.getInstance(config.getUsersClassName(), config.getServerElement());

//Create the ServletSelector for the HttpServer
ServletSelector selector =
	new ServletSelector(
		new File("ROOT"),
		config.getRequireAuthentication());

//Add in the servlets
selector.addServlet("login", LoginServlet.class);
selector.addServlet("users", UserManagerServlet.class);
//etc.

//Instantiate the server.
int port = config.getServerPort();
boolean ssl = config.getServerSSL();
HttpServer httpServer = null;
try { httpServer = new HttpServer(ssl, port, selector); }
catch (Exception ex) {
	logger.error("Unable to instantiate the HTTP Server on port "+port, ex);
	System.exit(0);
}