00001 /* 00002 * ==================================================================== 00003 * 00004 * The Apache Software License, Version 1.1 00005 * 00006 * Copyright (c) 1999-2001 The Apache Software Foundation. All rights 00007 * reserved. 00008 * 00009 * Redistribution and use in source and binary forms, with or without 00010 * modification, are permitted provided that the following conditions 00011 * are met: 00012 * 00013 * 1. Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * 00016 * 2. Redistributions in binary form must reproduce the above copyright 00017 * notice, this list of conditions and the following disclaimer in 00018 * the documentation and/or other materials provided with the 00019 * distribution. 00020 * 00021 * 3. The end-user documentation included with the redistribution, if 00022 * any, must include the following acknowlegement: 00023 * "This product includes software developed by the 00024 * Apache Software Foundation (http://www.apache.org/)." 00025 * Alternately, this acknowlegement may appear in the software itself, 00026 * if and wherever such third-party acknowlegements normally appear. 00027 * 00028 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software 00029 * Foundation" must not be used to endorse or promote products derived 00030 * from this software without prior written permission. For written 00031 * permission, please contact apache@apache.org. 00032 * 00033 * 5. Products derived from this software may not be called "Apache" 00034 * nor may "Apache" appear in their names without prior written 00035 * permission of the Apache Group. 00036 * 00037 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 00038 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00039 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00040 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 00041 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00042 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00043 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 00044 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00045 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00046 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00047 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00048 * SUCH DAMAGE. 00049 * ==================================================================== 00050 * 00051 */ 00052 00053 #include <servlet/HttpServlet.h> 00054 #include "NoBodyResponse.h" 00055 #include <servlet/HttpServletRequest.h> 00056 #include <servlet/HttpServletResponse.h> 00057 #include <servlet/ServletRequest.h> 00058 #include <servlet/ServletResponse.h> 00059 #include <stdexcept> 00060 00061 using namespace std; 00062 00063 namespace servlet 00064 { 00065 00066 inline void not_supported(HttpServletRequest& req, HttpServletResponse& resp, 00067 const string& method_name) 00068 { 00069 const string protocol = req.getProtocol(); 00070 const string msg = "Method "+method_name+" not supported"; 00071 if (protocol.rfind("1.1")!=std::string::npos) 00072 resp.sendError(HttpServletResponse::SC_METHOD_NOT_ALLOWED, msg); 00073 else 00074 resp.sendError(HttpServletResponse::SC_BAD_REQUEST, msg); 00075 } 00076 //-------------------------------------------------------------------- 00077 00078 void HttpServlet::doGet(HttpServletRequest& req, HttpServletResponse& resp) { 00079 not_supported(req,resp,"GET"); 00080 } 00081 //-------------------------------------------------------------------- 00082 00083 void HttpServlet::doHead(HttpServletRequest& req, HttpServletResponse& resp) { 00084 NoBodyResponse response(resp); 00085 doGet(req, response); 00086 response.setContentLength(); 00087 } 00088 //-------------------------------------------------------------------- 00089 00090 void HttpServlet::doPost(HttpServletRequest& req, HttpServletResponse& resp) { 00091 not_supported(req,resp,"POST"); 00092 } 00093 //-------------------------------------------------------------------- 00094 00095 void HttpServlet::doPut(HttpServletRequest& req, HttpServletResponse& resp) { 00096 not_supported(req,resp,"PUT"); 00097 } 00098 //-------------------------------------------------------------------- 00099 00100 void HttpServlet::doDelete(HttpServletRequest& req, HttpServletResponse& resp) { 00101 not_supported(req,resp,"DELETE"); 00102 } 00103 //-------------------------------------------------------------------- 00104 void HttpServlet::doOptions(HttpServletRequest& req, HttpServletResponse& resp) { 00105 not_supported(req,resp,"OPTIONS"); 00106 /* Method[] methods = getAllDeclaredMethods(this.getClass()); 00107 00108 boolean ALLOW_GET = false; 00109 boolean ALLOW_HEAD = false; 00110 boolean ALLOW_POST = false; 00111 boolean ALLOW_PUT = false; 00112 boolean ALLOW_DELETE = false; 00113 boolean ALLOW_TRACE = true; 00114 boolean ALLOW_OPTIONS = true; 00115 00116 for (int i=0; i<methods.length; i++) { 00117 Method m = methods[i]; 00118 00119 if (m.getName() == ("doGet")) { 00120 ALLOW_GET = true; 00121 ALLOW_HEAD = true; 00122 } 00123 if (m.getName() == ("doPost")) 00124 ALLOW_POST = true; 00125 if (m.getName() == ("doPut")) 00126 ALLOW_PUT = true; 00127 if (m.getName() == ("doDelete")) 00128 ALLOW_DELETE = true; 00129 00130 } 00131 00132 String allow = null; 00133 if (ALLOW_GET) 00134 if (allow==null) allow=METHOD_GET; 00135 if (ALLOW_HEAD) 00136 if (allow==null) allow=METHOD_HEAD; 00137 else allow += ", " + METHOD_HEAD; 00138 if (ALLOW_POST) 00139 if (allow==null) allow=METHOD_POST; 00140 else allow += ", " + METHOD_POST; 00141 if (ALLOW_PUT) 00142 if (allow==null) allow=METHOD_PUT; 00143 else allow += ", " + METHOD_PUT; 00144 if (ALLOW_DELETE) 00145 if (allow==null) allow=METHOD_DELETE; 00146 else allow += ", " + METHOD_DELETE; 00147 if (ALLOW_TRACE) 00148 if (allow==null) allow=METHOD_TRACE; 00149 else allow += ", " + METHOD_TRACE; 00150 if (ALLOW_OPTIONS) 00151 if (allow==null) allow=METHOD_OPTIONS; 00152 else allow += ", " + METHOD_OPTIONS; 00153 00154 resp.setHeader("Allow", allow);*/ 00155 } 00156 //-------------------------------------------------------------------- 00157 00158 void HttpServlet::doTrace(HttpServletRequest& req, HttpServletResponse& resp) { 00159 not_supported(req,resp,"TRACE");//TODO 00160 /* 00161 int responseLength; 00162 00163 String CRLF = "\r\n"; 00164 String responseString = "TRACE "+ req.getRequestURI()+ 00165 " " + req.getProtocol(); 00166 00167 Enumeration reqHeaderEnum = req.getHeaderNames(); 00168 00169 while( reqHeaderEnum.hasMoreElements() ) { 00170 String headerName = (String)reqHeaderEnum.nextElement(); 00171 responseString += CRLF + headerName + ": " + 00172 req.getHeader(headerName); 00173 } 00174 00175 responseString += CRLF; 00176 00177 responseLength = responseString.length(); 00178 00179 resp.setContentType("message/http"); 00180 resp.setContentLength(responseLength); 00181 ServletOutputStream out = resp.getOutputStream(); 00182 out.print(responseString); 00183 out.close(); 00184 */ 00185 } 00186 //-------------------------------------------------------------------- 00187 void HttpServlet::service(HttpServletRequest& req, HttpServletResponse& resp) { 00188 const string method = req.getMethod(); 00189 if(method == "GET") { 00190 long lastModified = getLastModified(req); 00191 if (lastModified == -1) { 00192 // servlet doesn't support if-modified-since, no reason 00193 // to go through further expensive logic 00194 doGet(req, resp); 00195 } else { 00196 long ifModifiedSince = req.getDateHeader("If-Modified-Since"); 00197 if (ifModifiedSince < (lastModified / 1000 * 1000)) { 00198 // If the servlet mod time is later, call doGet() 00199 // Round down to the nearest second for a proper compare 00200 // A ifModifiedSince of -1 will always be less 00201 maybeSetLastModified(resp, lastModified); 00202 doGet(req, resp); 00203 } else { 00204 resp.setStatus(HttpServletResponse::SC_NOT_MODIFIED); 00205 } 00206 } 00207 }else if(method == "POST") { 00208 doPost(req, resp); 00209 }else if(method == "HEAD") { 00210 long lastModified = getLastModified(req); 00211 maybeSetLastModified(resp, lastModified); 00212 doHead(req, resp); 00213 }else if(method == "PUT") { 00214 doPut(req, resp); 00215 }else if(method == "DELETE") { 00216 doDelete(req, resp); 00217 }else if(method == "OPTIONS") { 00218 doOptions(req,resp); 00219 }else if(method == "TRACE") { 00220 doTrace(req,resp); 00221 }else { 00222 // Note that this means NO servlet supports whatever 00223 // method was requested, anywhere on this server. 00224 resp.sendError( 00225 HttpServletResponse::SC_NOT_IMPLEMENTED, 00226 "Method "+req.getMethod()+" not implemented" 00227 ); 00228 } 00229 } 00230 //-------------------------------------------------------------------- 00231 00232 void HttpServlet::maybeSetLastModified(HttpServletResponse& resp, long lastModified) { 00233 if (resp.containsHeader("Last-Modified")) 00234 return; 00235 if (lastModified >= 0) 00236 resp.setDateHeader("Last-Modified", lastModified); 00237 } 00238 //-------------------------------------------------------------------- 00239 00240 void HttpServlet::service(ServletRequest& req, ServletResponse& res) { 00241 HttpServletRequest &request = 00242 dynamic_cast<HttpServletRequest&>(req); 00243 HttpServletResponse &response = 00244 dynamic_cast<HttpServletResponse&>(res); 00245 service(request, response); 00246 } 00247 //-------------------------------------------------------------------- 00248 }