00001
00002
00003
00004
00005
00006
00007
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 {
00029 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 }
00250 }
00251
00252 #endif
00253