Guitar
webclient.h
Go to the documentation of this file.
1 
2 #ifndef WEBCLIENT_H_
3 #define WEBCLIENT_H_
4 
5 #include <vector>
6 #include <string>
7 #include <functional>
8 
9 #define USE_OPENSSL 1
10 #define OPENSSL_NO_SHA1 1
11 
12 class WebContext;
13 class WebClient;
14 
15 typedef void _in_addr;
17 public:
18  bool resolve(char const *name, _in_addr *out);
19 };
20 
22 protected:
23  void abort(std::string const &message = {});
24 public:
25  virtual ~WebClientHandler() = default;
26  virtual void checkHeader(WebClient *wc)
27  {
28  (void)wc;
29  }
30  virtual void checkContent(char const *ptr, size_t len)
31  {
32  (void)ptr;
33  (void)len;
34  }
35 };
36 
37 class WebProxy {
38 public:
39  std::string server;
40  bool empty() const
41  {
42  return server.empty();
43  }
44 };
45 
46 struct ResponseHeader;
47 
48 class WebClient {
49 public:
50  class ContentType {
51  public:
52  static constexpr const char *APPLICATION_OCTET_STREAM = "application/octet-stream";
53  static constexpr const char *APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
54  static constexpr const char *MULTIPART_FORM_DATA = "multipart/form-data";
55  };
56  class URL {
57  friend class WebClient;
58  private:
59  struct Data {
60  std::string full_request;
61  std::string scheme;
62  std::string host;
63  int port = 0;
64  std::string path;
65  } data;
66  public:
67  URL() = default;
68  URL(std::string const &addr);
69  std::string const &scheme() const { return data.scheme; }
70  std::string const &host() const { return data.host; }
71  int port() const { return data.port; }
72  std::string const &path() const { return data.path; }
73  bool isssl() const;
74  };
75  enum HttpVersion {
78  };
79  struct Authorization {
80  enum Type {
83  } type = None;
84  std::string uid;
85  std::string pwd;
86  };
87  class Request {
88  friend class ::WebClient;
89  private:
92  std::vector<std::string> headers;
93  public:
94  Request() = default;
95  Request(std::string const &loc, std::vector<std::string> const &headers = {})
96  : url(loc)
97  , headers(headers)
98  {
99  }
100  void set_location(std::string const &loc)
101  {
102  url = URL(loc);
103  }
104  void set_authorization(Authorization::Type type, std::string const &uid, std::string const &pwd)
105  {
106  auth.type = type;
107  auth.uid = uid;
108  auth.pwd = pwd;
109  }
110  void set_basic_authorization(std::string const &uid, std::string const &pwd)
111  {
113  }
114  void add_header(std::string const &s)
115  {
116  headers.push_back(s);
117  }
118  };
119  class Error {
120  private:
121  std::string msg_;
122  public:
123  Error() = default;
124  Error(std::string const &message)
125  : msg_(message)
126  {
127  }
128  virtual ~Error() = default;
129  std::string message() const
130  {
131  return msg_;
132  }
133  };
134  struct Response {
135  int code = 0;
136  struct Version {
137  unsigned int hi = 0;
138  unsigned int lo = 0;
139  } version;
140  std::vector<std::string> header;
141  std::vector<char> content;
142  };
143  struct Post {
144  std::string content_type;
145  std::string boundary;
146  std::vector<char> data;
147  };
149  std::string type;
150  std::string name;
151  std::string filename;
152  };
153  struct Part {
154  char const *data = nullptr;
155  size_t size = 0;
156  std::string content_type;
159  Part() = default;
160  Part(char const *data, size_t size, std::string const &content_type = {})
161  : data(data)
162  , size(size)
164  {
165  }
167  {
168  content_disposition = cd;
169  }
170  };
171  struct RequestOption {
173  bool keep_alive = true;
174  };
175 private:
176  struct Private;
177  Private *m;
178  void clear_error();
179  static int get_port(URL const *url, char const *scheme, char const *protocol);
180  void set_default_header(const Request &url, Post const *post, const RequestOption &opt);
181  std::string make_http_request(const Request &url, Post const *post, const WebProxy *proxy, bool https);
182  void parse_http_header(char const *begin, char const *end, std::vector<std::string> *header);
183  void parse_http_header(char const *begin, char const *end, Response *out);
184  bool http_get(const Request &request_req, Post const *post, RequestOption const &opt, ResponseHeader *rh, std::vector<char> *out);
185  bool https_get(const Request &request_url, Post const *post, RequestOption const &opt, ResponseHeader *rh, std::vector<char> *out);
186  bool get(const Request &req, Post const *post, Response *out, WebClientHandler *handler);
187  static void parse_header(std::vector<std::string> const *header, WebClient::Response *res);
188  static std::string header_value(std::vector<std::string> const *header, std::string const &name);
189  void append(char const *ptr, size_t len, std::vector<char> *out, WebClientHandler *handler);
190  void on_end_header(const std::vector<char> *vec, WebClientHandler *handler);
191  void receive_(const RequestOption &opt, std::function<int (char *, int)> const &, ResponseHeader *rh, std::vector<char> *out);
192  void output_debug_string(char const *str);
193  void output_debug_strings(const std::vector<std::string> &vec);
194  static void cleanup();
195  void reset();
196 public:
197  static void initialize();
198  WebClient(WebContext *webcx);
199  ~WebClient();
200  WebClient(WebClient const &) = delete;
201  void operator = (WebClient const &) = delete;
202 
203  void set_http_version(HttpVersion httpver);
204 
205  Error const &error() const;
206  int get(const Request &req, WebClientHandler *handler = nullptr);
207  int post(const Request &req, Post const *post, WebClientHandler *handler = nullptr);
208  void close();
209  void add_header(std::string const &text);
210  Response const &response() const;
211  std::string header_value(std::string const &name) const;
212  std::string content_type() const;
213  size_t content_length() const;
214  char const *content_data() const;
215 
216  static void make_application_www_form_urlencoded(char const *begin, char const *end, WebClient::Post *out);
217  static void make_multipart_form_data(const std::vector<Part> &parts, WebClient::Post *out, std::string const &boundary);
218  static void make_multipart_form_data(char const *data, size_t size, WebClient::Post *out, std::string const &boundary);
219 
220  static std::string get(const std::string &url);
221  static std::string checkip();
222 };
223 
224 class WebContext {
225  friend class WebClient;
226 public:
227 private:
228  struct Private;
229  Private *m;
230 public:
232  ~WebContext();
233  WebContext(WebContext const &r) = delete;
234  void operator = (WebContext const &r) = delete;
235 
237  void set_keep_alive_enabled(bool f);
238 
239  void set_http_proxy(std::string const &proxy);
240  void set_https_proxy(std::string const &proxy);
241  WebProxy const *http_proxy() const;
242  WebProxy const *https_proxy() const;
243 
244  bool load_cacert(char const *path);
245 
246  void notify_broken_pipe();
247 };
248 
249 #endif
WebClient::Private::crlf_state
int crlf_state
Definition: webclient.cpp:186
WebClient::Part::Part
Part(char const *data, size_t size, std::string const &content_type={})
Definition: webclient.h:160
WebClient::Private::last_port
int last_port
Definition: webclient.cpp:189
WebClient::Part::set_content_disposition
void set_content_disposition(ContentDisposition const &cd)
Definition: webclient.h:166
WebClient::Part
Definition: webclient.h:153
WebClient::Error::~Error
virtual ~Error()=default
WebContext::~WebContext
~WebContext()
Definition: webclient.cpp:1212
WebContext::Private::https_proxy
WebProxy https_proxy
Definition: webclient.cpp:121
ResponseHeader::Header
@ Header
Definition: webclient.cpp:508
USER_AGENT
#define USER_AGENT
Definition: webclient.cpp:44
WebClient::Request::url
URL url
Definition: webclient.h:90
ResponseHeader::internal
struct ResponseHeader::@14 internal
WebClient::URL::Data::scheme
std::string scheme
Definition: webclient.h:61
WebClient::Post::content_type
std::string content_type
Definition: webclient.h:144
WebContext::operator=
void operator=(WebContext const &r)=delete
WebClient::URL::URL
URL()=default
ResponseHeader::pos
size_t pos
Definition: webclient.cpp:498
WebClient::URL::isssl
bool isssl() const
Definition: webclient.cpp:167
WebClient::Request::set_basic_authorization
void set_basic_authorization(std::string const &uid, std::string const &pwd)
Definition: webclient.h:110
WebClient::ContentDisposition::type
std::string type
Definition: webclient.h:149
WebClient::URL::host
const std::string & host() const
Definition: webclient.h:70
WebClient::RequestOption::handler
WebClientHandler * handler
Definition: webclient.h:172
WebContext::load_cacert
bool load_cacert(char const *path)
Definition: webclient.cpp:1261
ResponseHeader::content_length
int content_length
Definition: webclient.cpp:500
WebClient::append
void append(char const *ptr, size_t len, std::vector< char > *out, WebClientHandler *handler)
Definition: webclient.cpp:448
WebClient::Private::content_offset
size_t content_offset
Definition: webclient.cpp:187
WebClient::receive_
void receive_(const RequestOption &opt, std::function< int(char *, int)> const &, ResponseHeader *rh, std::vector< char > *out)
Definition: webclient.cpp:585
WebClient
Definition: webclient.h:48
WebClient::Error
Definition: webclient.h:119
WebContext::Private::ctx
SSL_CTX * ctx
Definition: webclient.cpp:118
WebClient::Authorization::Basic
@ Basic
Definition: webclient.h:82
WebClient::Response::code
int code
Definition: webclient.h:135
WebClient::WebClient
WebClient(WebContext *webcx)
Definition: webclient.cpp:195
WebClient::Error::message
std::string message() const
Definition: webclient.h:129
WebClient::ContentType::APPLICATION_X_WWW_FORM_URLENCODED
static constexpr const char * APPLICATION_X_WWW_FORM_URLENCODED
Definition: webclient.h:53
WebClient::clear_error
void clear_error()
Definition: webclient.cpp:270
WebClient::Private::last_host_name
std::string last_host_name
Definition: webclient.cpp:188
WebClient::close
void close()
Definition: webclient.cpp:1110
WebContext::WebContext
WebContext(WebClient::HttpVersion httpver)
Definition: webclient.cpp:1199
WebClient::cleanup
static void cleanup()
Definition: webclient.cpp:228
WebClient::ContentDisposition::name
std::string name
Definition: webclient.h:150
WebClient::URL::Data
Definition: webclient.h:59
WebClient::Request::Request
Request()=default
WebContext::m
Private * m
Definition: webclient.h:228
HostNameResolver::resolve
bool resolve(char const *name, _in_addr *out)
Definition: webclient.cpp:99
WebContext::set_http_proxy
void set_http_proxy(std::string const &proxy)
Definition: webclient.cpp:1230
WebClient::on_end_header
void on_end_header(const std::vector< char > *vec, WebClientHandler *handler)
Definition: webclient.cpp:437
WebClient::Authorization::uid
std::string uid
Definition: webclient.h:84
base64_encode
void base64_encode(char const *src, size_t length, std::vector< char > *out)
Definition: base64.cpp:35
WebClient::Private::webcx
WebContext * webcx
Definition: webclient.cpp:184
WebClient::Private
Definition: webclient.cpp:180
HostNameResolver
Definition: webclient.h:16
WebClient::HttpVersion
HttpVersion
Definition: webclient.h:75
WebClient::~WebClient
~WebClient()
Definition: webclient.cpp:203
WebClient::operator=
void operator=(WebClient const &)=delete
WebClient::URL
Definition: webclient.h:56
WebClientHandler::abort
void abort(std::string const &message={})
Definition: webclient.cpp:175
WebClient::Response::version
struct WebClient::Response::Version version
WebClient::Part::data
const char * data
Definition: webclient.h:154
WebClient::Request::Request
Request(std::string const &loc, std::vector< std::string > const &headers={})
Definition: webclient.h:95
WebClient::URL::Data::full_request
std::string full_request
Definition: webclient.h:60
WebClient::Authorization::None
@ None
Definition: webclient.h:81
WebContext
Definition: webclient.h:224
WebClient::output_debug_strings
void output_debug_strings(const std::vector< std::string > &vec)
Definition: webclient.cpp:258
WebContext::set_keep_alive_enabled
void set_keep_alive_enabled(bool f)
Definition: webclient.cpp:1225
WebClient::RequestOption
Definition: webclient.h:171
WebClient::Part::Part
Part()=default
WebClient::reset
void reset()
Definition: webclient.cpp:238
WebClient::get
bool get(const Request &req, Post const *post, Response *out, WebClientHandler *handler)
Definition: webclient.cpp:935
send_
static void send_(socket_t s, char const *ptr, int len)
Definition: webclient.cpp:424
WebClient::parse_header
static void parse_header(std::vector< std::string > const *header, WebClient::Response *res)
Definition: webclient.cpp:986
WebClient::Error::msg_
std::string msg_
Definition: webclient.h:121
WebClient::Post::data
std::vector< char > data
Definition: webclient.h:146
WebClient::Authorization::Type
Type
Definition: webclient.h:80
WebClient::get_port
static int get_port(URL const *url, char const *scheme, char const *protocol)
Definition: webclient.cpp:275
WebClient::content_type
std::string content_type() const
Definition: webclient.cpp:1072
WebContext::notify_broken_pipe
void notify_broken_pipe()
Definition: webclient.cpp:1271
WebClientHandler::checkContent
virtual void checkContent(char const *ptr, size_t len)
Definition: webclient.h:30
WebClient::Private::request_header
std::vector< std::string > request_header
Definition: webclient.cpp:181
_in_addr
void _in_addr
Definition: webclient.h:13
WebClient::make_multipart_form_data
static void make_multipart_form_data(const std::vector< Part > &parts, WebClient::Post *out, std::string const &boundary)
Definition: webclient.cpp:1143
ResponseHeader::state
State state
Definition: webclient.cpp:511
WebClient::make_application_www_form_urlencoded
static void make_application_www_form_urlencoded(char const *begin, char const *end, WebClient::Post *out)
Definition: webclient.cpp:1136
WebClient::Private::sock
socket_t sock
Definition: webclient.cpp:191
WebClient::Private::http_version
WebClient::HttpVersion http_version
Definition: webclient.cpp:185
WebClient::Request
Definition: webclient.h:87
WebClient::ContentDisposition::filename
std::string filename
Definition: webclient.h:151
WebClient::make_http_request
std::string make_http_request(const Request &url, Post const *post, const WebProxy *proxy, bool https)
Definition: webclient.cpp:351
WebContext::https_proxy
const WebProxy * https_proxy() const
Definition: webclient.cpp:1250
WebClient::initialize
static void initialize()
Definition: webclient.cpp:214
WebClient::Private::response
WebClient::Response response
Definition: webclient.cpp:183
WebClient::header_value
static std::string header_value(std::vector< std::string > const *header, std::string const &name)
Definition: webclient.cpp:1049
base64.h
ResponseHeader::chunked
bool chunked
Definition: webclient.cpp:504
WebClient::Request::add_header
void add_header(std::string const &s)
Definition: webclient.h:114
WebClient::Part::size
size_t size
Definition: webclient.h:155
WebClient::ContentType::APPLICATION_OCTET_STREAM
static constexpr const char * APPLICATION_OCTET_STREAM
Definition: webclient.h:52
WebClient::Response::Version
Definition: webclient.h:136
WebClient::Response::header
std::vector< std::string > header
Definition: webclient.h:140
WebClient::checkip
static std::string checkip()
Definition: webclient.cpp:1287
WebClient::HTTP_1_0
@ HTTP_1_0
Definition: webclient.h:76
WebProxy::server
std::string server
Definition: webclient.h:39
WebContext::Private
Definition: webclient.cpp:116
WebClient::Authorization
Definition: webclient.h:79
socket_t
int socket_t
Definition: webclient.cpp:20
decode_chunked
bool decode_chunked(char const *ptr, char const *end, std::vector< char > *out)
Definition: webclient.cpp:902
WebClient::set_http_version
void set_http_version(HttpVersion httpver)
Definition: webclient.cpp:209
WebProxy
Definition: webclient.h:37
WebClientHandler
Definition: webclient.h:21
WebClient::Part::content_type
std::string content_type
Definition: webclient.h:156
WebClient::m
Private * m
Definition: webclient.h:176
to_s
static std::string to_s(size_t n)
Definition: webclient.cpp:296
WebClient::Error::Error
Error()=default
INVALID_SOCKET
#define INVALID_SOCKET
Definition: webclient.cpp:21
WebClient::URL::scheme
const std::string & scheme() const
Definition: webclient.h:69
ResponseHeader::connection_keep_alive
bool connection_keep_alive
Definition: webclient.cpp:501
WebClient::HTTP_1_1
@ HTTP_1_1
Definition: webclient.h:77
stristr
static char * stristr(char *str1, char const *str2)
Definition: webclient.cpp:484
ResponseHeader
Definition: webclient.cpp:496
WebClientHandler::checkHeader
virtual void checkHeader(WebClient *wc)
Definition: webclient.h:26
WebClient::ContentDisposition
Definition: webclient.h:148
WebClient::Request::set_authorization
void set_authorization(Authorization::Type type, std::string const &uid, std::string const &pwd)
Definition: webclient.h:104
WebClient::Private::ssl
SSL * ssl
Definition: webclient.cpp:192
WebClient::URL::Data::path
std::string path
Definition: webclient.h:64
WebProxy::empty
bool empty() const
Definition: webclient.h:40
WebClient::Private::keep_alive
bool keep_alive
Definition: webclient.cpp:190
WebContext::Private::broken_pipe
bool broken_pipe
Definition: webclient.cpp:122
WebClient::URL::path
const std::string & path() const
Definition: webclient.h:72
WebClient::Error::Error
Error(std::string const &message)
Definition: webclient.h:124
ResponseHeader::lf
int lf
Definition: webclient.cpp:506
WebClient::URL::port
int port() const
Definition: webclient.h:71
WebClient::content_length
size_t content_length() const
Definition: webclient.cpp:1087
WebContext::http_proxy
const WebProxy * http_proxy() const
Definition: webclient.cpp:1242
WebClient::Response::Version::hi
unsigned int hi
Definition: webclient.h:137
WebClient::Part::content_disposition
ContentDisposition content_disposition
Definition: webclient.h:157
WebClient::Part::content_transfer_encoding
std::string content_transfer_encoding
Definition: webclient.h:158
WebClient::Post::boundary
std::string boundary
Definition: webclient.h:145
WebClient::URL::data
struct WebClient::URL::Data data
WebClient::Post
Definition: webclient.h:143
WebClient::Private::error
WebClient::Error error
Definition: webclient.cpp:182
WebClient::set_default_header
void set_default_header(const Request &url, Post const *post, const RequestOption &opt)
Definition: webclient.cpp:303
WebClient::Request::headers
std::vector< std::string > headers
Definition: webclient.h:92
WebContext::set_http_version
void set_http_version(WebClient::HttpVersion httpver)
Definition: webclient.cpp:1220
inet_connect
static int inet_connect(std::string const &hostname, int port)
Definition: webclient.cpp:616
SOCKET_ERROR
#define SOCKET_ERROR
Definition: webclient.cpp:22
WebClient::parse_http_header
void parse_http_header(char const *begin, char const *end, std::vector< std::string > *header)
Definition: webclient.cpp:385
ResponseHeader::put
void put(int c)
Definition: webclient.cpp:512
WebClient::Request::auth
Authorization auth
Definition: webclient.h:91
WebClient::URL::Data::port
int port
Definition: webclient.h:63
ResponseHeader::State
State
Definition: webclient.cpp:507
WebContext::set_https_proxy
void set_https_proxy(std::string const &proxy)
Definition: webclient.cpp:1236
WebClient::RequestOption::keep_alive
bool keep_alive
Definition: webclient.h:173
WebClient::Authorization::type
enum WebClient::Authorization::Type type
WebContext::Private::http_proxy
WebProxy http_proxy
Definition: webclient.cpp:120
webclient.h
WebClient::content_data
const char * content_data() const
Definition: webclient.cpp:1092
closesocket
#define closesocket(S)
Definition: webclient.cpp:19
WebClient::http_get
bool http_get(const Request &request_req, Post const *post, RequestOption const &opt, ResponseHeader *rh, std::vector< char > *out)
Definition: webclient.cpp:636
ResponseHeader::Content
@ Content
Definition: webclient.cpp:509
ResponseHeader::connection_close
bool connection_close
Definition: webclient.cpp:502
WebContext::Private::http_version
WebClient::HttpVersion http_version
Definition: webclient.cpp:117
WebClient::Response
Definition: webclient.h:134
WebClient::response
const Response & response() const
Definition: webclient.cpp:1131
ResponseHeader::line
std::vector< char > line
Definition: webclient.cpp:499
WebClient::Request::set_location
void set_location(std::string const &loc)
Definition: webclient.h:100
WebClient::post
int post(const Request &req, Post const *post, WebClientHandler *handler=nullptr)
Definition: webclient.cpp:1104
WebClient::Response::content
std::vector< char > content
Definition: webclient.h:141
WebClient::URL::Data::host
std::string host
Definition: webclient.h:62
dtl::version
const string version
Definition: variables.hpp:66
WebClient::Authorization::pwd
std::string pwd
Definition: webclient.h:85
WebClient::ContentType::MULTIPART_FORM_DATA
static constexpr const char * MULTIPART_FORM_DATA
Definition: webclient.h:54
WebClient::Response::Version::lo
unsigned int lo
Definition: webclient.h:138
WebClient::add_header
void add_header(std::string const &text)
Definition: webclient.cpp:1126
WebClient::error
const Error & error() const
Definition: webclient.cpp:265
WebClient::https_get
bool https_get(const Request &request_url, Post const *post, RequestOption const &opt, ResponseHeader *rh, std::vector< char > *out)
Definition: webclient.cpp:686
WebContext::Private::use_keep_alive
bool use_keep_alive
Definition: webclient.cpp:119
WebClient::output_debug_string
void output_debug_string(char const *str)
Definition: webclient.cpp:247
WebClientHandler::~WebClientHandler
virtual ~WebClientHandler()=default
WebClient::ContentType
Definition: webclient.h:50