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
00024 namespace pion {
00025 namespace spdy {
00026
00027
00031
00032 class PION_API parser
00033 {
00034 public:
00035
00037 enum error_value_t {
00038 ERROR_INVALID_SPDY_FRAME = 1,
00039 ERROR_INVALID_SPDY_VERSION,
00040 ERROR_DECOMPRESSION,
00041 ERROR_PROTOCOL_ERROR,
00042 ERROR_INTERNAL_SPDY_ERROR,
00043 ERROR_MISSING_HEADER_DATA
00044 };
00045
00047 class error_category_t
00048 : public boost::system::error_category
00049 {
00050 public:
00051 const char *name() const { return "SPDYParser"; }
00052 std::string message(int ev) const {
00053 switch (ev) {
00054 case ERROR_INVALID_SPDY_FRAME:
00055 return "invalid spdy frame";
00056 case ERROR_INVALID_SPDY_VERSION:
00057 return "invalid spdy version";
00058 case ERROR_DECOMPRESSION:
00059 return "error in decompression";
00060 case ERROR_MISSING_HEADER_DATA:
00061 return "missing header data";
00062
00063 }
00064 return "SPDYParser error";
00065 }
00066 };
00067
00069 parser();
00070
00072 ~parser() {}
00073
00082 boost::tribool parse(http_protocol_info& http_headers,
00083 boost::system::error_code& ec,
00084 decompressor_ptr& decompressor,
00085 const char *packet_ptr,
00086 boost::uint32_t& length_packet,
00087 boost::uint32_t current_stream_count);
00088
00090 const char * get_spdy_data_content( ) { return m_last_data_chunk_ptr; }
00091
00093 const char * get_spdy_read_pointer( ) { return m_read_ptr; }
00094
00100 static spdy_frame_type get_spdy_frame_type(const char *ptr);
00101
00107 static bool is_spdy_control_frame(const char *ptr);
00108
00114 static boost::uint32_t get_control_frame_stream_id(const char *ptr);
00115
00116
00117 protected:
00118
00120 inline void set_read_ptr(const char *ptr) { m_read_ptr = m_current_data_chunk_ptr = ptr; }
00121
00124 bool populate_frame(boost::system::error_code& ec,
00125 spdy_control_frame_info& frame,
00126 boost::uint32_t& length_packet,
00127 boost::uint32_t& stream_id,
00128 http_protocol_info& http_headers);
00129
00131 static void create_error_category(void);
00132
00134 static inline error_category_t& get_error_category(void) {
00135 boost::call_once(parser::create_error_category, m_instance_flag);
00136 return *m_error_category_ptr;
00137 }
00138
00145 static inline void set_error(boost::system::error_code& ec, error_value_t ev) {
00146 ec = boost::system::error_code(static_cast<int>(ev), get_error_category());
00147 }
00148
00153 void parse_header_payload(boost::system::error_code& ec,
00154 decompressor_ptr& decompressor,
00155 const spdy_control_frame_info& frame,
00156 http_protocol_info& http_headers,
00157 boost::uint32_t current_stream_count);
00158
00163 void parse_spdy_data(boost::system::error_code& ec,
00164 const spdy_control_frame_info& frame,
00165 boost::uint32_t stream_id,
00166 http_protocol_info& http_info);
00167
00172 void parse_spdy_settings_frame(boost::system::error_code& ec,
00173 const spdy_control_frame_info& frame);
00174
00179 void parse_spdy_rst_stream(boost::system::error_code& ec,
00180 const spdy_control_frame_info& frame);
00181
00186 void parse_spdy_ping_frame(boost::system::error_code& ec,
00187 const spdy_control_frame_info& frame);
00188
00193 void parse_spdy_goaway_frame(boost::system::error_code& ec,
00194 const spdy_control_frame_info& frame);
00195
00200 void parse_spdy_window_update_frame(boost::system::error_code& ec,
00201 const spdy_control_frame_info& frame);
00202
00211 boost::tribool parse_spdy_frame(boost::system::error_code& ec,
00212 decompressor_ptr& decompressor,
00213 http_protocol_info& http_headers,
00214 boost::uint32_t& length_packet,
00215 boost::uint32_t current_stream_count);
00216
00217 private:
00218
00220 const char * m_read_ptr;
00221
00223 const char * m_uncompressed_ptr;
00224
00226 const char * m_current_data_chunk_ptr;
00227
00229 const char * m_last_data_chunk_ptr;
00230
00232 mutable logger m_logger;
00233
00235 static error_category_t * m_error_category_ptr;
00236
00238 static boost::once_flag m_instance_flag;
00239 };
00240
00242 typedef boost::shared_ptr<parser> parser_ptr;
00243
00244
00245 }
00246 }
00247
00248 #endif
00249