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

Generated on Fri Nov 11 18:44:22 2005 for Mango by  doxygen 1.4.0