- Main Page
- Classes
- Files

- File List

# include/pion/http/server.hpp

    00001 // ---------------------------------------------------------------------
    00002 // pion:  a Boost C++ framework for building lightweight HTTP interfaces
    00003 // ---------------------------------------------------------------------
    00004 // Copyright (C) 2007-2012 Cloudmeter, Inc.  (http://www.cloudmeter.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_HTTP_SERVER_HEADER__
    00011 #define __PION_HTTP_SERVER_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/config.hpp>
    00022 #include <pion/tcp/server.hpp>
    00023 #include <pion/tcp/connection.hpp>
    00024 #include <pion/http/request.hpp>
    00025 #include <pion/http/auth.hpp>
    00026 #include <pion/http/parser.hpp>
    00027
    00028
    00029 namespace pion {    // begin namespace pion
    00030 namespace http {    // begin namespace http
    00031
    00032
    00036 class PION_API server :
    00037     public tcp::server
    00038 {
    00039
    00040 public:
    00041
    00043     typedef boost::function2<void, http::request_ptr&, tcp::connection_ptr&>  request_handler_t;
    00044
    00046     typedef boost::function3<void, http::request_ptr&, tcp::connection_ptr&,
    00047         const std::string&> error_handler_t;
    00048
    00049
    00051     virtual ~server() { if (is_listening()) stop(); }
    00052
    00058     explicit server(const unsigned int tcp_port = 0)
    00059         : tcp::server(tcp_port),
    00060         m_bad_request_handler(server::handle_bad_request),
    00061         m_not_found_handler(server::handle_not_found_request),
    00062         m_server_error_handler(server::handle_server_error),
    00063         m_max_content_length(http::parser::DEFAULT_CONTENT_MAX)
    00064     {
    00065         set_logger(PION_GET_LOGGER("pion.http.server"));
    00066     }
    00067
    00073     explicit server(const boost::asio::ip::tcp::endpoint& endpoint)
    00074         : tcp::server(endpoint),
    00075         m_bad_request_handler(server::handle_bad_request),
    00076         m_not_found_handler(server::handle_not_found_request),
    00077         m_server_error_handler(server::handle_server_error),
    00078         m_max_content_length(http::parser::DEFAULT_CONTENT_MAX)
    00079     {
    00080         set_logger(PION_GET_LOGGER("pion.http.server"));
    00081     }
    00082
    00089     explicit server(scheduler& sched, const unsigned int tcp_port = 0)
    00090         : tcp::server(sched, tcp_port),
    00091         m_bad_request_handler(server::handle_bad_request),
    00092         m_not_found_handler(server::handle_not_found_request),
    00093         m_server_error_handler(server::handle_server_error),
    00094         m_max_content_length(http::parser::DEFAULT_CONTENT_MAX)
    00095     {
    00096         set_logger(PION_GET_LOGGER("pion.http.server"));
    00097     }
    00098
    00105     server(scheduler& sched, const boost::asio::ip::tcp::endpoint& endpoint)
    00106         : tcp::server(sched, endpoint),
    00107         m_bad_request_handler(server::handle_bad_request),
    00108         m_not_found_handler(server::handle_not_found_request),
    00109         m_server_error_handler(server::handle_server_error),
    00110         m_max_content_length(http::parser::DEFAULT_CONTENT_MAX)
    00111     {
    00112         set_logger(PION_GET_LOGGER("pion.http.server"));
    00113     }
    00114
    00121     void add_resource(const std::string& resource, request_handler_t request_handler);
    00122
    00128     void remove_resource(const std::string& resource);
    00129
    00136     void add_redirect(const std::string& requested_resource, const std::string& new_resource);
    00137
    00139     inline void set_bad_request_handler(request_handler_t h) { m_bad_request_handler = h; }
    00140
    00142     inline void set_not_found_handler(request_handler_t h) { m_not_found_handler = h; }
    00143
    00145     inline void set_error_handler(error_handler_t h) { m_server_error_handler = h; }
    00146
    00148     virtual void clear(void) {
    00149         if (is_listening()) stop();
    00150         boost::mutex::scoped_lock resource_lock(m_resource_mutex);
    00151         m_resources.clear();
    00152     }
    00153
    00160     static inline std::string strip_trailing_slash(const std::string& str) {
    00161         std::string result(str);
    00162         if (!result.empty() && result[result.size()-1]=='/')
    00163             result.resize(result.size() - 1);
    00164         return result;
    00165     }
    00166
    00173     static void handle_bad_request(http::request_ptr& http_request_ptr,
    00174                                  tcp::connection_ptr& tcp_conn);
    00175
    00182     static void handle_not_found_request(http::request_ptr& http_request_ptr,
    00183                                       tcp::connection_ptr& tcp_conn);
    00184
    00192     static void handle_server_error(http::request_ptr& http_request_ptr,
    00193                                   tcp::connection_ptr& tcp_conn,
    00194                                   const std::string& error_msg);
    00195
    00203     static void handle_forbidden_request(http::request_ptr& http_request_ptr,
    00204                                        tcp::connection_ptr& tcp_conn,
    00205                                        const std::string& error_msg);
    00206
    00214     static void handle_method_not_allowed(http::request_ptr& http_request_ptr,
    00215                                        tcp::connection_ptr& tcp_conn,
    00216                                        const std::string& allowed_methods = "");
    00217
    00221     inline void set_authentication(http::auth_ptr auth) { m_auth_ptr = auth; }
    00222
    00224     inline void set_max_content_length(std::size_t n) { m_max_content_length = n; }
    00225
    00226 protected:
    00227
    00233     virtual void handle_connection(tcp::connection_ptr& tcp_conn);
    00234
    00242     virtual void handle_request(http::request_ptr& http_request_ptr,
    00243                                 tcp::connection_ptr& tcp_conn, const boost::system::error_code& ec);
    00244
    00251     virtual bool find_request_handler(const std::string& resource,
    00252                                       request_handler_t& request_handler) const;
    00253
    00254
    00255 private:
    00256
    00258     static const unsigned int   MAX_REDIRECTS;
    00259
    00261     typedef std::map<std::string, request_handler_t>    resource_map_t;
    00262
    00264     typedef std::map<std::string, std::string>          redirect_map_t;
    00265
    00266
    00268     resource_map_t              m_resources;
    00269
    00271     redirect_map_t              m_redirects;
    00272
    00274     request_handler_t           m_bad_request_handler;
    00275
    00277     request_handler_t           m_not_found_handler;
    00278
    00280     error_handler_t             m_server_error_handler;
    00281
    00283     mutable boost::mutex        m_resource_mutex;
    00284
    00286     http::auth_ptr              m_auth_ptr;
    00287
    00289     std::size_t                 m_max_content_length;
    00290 };
    00291
    00292
    00294 typedef boost::shared_ptr<server>   server_ptr;
    00295
    00296
    00297 }   // end namespace http
    00298 }   // end namespace pion
    00299
    00300 #endif