net/include/pion/net/HTTPServer.hpp

00001 // ------------------------------------------------------------------
00002 // pion-net: a C++ framework for building lightweight HTTP interfaces
00003 // ------------------------------------------------------------------
00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
00005 //
00006 // Distributed under the Boost Software License, Version 1.0.
00007 // See http://www.boost.org/LICENSE_1_0.txt
00008 //
00009 
00010 #ifndef __PION_HTTPSERVER_HEADER__
00011 #define __PION_HTTPSERVER_HEADER__
00012 
00013 #include <map>
00014 #include <string>
00015 #include <boost/asio.hpp>
00016 #include <boost/function.hpp>
00017 #include <boost/function/function2.hpp>
00018 #include <boost/function/function3.hpp>
00019 #include <boost/shared_ptr.hpp>
00020 #include <boost/thread/mutex.hpp>
00021 #include <pion/PionConfig.hpp>
00022 #include <pion/net/TCPServer.hpp>
00023 #include <pion/net/TCPConnection.hpp>
00024 #include <pion/net/HTTPRequest.hpp>
00025 #include <pion/net/HTTPAuth.hpp>
00026 #include <pion/net/HTTPParser.hpp>
00027 
00028 
00029 namespace pion {    // begin namespace pion
00030 namespace net {     // begin namespace net (Pion Network Library)
00031 
00035 class PION_NET_API HTTPServer :
00036     public TCPServer
00037 {
00038 
00039 public:
00040 
00042     typedef boost::function2<void, HTTPRequestPtr&, TCPConnectionPtr&>  RequestHandler;
00043 
00045     typedef boost::function3<void, HTTPRequestPtr&, TCPConnectionPtr&,
00046         const std::string&> ServerErrorHandler;
00047 
00048 
00050     virtual ~HTTPServer() { if (isListening()) stop(); }
00051 
00057     explicit HTTPServer(const unsigned int tcp_port = 0)
00058         : TCPServer(tcp_port),
00059         m_bad_request_handler(HTTPServer::handleBadRequest),
00060         m_not_found_handler(HTTPServer::handleNotFoundRequest),
00061         m_server_error_handler(HTTPServer::handleServerError),
00062         m_max_content_length(HTTPParser::DEFAULT_CONTENT_MAX)
00063     { 
00064         setLogger(PION_GET_LOGGER("pion.net.HTTPServer"));
00065     }
00066 
00072     explicit HTTPServer(const boost::asio::ip::tcp::endpoint& endpoint)
00073         : TCPServer(endpoint),
00074         m_bad_request_handler(HTTPServer::handleBadRequest),
00075         m_not_found_handler(HTTPServer::handleNotFoundRequest),
00076         m_server_error_handler(HTTPServer::handleServerError),
00077         m_max_content_length(HTTPParser::DEFAULT_CONTENT_MAX)
00078     { 
00079         setLogger(PION_GET_LOGGER("pion.net.HTTPServer"));
00080     }
00081 
00088     explicit HTTPServer(PionScheduler& scheduler, const unsigned int tcp_port = 0)
00089         : TCPServer(scheduler, tcp_port),
00090         m_bad_request_handler(HTTPServer::handleBadRequest),
00091         m_not_found_handler(HTTPServer::handleNotFoundRequest),
00092         m_server_error_handler(HTTPServer::handleServerError),
00093         m_max_content_length(HTTPParser::DEFAULT_CONTENT_MAX)
00094     { 
00095         setLogger(PION_GET_LOGGER("pion.net.HTTPServer"));
00096     }
00097 
00104     HTTPServer(PionScheduler& scheduler, const boost::asio::ip::tcp::endpoint& endpoint)
00105         : TCPServer(scheduler, endpoint),
00106         m_bad_request_handler(HTTPServer::handleBadRequest),
00107         m_not_found_handler(HTTPServer::handleNotFoundRequest),
00108         m_server_error_handler(HTTPServer::handleServerError),
00109         m_max_content_length(HTTPParser::DEFAULT_CONTENT_MAX)
00110     { 
00111         setLogger(PION_GET_LOGGER("pion.net.HTTPServer"));
00112     }
00113 
00120     void addResource(const std::string& resource, RequestHandler request_handler);
00121 
00128     void addRedirect(const std::string& requested_resource, const std::string& new_resource);
00129 
00131     inline void setBadRequestHandler(RequestHandler h) { m_bad_request_handler = h; }
00132 
00134     inline void setNotFoundHandler(RequestHandler h) { m_not_found_handler = h; }
00135 
00137     inline void setServerErrorHandler(ServerErrorHandler h) { m_server_error_handler = h; }
00138 
00140     virtual void clear(void) {
00141         if (isListening()) stop();
00142         boost::mutex::scoped_lock resource_lock(m_resource_mutex);
00143         m_resources.clear();
00144     }
00145 
00152     static inline std::string stripTrailingSlash(const std::string& str) {
00153         std::string result(str);
00154         if (!result.empty() && result[result.size()-1]=='/')
00155             result.resize(result.size() - 1);
00156         return result;
00157     }
00158 
00165     static void handleBadRequest(HTTPRequestPtr& http_request,
00166                                  TCPConnectionPtr& tcp_conn);
00167 
00174     static void handleNotFoundRequest(HTTPRequestPtr& http_request,
00175                                       TCPConnectionPtr& tcp_conn);
00176 
00184     static void handleServerError(HTTPRequestPtr& http_request,
00185                                   TCPConnectionPtr& tcp_conn,
00186                                   const std::string& error_msg);
00187 
00191     inline void setAuthentication(HTTPAuthPtr auth) { m_auth = auth; }
00192 
00194     inline void setMaxContentLength(std::size_t n) { m_max_content_length = n; }
00195 
00196 protected:
00197 
00203     virtual void handleConnection(TCPConnectionPtr& tcp_conn);
00204 
00211     void handleRequest(HTTPRequestPtr& http_request, TCPConnectionPtr& tcp_conn);
00212 
00219     bool findRequestHandler(const std::string& resource,
00220                             RequestHandler& request_handler) const;
00221 
00222 
00223 private:
00224 
00226     static const unsigned int   MAX_REDIRECTS;
00227 
00229     typedef std::map<std::string, RequestHandler>   ResourceMap;
00230 
00232     typedef std::map<std::string, std::string>      RedirectMap;
00233 
00234 
00236     ResourceMap                 m_resources;
00237 
00239     RedirectMap                 m_redirects;
00240 
00242     RequestHandler              m_bad_request_handler;
00243 
00245     RequestHandler              m_not_found_handler;
00246 
00248     ServerErrorHandler          m_server_error_handler;
00249 
00251     mutable boost::mutex        m_resource_mutex;
00252 
00254     HTTPAuthPtr                 m_auth;
00255 
00257     std::size_t                 m_max_content_length;
00258 };
00259 
00260 
00262 typedef boost::shared_ptr<HTTPServer>       HTTPServerPtr;
00263 
00264 
00265 }   // end namespace net
00266 }   // end namespace pion
00267 
00268 #endif

Generated on Fri Dec 4 08:54:29 2009 for pion-net by  doxygen 1.4.7