libiqxmlrpc  0.12.4
 All Classes Namespaces Files Functions Typedefs Enumerations
http.h
1 // Libiqxmlrpc - an object-oriented XML-RPC solution.
2 // Copyright (C) 2011 Anton Dedov
3 
4 #ifndef _libiqxmlrpc_http_h_
5 #define _libiqxmlrpc_http_h_
6 
7 #include "except.h"
8 #include "inet_addr.h"
9 
10 #include <boost/function.hpp>
11 #include <boost/shared_ptr.hpp>
12 
13 #include <map>
14 #include <string>
15 
16 namespace iqxmlrpc {
17 
18 class Auth_Plugin_base;
19 
21 
25 namespace http {
26 
28 enum Verification_level { HTTP_CHECK_WEAK, HTTP_CHECK_STRICT };
29 
30 #ifdef _MSC_VER
31 #pragma warning(push)
32 #pragma warning(disable: 4251)
33 #endif
34 
37 class LIBIQXMLRPC_API Header {
38 public:
39  Header(Verification_level = HTTP_CHECK_WEAK);
40  virtual ~Header();
41 
42  unsigned content_length() const;
43  bool conn_keep_alive() const;
44  bool expect_continue() const;
45 
46  void set_content_length( size_t ln );
47  void set_conn_keep_alive( bool );
48  void set_option(const std::string& name, const std::string& value);
49 
51  std::string dump() const;
52 
53 protected:
54  bool option_exists(const std::string&) const;
55  void set_option_default(const std::string& name, const std::string& value);
56  void set_option_default(const std::string& name, unsigned value);
57  void set_option_checked(const std::string& name, const std::string& value);
58  void set_option(const std::string& name, size_t value);
59 
60  const std::string& get_head_line() const { return head_line_; }
61  std::string get_string(const std::string& name) const;
62  unsigned get_unsigned(const std::string& name) const;
63 
64  //
65  // Parser interface
66  //
67 
68  typedef boost::function<void (const std::string&)> Option_validator_fn;
69 
70  void register_validator(
71  const std::string&,
72  Option_validator_fn,
74 
75  void parse(const std::string&);
76 
77 private:
78  template <class T>
79  T get_option(const std::string& name) const;
80 
81  virtual std::string dump_head() const = 0;
82 
83 private:
84  struct Option_validator {
85  Verification_level level;
86  Option_validator_fn fn;
87  };
88 
89  typedef std::map<std::string, std::string> Options;
90  typedef std::multimap<std::string, Option_validator> Validators;
91 
92  std::string head_line_;
93  Options options_;
94  Validators validators_;
95  Verification_level ver_level_;
96 };
97 
98 #ifdef _MSC_VER
99 #pragma warning(pop)
100 #endif
101 
103 class LIBIQXMLRPC_API Request_header: public Header {
104  std::string uri_;
105 
106 public:
107  Request_header( Verification_level, const std::string& to_parse );
108  Request_header( const std::string& uri, const std::string& vhost, int port );
109 
110  const std::string& uri() const { return uri_; }
111  std::string host() const;
112  std::string agent() const;
113 
114  bool has_authinfo() const;
115  void get_authinfo(std::string& user, std::string& password) const;
116  void set_authinfo(const std::string& user, const std::string& password);
117 
118 private:
119  virtual std::string dump_head() const;
120 };
121 
123 class LIBIQXMLRPC_API Response_header: public Header {
124  int code_;
125  std::string phrase_;
126 
127 public:
128  Response_header( Verification_level, const std::string& to_parse );
129  Response_header( int = 200, const std::string& = "OK" );
130 
131  int code() const { return code_; }
132  const std::string& phrase() const { return phrase_; }
133  std::string server() const;
134 
135 private:
136  std::string current_date() const;
137  virtual std::string dump_head() const;
138 };
139 
140 #ifdef _MSC_VER
141 #pragma warning(push)
142 #pragma warning(disable: 4251)
143 #endif
144 
146 class LIBIQXMLRPC_API Packet {
147 protected:
148  boost::shared_ptr<http::Header> header_;
149  std::string content_;
150 
151 public:
152  Packet( http::Header* header, const std::string& content );
153  virtual ~Packet();
154 
157  void set_keep_alive( bool = true );
158 
159  const http::Header* header() const { return header_.get(); }
160  const std::string& content() const { return content_; }
161 
162  std::string dump() const
163  {
164  return header_->dump() + content_;
165  }
166 };
167 
168 #ifdef _MSC_VER
169 #pragma warning(pop)
170 #pragma warning(disable: 4251)
171 #endif
172 
176  std::string header_cache;
177  std::string content_cache;
178  Header* header;
179  Verification_level ver_level_;
180  bool constructed;
181  bool need_continue;
182  size_t pkt_max_sz;
183  size_t total_sz;
184  bool continue_sent_;
185 
186 public:
187  Packet_reader():
188  header(0),
189  constructed(false),
190  pkt_max_sz(0),
191  total_sz(0),
192  continue_sent_(false)
193  {
194  }
195 
196  ~Packet_reader()
197  {
198  if( !constructed )
199  delete header;
200  }
201 
202  void set_verification_level(Verification_level lev)
203  {
204  ver_level_ = lev;
205  }
206 
207  void set_max_size( size_t m )
208  {
209  pkt_max_sz = m;
210  }
211 
212  bool expect_continue() const;
213  Packet* read_request( const std::string& );
214  Packet* read_response( const std::string&, bool read_header_only );
215  void set_continue_sent();
216 
217 private:
218  void clear();
219  void check_sz( size_t );
220  bool read_header( const std::string& );
221 
222  template <class Header_type>
223  Packet* read_packet( const std::string&, bool = false );
224 };
225 
226 
228 class LIBIQXMLRPC_API Malformed_packet: public Exception {
229 public:
231  Exception( "Malformed HTTP packet received.") {}
232 
233  Malformed_packet(const std::string& problem_domain):
234  Exception( "Malformed HTTP packet received (" + problem_domain + ")." ) {}
235 };
236 
239 class LIBIQXMLRPC_API Error_response: public Packet, public Exception {
240 public:
241  Error_response( const std::string& phrase, int code ):
242  Packet( new Response_header(code, phrase), "" ),
243  Exception( "HTTP: " + phrase ) {}
244 
245  ~Error_response() throw() {};
246 
247  const Response_header* response_header() const
248  {
249  return dynamic_cast<const Response_header*>(header());
250  }
251 
252  // deprecated
253  std::string dump_error_response() const { return dump(); }
254 };
255 
256 } // namespace http
257 } // namespace iqxmlrpc
258 
259 #endif
260 // vim:ts=2:sw=2:et