pion
5.0.6
|
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