pion  5.0.6
include/pion/spdy/parser.hpp
00001 // ---------------------------------------------------------------------
00002 // pion:  a Boost C++ framework for building lightweight HTTP interfaces
00003 // ---------------------------------------------------------------------
00004 // Copyright (C) 2007-2014 Splunk Inc.  (https://github.com/splunk/pion)
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_SPDYPARSER_HEADER__
00011 #define __PION_SPDYPARSER_HEADER__
00012 
00013 
00014 #include <boost/shared_ptr.hpp>
00015 #include <boost/logic/tribool.hpp>
00016 #include <boost/system/error_code.hpp>
00017 #include <boost/thread/once.hpp>
00018 #include <pion/config.hpp>
00019 #include <pion/logger.hpp>
00020 #include <pion/spdy/types.hpp>
00021 #include <pion/spdy/decompressor.hpp>
00022 
00023 #ifndef BOOST_SYSTEM_NOEXCEPT
00024     #define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT
00025 #endif
00026 
00027 
00028 namespace pion {    // begin namespace pion
00029 namespace spdy {    // begin namespace spdy
00030 
00031     
00035 
00036 class PION_API parser
00037 {
00038 public:
00039     
00041     enum error_value_t {
00042         ERROR_INVALID_SPDY_FRAME = 1,
00043         ERROR_INVALID_SPDY_VERSION,
00044         ERROR_DECOMPRESSION,
00045         ERROR_PROTOCOL_ERROR,
00046         ERROR_INTERNAL_SPDY_ERROR,
00047         ERROR_MISSING_HEADER_DATA
00048     };
00049     
00051     class error_category_t
00052         : public boost::system::error_category
00053     {
00054     public:
00055         const char *name() const BOOST_SYSTEM_NOEXCEPT { return "SPDYParser"; }
00056         std::string message(int ev) const {
00057             switch (ev) {
00058                 case ERROR_INVALID_SPDY_FRAME:
00059                     return "invalid spdy frame";
00060                 case ERROR_INVALID_SPDY_VERSION:
00061                     return "invalid spdy version";
00062                 case ERROR_DECOMPRESSION:
00063                     return "error in decompression";
00064                 case ERROR_MISSING_HEADER_DATA:
00065                     return "missing header data";
00066                     
00067             }
00068             return "SPDYParser error";
00069         }
00070     };
00071     
00073     parser();
00074     
00076     ~parser() {}
00077     
00086     boost::tribool parse(http_protocol_info& http_headers,
00087                          boost::system::error_code& ec,
00088                          decompressor_ptr& decompressor,
00089                          const char *packet_ptr,
00090                          boost::uint32_t& length_packet,
00091                          boost::uint32_t current_stream_count);
00092     
00094     const char * get_spdy_data_content( ) { return m_last_data_chunk_ptr; }
00095     
00097     const char * get_spdy_read_pointer( ) { return m_read_ptr; }
00098     
00104     static spdy_frame_type get_spdy_frame_type(const char *ptr);
00105     
00111     static bool is_spdy_control_frame(const char *ptr);
00112     
00118     static boost::uint32_t get_control_frame_stream_id(const char *ptr);
00119     
00120     
00121 protected:
00122     
00124     inline void set_read_ptr(const char *ptr) { m_read_ptr = m_current_data_chunk_ptr = ptr; }
00125     
00128     bool populate_frame(boost::system::error_code& ec,
00129                         spdy_control_frame_info& frame,
00130                         boost::uint32_t& length_packet,
00131                         boost::uint32_t& stream_id,
00132                         http_protocol_info& http_headers);
00133     
00135     static void create_error_category(void);
00136     
00138     static inline error_category_t& get_error_category(void) {
00139         boost::call_once(parser::create_error_category, m_instance_flag);
00140         return *m_error_category_ptr;
00141     }
00142 
00149     static inline void set_error(boost::system::error_code& ec, error_value_t ev) {
00150         ec = boost::system::error_code(static_cast<int>(ev), get_error_category());
00151     }
00152     
00157     void parse_header_payload(boost::system::error_code& ec,
00158                               decompressor_ptr& decompressor,
00159                               const spdy_control_frame_info& frame,
00160                               http_protocol_info& http_headers,
00161                               boost::uint32_t current_stream_count);
00162     
00167     void parse_spdy_data(boost::system::error_code& ec,
00168                          const spdy_control_frame_info& frame,
00169                          boost::uint32_t stream_id,
00170                          http_protocol_info& http_info);
00171     
00176     void parse_spdy_settings_frame(boost::system::error_code& ec,
00177                                    const spdy_control_frame_info& frame);
00178     
00183     void parse_spdy_rst_stream(boost::system::error_code& ec,
00184                                const spdy_control_frame_info& frame);
00185     
00190     void parse_spdy_ping_frame(boost::system::error_code& ec,
00191                                const spdy_control_frame_info& frame);
00192     
00197     void parse_spdy_goaway_frame(boost::system::error_code& ec,
00198                                  const spdy_control_frame_info& frame);
00199     
00204     void parse_spdy_window_update_frame(boost::system::error_code& ec,
00205                                         const spdy_control_frame_info& frame);
00206     
00215     boost::tribool parse_spdy_frame(boost::system::error_code& ec,
00216                                     decompressor_ptr& decompressor,
00217                                     http_protocol_info& http_headers,
00218                                     boost::uint32_t& length_packet,
00219                                     boost::uint32_t current_stream_count);
00220     
00221 private:
00222     
00224     const char *                        m_read_ptr;
00225     
00227     const char *                        m_uncompressed_ptr;
00228     
00230     const char *                        m_current_data_chunk_ptr;
00231     
00233     const char *                        m_last_data_chunk_ptr;
00234     
00236     mutable logger                      m_logger;
00237     
00239     static error_category_t *           m_error_category_ptr;
00240     
00242     static boost::once_flag             m_instance_flag;
00243 };
00244 
00246 typedef boost::shared_ptr<parser>       parser_ptr;
00247         
00248         
00249 }   // end namespace spdy
00250 }   // end namespace pion
00251 
00252 #endif
00253