CPPSERV


Home Projects Jobs Clientele Contact
CPPSERV Documentation Download TODO Mailing lists Bug tracker News RSS Feed Browse source

servletcontainer.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004-2006 by Ilya A. Volynets-Evenbakh                  *
00003  *   ilya@total-knowledge.com                                              *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 #include <servletcontainer.h>
00021 
00022 #include <servlet/Servlet.h>
00023 #include <HttpServletRequestImpl.h>
00024 #include <HttpServletResponseImpl.h>
00025 #include <ServletOutputStream.h>
00026 #include <servlet/IllegalStateException.h>
00027 #include <IncludedResponseWrapper.h>
00028 #include <ForwardedRequestWrapper.h>
00029 #include <serverconfig/appcontext.h>
00030 
00031 namespace container {
00032 
00033 ServletContainer::ServletContainer(servlet::Servlet* servlet,
00034         container::ServletConfigImpl* conf,
00035         const std::string& path,
00036         size_t maxRequestSize, size_t maxFileSize,
00037         const std::string& mime, const std::string& enc, bool cache)
00038     : m_servlet(servlet)
00039     , m_conf(conf)
00040     , m_path(path)
00041     , m_maxRequestSize(maxRequestSize)
00042     , m_maxFileSize(maxFileSize)
00043     , m_mime(mime)
00044     , m_enc(enc)
00045     , m_cache(cache)
00046 {
00047 }
00048 
00049 ServletContainer::~ServletContainer()
00050 {
00051     //FIXME:  should this be done elsewhere, since we didn't create this servlet?
00052     // Unlikely though - servlets can't be allocated on stack (not yet at least)
00053     delete m_servlet;
00054 }
00055 
00056 void ServletContainer::forward(servlet::ServletRequest& request, servlet::ServletResponse& response) const
00057 {
00058     if(response.isCommitted())
00059         throw servlet::IllegalStateException();
00060     response.getOutputStream().clear();
00061     serverconfig::AppContext& ctx = static_cast<serverconfig::AppContext&>(getConfig()->getServletContext());
00062     std::string uri = ctx.getUriBase()+ctx.getServletContextName()+getName();
00063     ForwardedRequestWrapper freq(dynamic_cast<servlet::HttpServletRequest*>(&request),
00064                      ctx, uri, getPath());
00065     m_servlet->service(freq, response);
00066 }
00067 void ServletContainer::include(servlet::ServletRequest& request, servlet::ServletResponse& response) const
00068 {
00069     IncludedResponseWrapper iresp(dynamic_cast<servlet::HttpServletResponse*>(&response));  
00070     m_servlet->service(request, iresp);
00071 }
00072 
00073 void ServletContainer::invalidRequest(std::ostream& out, servlet::Traceable& e)
00074 {
00075     out<<"Status: "<<servlet::HttpServletResponse::SC_INTERNAL_SERVER_ERROR<<"\n";
00076     out<<"Content-type: text/html\n\n";
00077     out<<"<HTML><HEAD><TITLE>Internal Error</TITLE></HEAD><BODY><B>Exception thrown while processing the request:</B><BR><PRE>\n";
00078     e.printStackTrace(out);
00079     out<<"\n</PRE></BODY>"<<std::endl;
00080 }
00081 void ServletContainer::invalidRequest(std::ostream& out)
00082 {
00083     out<<"Status: "<<servlet::HttpServletResponse::SC_INTERNAL_SERVER_ERROR<<"\n";
00084     out<<"Content-type: text/html\n\n";
00085     out<<"<HTML><HEAD><TITLE>Internal Error</TITLE></HEAD><BODY><B>Unknown error occured while processing the request</B></BODY>"<<std::endl;
00086 }
00087 
00092 void ServletContainer::service(Connection& con)
00093 {
00094     container::HttpServletRequestImpl req(con,(serverconfig::AppContext*)&m_conf->getServletContext(),
00095         getPath(), m_maxRequestSize, m_maxFileSize);
00096     container::HttpServletResponseImpl resp(con, m_mime, m_enc);
00097     resp.setReqRef(&req);
00098     req.setRespRef(&resp);
00099     try {
00100         req.load();
00101     }
00102     catch (servlet::Traceable& e) {
00103         std::ostream out(&con);
00104         invalidRequest(out, e);
00105         invalidRequest(std::cerr, e);
00106         return;
00107     }
00108     catch (...) {
00109         std::ostream out(&con);
00110         invalidRequest(out);
00111         invalidRequest(std::cerr);
00112         return;
00113     }
00114     std::ostream& out=resp.getOutputStream();
00115     try {
00116         // If caching isn't allowed, set cache-control, expires, and
00117         // no-cache pragma headers
00118         if(!m_cache) {
00119             resp.setHeader("pragma", "no-cache");
00120             resp.setHeader("cache-control", "no-cache");
00121             resp.setDateHeader("expires", -1);
00122         }
00123         m_servlet->service(static_cast<servlet::ServletRequest&>(req),
00124             static_cast<servlet::ServletResponse&>(resp));
00125     } catch (servlet::IllegalStateException& e) {
00126         std::cerr<<"Trying to set headers in committed servlet?\n";
00127         e.printStackTrace(std::cerr);
00128         out<<"<pre>Cannot set headers after output has been committed\n";
00129         e.printStackTrace(out);
00130         out<<"\n</pre>\n";
00131     } catch (servlet::Traceable& e) {
00132         std::cerr<<"Caught an exception\n";
00133         out<<"<pre>Caught an exception:\n";
00134         e.printStackTrace(std::cerr);
00135         out<<"</pre></body></html>";
00136     } catch (...){
00137         std::cerr<<"Caught an unknown exception\n";
00138         out<<"Caught an unknown exception\n";
00139     }
00140 }
00141 
00142 }

SourceForge.net Logo