Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

Servlet.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file Servlet.d
00004         
00005         Copyright (C) 2004 Kris Bell
00006         
00007         This software is provided 'as-is', without any express or implied
00008         warranty. In no event will the authors be held liable for damages
00009         of any kind arising from the use of this software.
00010         
00011         Permission is hereby granted to anyone to use this software for any 
00012         purpose, including commercial applications, and to alter it and/or 
00013         redistribute it freely, subject to the following restrictions:
00014         
00015         1. The origin of this software must not be misrepresented; you must 
00016            not claim that you wrote the original software. If you use this 
00017            software in a product, an acknowledgment within documentation of 
00018            said product would be appreciated but is not required.
00019 
00020         2. Altered source versions must be plainly marked as such, and must 
00021            not be misrepresented as being the original software.
00022 
00023         3. This notice may not be removed or altered from any distribution
00024            of the source.
00025 
00026 
00027                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00028 
00029         
00030         @version        Initial version, April 2004      
00031         @author         Kris
00032 
00033 
00034 *******************************************************************************/
00035 
00036 module mango.servlet.Servlet;
00037 
00038 public import  mango.io.Exception;
00039 
00040 public import  mango.servlet.ServletConfig;
00041 
00042 public import  mango.http.server.HttpHeaders,
00043                mango.http.server.HttpResponse;
00044 
00045 public import  mango.servlet.model.IServletRequest,
00046                mango.servlet.model.IServletResponse;
00047                 
00048 
00049 /******************************************************************************
00050 
00051         The fundamental Servlet exception
00052 
00053 ******************************************************************************/
00054 
00055 class ServletException : IOException
00056 {
00057         /**********************************************************************
00058 
00059                 Construct this exception with the provided message
00060                 
00061         **********************************************************************/
00062 
00063         this (char[] msg)
00064         {
00065                 super (msg);
00066         }
00067 }
00068 
00069 
00070 /******************************************************************************
00071 
00072         Exception to indicate a service is unavailable
00073 
00074 ******************************************************************************/
00075 
00076 class UnavailableException : ServletException
00077 {
00078         /**********************************************************************
00079 
00080                 Construct this exception with the provided message
00081                 
00082         **********************************************************************/
00083 
00084         this (char[] msg)
00085         {
00086                 super (msg);
00087         }
00088 }
00089 
00090 
00091 /******************************************************************************
00092 
00093         The basic servlet class. This is a bit different from the Java
00094         style servlets, as the class hierarchy is effectively inverted.
00095 
00096         Servlet, by itself, does not break out each request-method. It
00097         provides only the most basic functionality. See MethodServlet
00098         for additional functionalty.
00099 
00100 ******************************************************************************/
00101 
00102 class Servlet
00103 {
00104         /**********************************************************************
00105 
00106                 Service is the main entry point for all servlets.
00107 
00108         **********************************************************************/
00109 
00110         abstract void service (IServletRequest request, IServletResponse response);
00111 
00112         /**********************************************************************
00113 
00114                 Init is called when the servlet is first registered.
00115 
00116         **********************************************************************/
00117 
00118         void init (ServletConfig config)
00119         {
00120         }
00121 }
00122 
00123 
00124 /******************************************************************************
00125 
00126         Extends the basic servlet with individual signatures for handling 
00127         each request method.
00128 
00129 ******************************************************************************/
00130 
00131 class MethodServlet : Servlet
00132 {
00133 
00134         /**********************************************************************
00135         
00136                 Default response for unimplemented requests.
00137 
00138         **********************************************************************/
00139 
00140         static private void error (IServletResponse response)
00141         {
00142                 response.sendError (HttpResponses.MethodNotAllowed);
00143         }
00144 
00145         /**********************************************************************
00146 
00147                 Handle a GET request
00148 
00149         **********************************************************************/
00150 
00151         void doGet (IServletRequest request, IServletResponse response)
00152         {
00153                 error (response);
00154         }
00155 
00156         /**********************************************************************
00157 
00158                 Handle a HEAD request
00159 
00160         **********************************************************************/
00161 
00162         void doHead (IServletRequest request, IServletResponse response)
00163         {
00164                 error (response);
00165         }
00166 
00167         /**********************************************************************
00168 
00169                 Handle a POST request
00170 
00171         **********************************************************************/
00172 
00173         void doPost (IServletRequest request, IServletResponse response)
00174         {
00175                 error (response);
00176         }
00177 
00178         /**********************************************************************
00179 
00180                 Handle a DELETE request
00181 
00182         **********************************************************************/
00183 
00184         void doDelete (IServletRequest request, IServletResponse response)
00185         {
00186                 error (response);
00187         }
00188 
00189         /**********************************************************************
00190 
00191                 Handle a PUT request
00192 
00193         **********************************************************************/
00194 
00195         void doPut (IServletRequest request, IServletResponse response)
00196         {
00197                 error (response);
00198         }
00199 
00200         /**********************************************************************
00201 
00202                 Handle an OPTIONS request
00203 
00204         **********************************************************************/
00205 
00206         void doOptions (IServletRequest request, IServletResponse response)
00207         {
00208                 error (response);
00209         }
00210 
00211         /**********************************************************************
00212 
00213                 Handle a TRACE request
00214 
00215         **********************************************************************/
00216 
00217         void doTrace (IServletRequest request, IServletResponse response)
00218         {
00219                 error (response);
00220         }
00221 
00222         /**********************************************************************
00223 
00224                 overridable implementation of getLastModified() returns
00225                 -1 to say it doesn't know.
00226 
00227         **********************************************************************/
00228 
00229         long getLastModified (IServletRequest request)
00230         {
00231                 return -1;
00232         }
00233 
00234         /**********************************************************************
00235 
00236                 Preamble for GET requests that tries to figure out if
00237                 we can simply return a NotModified status to the UA.
00238 
00239                 Servlets supporting such notions should override the
00240                 getLastModified() method above, and have it do the
00241                 appropriate thing.
00242 
00243         **********************************************************************/
00244 
00245         void get (IServletRequest request, IServletResponse response)
00246         {
00247                 long lastModified = getLastModified (request);
00248                 if (lastModified == -1) 
00249                     doGet (request, response);
00250                 else
00251                    {    
00252                    long ifModifiedSince = request.getHeaders.getDate (HttpHeader.IfModifiedSince);
00253                    if (ifModifiedSince < (lastModified / 1000 * 1000)) 
00254                       {
00255                       response.getHeaders.addDate (HttpHeader.LastModified, lastModified);
00256                       doGet (request, response);
00257                       } 
00258                    else 
00259                       response.setStatus (HttpResponses.NotModified);
00260                    }
00261         }
00262 
00263         /**********************************************************************
00264 
00265                 Service implementation for method specific isolation.
00266 
00267         **********************************************************************/
00268 
00269         void service (IServletRequest request, IServletResponse response)
00270         {
00271                 char[] method = request.getMethod();
00272 
00273                 switch (method[0])
00274                        {
00275                        case 'G':
00276                             get (request, response);
00277                             break;
00278 
00279                        case 'H':
00280                             doHead (request, response);
00281                             break;
00282 
00283                        case 'O':
00284                             doOptions (request, response);
00285                             break;
00286 
00287                        case 'T':
00288                             doTrace (request, response);
00289                             break;
00290 
00291                        case 'D':
00292                             doDelete (request, response);
00293                             break;
00294 
00295                        case 'P':
00296                             if (method[1] == 'O')
00297                                 doPost (request, response);
00298                             else
00299                                doPut (request, response);
00300                             break;
00301 
00302                        default:
00303                             response.sendError (HttpResponses.NotImplemented);
00304                             break;
00305                        }
00306         }
00307 }
00308 
00309 
00310 /******************************************************************************
00311 
00312         This class is intended to be compatible with a Java GenericServlet.
00313         Note that the ServletContext is available from the ServletRequest
00314         class, so this error-prone approach of accessing context via the
00315         configuration is rendered totally redundant.
00316 
00317 ******************************************************************************/
00318 
00319 class CompatibleServlet : MethodServlet
00320 {
00321         private ServletConfig config;
00322 
00323         /**********************************************************************
00324 
00325                 Servlet must implement the init() method
00326 
00327         **********************************************************************/
00328 
00329         abstract void init ();
00330 
00331         /**********************************************************************
00332 
00333                 Optional init() with ServletConfig passed to it.
00334 
00335         **********************************************************************/
00336 
00337         void init (ServletConfig config)
00338         {
00339                 this.config = config;
00340                 init ();
00341         }
00342 
00343         /**********************************************************************
00344 
00345                 Return the configuration passed with init()
00346 
00347         **********************************************************************/
00348 
00349         ServletConfig getConfig ()
00350         {
00351                 return config;
00352         }
00353 }
00354 
00355 

Generated on Sun Nov 7 19:06:52 2004 for Mango by doxygen 1.3.6