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 }