CPPSERV


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

requesthandler.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 
00021 #include "requesthandler.h"
00022 #include <servlet/HttpServletResponse.h> // Needed for SC_NOTFOUND constant
00023 #include <servlet/IllegalStateException.h>
00024 #include <iostream>
00025 #include <fstream>
00026 #include <dlfcn.h>
00027 
00028 namespace container {
00029 
00030 RequestHandler::urlmap_t RequestHandler::m_urlMap;
00031 sptk::CRWLock RequestHandler::m_servletMapLock;
00032 
00033 RequestHandler::RequestHandler(Connection* con)
00034     : m_con(con)
00035 {
00036 }
00037 
00038 
00039 RequestHandler::~RequestHandler()
00040 {
00041     try {
00042         delete m_con;//This may need to be done elsewhere..
00043     } catch (sockerr& e) {
00044         std::cerr<<"Error while closing connection: "<<e.errstr()<<std::endl;
00045     }
00046 }
00047 //TODO: make this configurable
00048 //      (perhaps per-app and with some sort of substitution syntax)
00049 std::string RequestHandler::m_noSuchServletText(
00050     "<HTML>"
00051         "<HEAD>"
00052             "<TITLE>404 - resource not found</TITLE>"
00053         "</HEAD>"
00054         "<BODY>"
00055             "<H1>404 - resource not found</H1>"
00056         "</BODY>"
00057     "</HTML>");
00058 }
00059 
00060 
00061 
00065 void container::RequestHandler::noSuchServlet()
00066 {
00067     std::ostream out(m_con);
00068     out<<"Status: "<<servlet::HttpServletResponse::SC_NOT_FOUND<<"\n"
00069         "Content-type: text/html\n\n";
00070     out<<m_noSuchServletText<<std::endl;
00071 }
00072 
00073 
00077 bool container::RequestHandler::addServlet(const std::string& name,ServletContainer *cont)
00078 {
00079     m_servletMapLock.lockRW();
00080     if(m_urlMap.getServletDesc(name)) { // Such servlet already mapped
00081         m_servletMapLock.unlock();
00082         return false;
00083     }
00084     ServDesc* desc=new ServDesc(cont);
00085     m_urlMap[name]=desc;
00086     m_servletMapLock.unlock();
00087     return true;
00088 }
00089 bool container::RequestHandler::removeServlet(const std::string& name)
00090 {
00091     ServDesc *desc=m_urlMap.getServletDesc(name);
00092     if(desc == 0)
00093         return true; // Hmm... Should we return false?
00094     m_servletMapLock.lockRW();
00095     m_urlMap.removeDesc(name);
00096     m_servletMapLock.unlock();
00097     //Once the following lock/unlock is done we can be
00098     //sure this servlet is no longer used, since we already removed
00099     //it from the map
00100     desc->m_servletLock.lockRW();
00101     desc->m_servletLock.unlock();
00102     delete desc;
00103     return true;
00104 }
00105 
00106 
00110 void container::RequestHandler::taskFunction()
00111 {
00112     std::string line;
00113     std::istream icon(m_con);
00114     std::getline(icon,line);
00115     if(line[line.size()-1]=='\r')
00116         line.erase(line.size()-1,1);
00117     m_servletMapLock.lockR();
00118     ServDesc *desc=m_urlMap.getServletDesc(line);
00119     if(desc == 0){
00120         urlmap_t* sm = m_urlMap.getPath(line, false);
00121         if(sm)
00122             desc = sm->getServletDesc("IndexServlet");
00123     }
00124     if(desc == 0){
00125         m_servletMapLock.unlock();
00126         std::cerr<<"Unable to map \""<<line<<"\" to anything"<<std::endl;
00127         while(getline(icon,line))
00128             std::cerr<<"Line: "<<line<<std::endl;
00129         noSuchServlet();
00130         return;
00131     } else {
00132         std::cerr<<"Found mapping for "<<line<<std::endl;
00133     }
00134     desc->m_servletLock.lockR();
00135     m_servletMapLock.unlock();
00136     try {
00137         desc->m_cont->service(*m_con);
00138     } catch (servlet::Traceable& e) {
00139         e.printStackTrace(std::cerr);
00140     } catch (std::exception& e) {
00141         std::cerr<<"Run-time error occured: "<<e.what()<<std::endl;
00142     } catch (...){
00143         std::cerr<<"Exception cought while processing request\n";
00144     }
00145     desc->m_servletLock.unlock();
00146 }

SourceForge.net Logo