OpenZWave Library  1.6.778
HttpClient.h
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //
3 // HttpClient.h
4 //
5 // Cross-platform HttpClient
6 //
7 // Originally based upon minihttp client
8 // Copyright (c) 2016 Justin Hammond <Justin@dynam.ac>
9 //
10 // SOFTWARE NOTICE AND LICENSE
11 //
12 // This file is part of OpenZWave.
13 //
14 // OpenZWave is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU Lesser General Public License as published
16 // by the Free Software Foundation, either version 3 of the License,
17 // or (at your option) any later version.
18 //
19 // OpenZWave is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU Lesser General Public License for more details.
23 //
24 // You should have received a copy of the GNU Lesser General Public License
25 // along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
26 //
27 //-----------------------------------------------------------------------------
28 
29 // Original License Text:
30 /* This program is free software. It comes without any warranty, to
31  * the extent permitted by applicable law. You can redistribute it
32  * and/or modify it under the terms of the Do What The Fuck You Want
33  * To Public License, Version 2, as published by Sam Hocevar.
34  * See http://sam.zoy.org/wtfpl/COPYING for more details. */
35 
36 #ifndef MINIHTTPSOCKET_H
37 #define MINIHTTPSOCKET_H
38 
39 // ---- Compile config -----
40 #define MINIHTTP_SUPPORT_HTTP
41 #define MINIHTTP_SUPPORT_SOCKET_SET
42 // -------------------------
43 
44 // Intentionally avoid pulling in any other headers
45 
46 #include <string>
47 #include <map>
48 #include <queue>
49 
50 namespace OpenZWave
51 {
57  namespace Internal
58  {
59  namespace Platform
60  {
68  bool InitNetwork();
69 
75  void StopNetwork();
76 
85  bool HasSSL();
86 
99  bool SplitURI(const std::string& uri, std::string& host, std::string& file, int& port);
100 
110  void URLEncode(const std::string& s, std::string& enc);
111 
117  {
118  SSLR_OK = 0x0,
119  SSLR_NO_SSL = 0x1,
120  SSLR_FAIL = 0x2,
129  _SSLR_FORCE32BIT = 0x7fffffff
130  };
131 
138  class TcpSocket
139  {
140  public:
141  TcpSocket();
142  virtual ~TcpSocket();
143 
144  virtual bool HasPendingTask() const
145  {
146  return false;
147  }
148 
149  bool open(const char *addr = NULL, unsigned int port = 0);
150  void close();
151  bool update(); // returns true if something interesting happened (incoming data, closed connection, etc)
152 
153  bool isOpen(void);
154 
155  void SetBufsizeIn(unsigned int s);
156  bool SetNonBlocking(bool nonblock);
157  unsigned int GetBufSize()
158  {
159  return _inbufSize;
160  }
161  const char *GetHost(void)
162  {
163  return _host.c_str();
164  }
165  bool SendBytes(const void *buf, unsigned int len);
166 
167  // SSL related
168  bool initSSL(const char *certs);
169  bool hasSSL() const
170  {
171  return !!_sslctx;
172  }
173  void shutdownSSL();
175 
176  protected:
177  virtual void _OnCloseInternal();
178  virtual void _OnData(); // data received callback. Internal, should only be overloaded to call _OnRecv()
179 
180  virtual void _OnRecv(void *buf, unsigned int size) = 0;
181  virtual void _OnClose()
182  {
183  }
184  ; // close callback
185  virtual void _OnOpen()
186  {
187  } // called when opened
188  virtual bool _OnUpdate()
189  {
190  return true;
191  } // called before reading from the socket
192 
193  void _ShiftBuffer();
194 
195  char *_inbuf;
196  char *_readptr; // part of inbuf, optionally skipped header
197  char *_writeptr; // passed to recv(). usually equal to _inbuf, but may point inside the buffer in case of a partial transfer.
198 
199  unsigned int _inbufSize; // size of internal buffer
200  unsigned int _writeSize; // how many bytes can be written to _writeptr;
201  unsigned int _recvSize; // incoming size, max _inbufSize - 1
202 
203  unsigned int _lastport; // port used in last open() call
204 
205  bool _nonblocking; // Default true. If false, the current thread is blocked while waiting for input.
206 
207 #ifdef _WIN32
208  intptr_t _s; // socket handle. really an int, but to be sure its 64 bit compatible as it seems required on windows, we use this.
209 #else
210  long _s;
211 #endif
212 
213  std::string _host;
214 
215  private:
216  int _writeBytes(const unsigned char *buf, size_t len);
217  int _readBytes(unsigned char *buf, size_t maxlen);
218  void *_sslctx;
219  };
220 
221 #ifdef MINIHTTP_SUPPORT_HTTP
222 
223  enum HttpCode
224  {
225  HTTP_OK = 200,
227  };
228 
235  class POST
236  {
237  public:
238  void reserve(size_t res)
239  {
240  data.reserve(res);
241  }
242  POST& add(const char *key, const char *value);
243  const char *c_str() const
244  {
245  return data.c_str();
246  }
247  const std::string& str() const
248  {
249  return data;
250  }
251  bool empty() const
252  {
253  return data.empty();
254  }
255  size_t length() const
256  {
257  return data.length();
258  }
259  private:
260  std::string data;
261  };
262 
269  struct Request
270  {
272  port(80), user(NULL)
273  {
274  }
275  Request(const std::string& h, const std::string& res, int p = 80, void *u = NULL) :
276  host(h), resource(res), port(80), user(u), useSSL(false)
277  {
278  }
279 
280  std::string protocol;
281  std::string host;
282  std::string header; // set by socket
283  std::string resource;
284  std::string extraGetHeaders;
285  int port;
286  void *user;
287  bool useSSL;
288  POST post; // if this is empty, it's a GET request, otherwise a POST request
289  };
290 
298  {
299  public:
300 
301  HttpSocket();
302  virtual ~HttpSocket();
303 
304  virtual bool HasPendingTask() const
305  {
306  return ExpectMoreData() || _requestQ.size();
307  }
308 
309  void SetKeepAlive(unsigned int secs)
310  {
311  _keep_alive = secs;
312  }
313  void SetUserAgent(const std::string &s)
314  {
315  _user_agent = s;
316  }
317  void SetAcceptEncoding(const std::string& s)
318  {
319  _accept_encoding = s;
320  }
321  void SetFollowRedirect(bool follow)
322  {
323  _followRedir = follow;
324  }
325  void SetAlwaysHandle(bool h)
326  {
327  _alwaysHandle = h;
328  }
329  void SetDownloadFile(std::string filename)
330  {
331  _filename = filename;
332  }
333 
334  bool Download(const std::string& url, const char *extraRequest = NULL, void *user = NULL, const POST *post = NULL);
335  bool SendRequest(Request& what, bool enqueue);
336  bool SendRequest(const std::string what, const char *extraRequest = NULL, void *user = NULL);
337  bool QueueRequest(const std::string what, const char *extraRequest = NULL, void *user = NULL);
338 
339  unsigned int GetRemaining() const
340  {
341  return _remaining;
342  }
343 
344  unsigned int GetStatusCode() const
345  {
346  return _status;
347  }
348  unsigned int GetContentLen() const
349  {
350  return _contentLen;
351  }
352  bool ChunkedTransfer() const
353  {
354  return _chunkedTransfer;
355  }
356  bool ExpectMoreData() const
357  {
358  return _remaining || _chunkedTransfer;
359  }
360 
361  const Request &GetCurrentRequest() const
362  {
363  return _curRequest;
364  }
365  const char *Hdr(const char *h) const;
366 
367  bool IsRedirecting() const;
368  bool IsSuccess() const;
369 
370  protected:
371  virtual void _OnCloseInternal();
372  virtual void _OnClose();
373  virtual void _OnData(); // data received callback. Internal, should only be overloaded to call _OnRecv()
374  virtual void _OnRecv(void *buf, unsigned int size);
375  virtual void _OnOpen(); // called when opene
376  virtual bool _OnUpdate(); // called before reading from the socket
377 
378  // new ones:
379  virtual void _OnRequestDone()
380  {
381  }
382 
383  bool _Redirect(std::string loc, bool forceGET);
384 
385  void _ProcessChunk();
386  bool _EnqueueOrSend(const Request& req, bool forceQueue = false);
387  void _DequeueMore();
388  bool _OpenRequest(const Request& req);
389  void _ParseHeader();
390  void _ParseHeaderFields(const char *s, size_t size);
391  bool _HandleStatus(); // Returns whether the processed request was successful, or not
392  void _FinishRequest();
393  void _OnRecvInternal(void *buf, unsigned int size);
394 
395  std::string _user_agent;
396  std::string _accept_encoding; // Default empty.
397  std::string _tmpHdr; // used to save the http header if the incoming buffer was not large enough
398 
399  unsigned int _keep_alive; // http related
400  unsigned int _remaining; // http "Content-Length: X" - already recvd. 0 if ready for next packet.
401  // For chunked transfer encoding, this holds the remaining size of the current chunk
402  unsigned int _contentLen; // as reported by server
403  unsigned int _status; // http status code, HTTP_OK if things are good
404 
405  std::queue<Request> _requestQ;
406  std::map<std::string, std::string> _hdrs; // Maps HTTP header fields to their values
407 
409 
412  bool _mustClose; // keep-alive specified, or not
413  bool _followRedir; // Default true. Follow 3xx redirects if this is set.
414  bool _alwaysHandle; // Also deliver to _OnRecv() if a non-success code was received.
415  std::string _filename;
416  FILE* _pFile;
417  };
418 
419 #endif
420 
421 // ------------------------------------------------------------------------
422 
423 #ifdef MINIHTTP_SUPPORT_SOCKET_SET
424 
431  class SocketSet
432  {
433  public:
434  virtual ~SocketSet();
435  void deleteAll();
436  bool update();
437  void add(TcpSocket *s, bool deleteWhenDone = true);
438  bool has(TcpSocket *s);
439  void remove(TcpSocket *s);
440  inline size_t size()
441  {
442  return _store.size();
443  }
444 
445 //protected:
446 
448  {
450  // To be extended
451  };
452 
453  typedef std::map<TcpSocket*, SocketSetData> Store;
454 
456  };
457 
458 #endif
459  } // namespace Platform
460  } // namespace Internal
461 } // namespace OpenZWave
462 
463 #endif
char * _inbuf
Definition: HttpClient.h:195
virtual bool _OnUpdate()
Definition: HttpClient.h:188
a Socket that speaks HTTP protocol.Talk to a HTTP(s) server
Definition: HttpClient.h:297
size_t length() const
Definition: HttpClient.h:255
virtual bool HasPendingTask() const
Definition: HttpClient.h:144
bool isOpen(void)
Definition: HttpClient.cpp:368
bool SplitURI(const std::string &uri, std::string &protocol, std::string &host, std::string &file, int &port, bool &useSSL)
Definition: HttpClient.cpp:258
virtual void _OnData()
Definition: HttpClient.cpp:746
const char * GetHost(void)
Definition: HttpClient.h:161
std::map< TcpSocket *, SocketSetData > Store
Definition: HttpClient.h:453
unsigned int _writeSize
Definition: HttpClient.h:200
std::string _accept_encoding
Definition: HttpClient.h:396
Definition: Bitfield.cpp:30
bool hasSSL() const
Definition: HttpClient.h:169
void _OnRecvInternal(void *buf, unsigned int size)
void SetFollowRedirect(bool follow)
Definition: HttpClient.h:321
bool empty() const
Definition: HttpClient.h:251
unsigned int GetContentLen() const
Definition: HttpClient.h:348
unsigned int GetRemaining() const
Definition: HttpClient.h:339
void _ShiftBuffer()
Definition: HttpClient.cpp:737
Store _store
Definition: HttpClient.h:455
std::string _user_agent
Definition: HttpClient.h:395
char * _writeptr
Definition: HttpClient.h:197
Support Multiple TCP Socket connectionsto Support multiple TCP Socket Connections.
Definition: HttpClient.h:431
bool _nonblocking
Definition: HttpClient.h:205
std::string _host
Definition: HttpClient.h:213
const Request & GetCurrentRequest() const
Definition: HttpClient.h:361
bool QueueRequest(const std::string what, const char *extraRequest=NULL, void *user=NULL)
unsigned int _contentLen
Definition: HttpClient.h:402
unsigned int _keep_alive
Definition: HttpClient.h:399
size_t size()
Definition: HttpClient.h:440
bool InitNetwork()
Initialize the Network for HTTP requestsInitializes the Network for HTTP requests.
Definition: HttpClient.cpp:206
virtual bool HasPendingTask() const
Definition: HttpClient.h:304
bool _chunkedTransfer
Definition: HttpClient.h:411
FILE * _pFile
Definition: HttpClient.h:416
void SetAcceptEncoding(const std::string &s)
Definition: HttpClient.h:317
void close()
Definition: HttpClient.cpp:373
bool _Redirect(std::string loc, bool forceGET)
#define NULL
Definition: Defs.h:82
Main class for making a HTTP request to a HTTP(s) serverMake a request to a HTTP Server.
Definition: HttpClient.h:269
bool _inProgress
Definition: HttpClient.h:410
unsigned int _remaining
Definition: HttpClient.h:400
char * _readptr
Definition: HttpClient.h:196
void SetAlwaysHandle(bool h)
Definition: HttpClient.h:325
void add(TcpSocket *s, bool deleteWhenDone=true)
unsigned int GetBufSize()
Definition: HttpClient.h:157
void SetKeepAlive(unsigned int secs)
Definition: HttpClient.h:309
virtual ~TcpSocket()
Definition: HttpClient.cpp:361
unsigned int _recvSize
Definition: HttpClient.h:201
std::queue< Request > _requestQ
Definition: HttpClient.h:405
bool SendBytes(const void *buf, unsigned int len)
Definition: HttpClient.cpp:673
const char * Hdr(const char *h) const
bool _followRedir
Definition: HttpClient.h:413
const char * c_str() const
Definition: HttpClient.h:243
unsigned int _inbufSize
Definition: HttpClient.h:199
unsigned int _lastport
Definition: HttpClient.h:203
std::map< std::string, std::string > _hdrs
Definition: HttpClient.h:406
virtual void _OnCloseInternal()
Definition: HttpClient.cpp:399
bool _alwaysHandle
Definition: HttpClient.h:414
bool SetNonBlocking(bool nonblock)
Definition: HttpClient.cpp:404
std::string _tmpHdr
Definition: HttpClient.h:397
Definition: HttpClient.h:119
void reserve(size_t res)
Definition: HttpClient.h:238
unsigned int _status
Definition: HttpClient.h:403
std::string resource
Definition: HttpClient.h:283
virtual void _OnRequestDone()
Definition: HttpClient.h:379
Definition: HttpClient.h:225
bool _mustClose
Definition: HttpClient.h:412
bool initSSL(const char *certs)
Definition: HttpClient.cpp:661
bool useSSL
Definition: HttpClient.h:287
POST post
Definition: HttpClient.h:288
std::string protocol
Definition: HttpClient.h:280
void shutdownSSL()
Definition: HttpClient.cpp:657
void _ParseHeaderFields(const char *s, size_t size)
void SetBufsizeIn(unsigned int s)
Definition: HttpClient.cpp:410
virtual void _OnOpen()
Definition: HttpClient.h:185
void SetDownloadFile(std::string filename)
Definition: HttpClient.h:329
bool SendRequest(Request &what, bool enqueue)
a TCP Socket that can optionally be protected via SSLThis represents a TCP Socket that can be encrypt...
Definition: HttpClient.h:138
SSLResult
Result Codes for SSL operations.
Definition: HttpClient.h:116
const std::string & str() const
Definition: HttpClient.h:247
virtual void _OnClose()
Definition: HttpClient.h:181
void URLEncode(const std::string &s, std::string &enc)
Encode a String suitable for sending as a URL request (eg Get)Encode a String so it can be sent as pa...
Definition: HttpClient.cpp:308
POST & add(const char *key, const char *value)
long _s
Definition: HttpClient.h:210
This class is used for Posting data to a HTTP(s) serverPost some data to a HTTP(s) server...
Definition: HttpClient.h:235
Definition: HttpClient.h:120
virtual void _OnRecv(void *buf, unsigned int size)
void * user
Definition: HttpClient.h:286
Request(const std::string &h, const std::string &res, int p=80, void *u=NULL)
Definition: HttpClient.h:275
SSLResult verifySSL()
Definition: HttpClient.cpp:667
Request _curRequest
Definition: HttpClient.h:408
std::string header
Definition: HttpClient.h:282
bool open(const char *addr=NULL, unsigned int port=0)
Definition: HttpClient.cpp:508
TcpSocket()
Definition: HttpClient.cpp:356
bool ChunkedTransfer() const
Definition: HttpClient.h:352
HttpCode
Definition: HttpClient.h:223
Definition: HttpClient.h:118
int port
Definition: HttpClient.h:285
void SetUserAgent(const std::string &s)
Definition: HttpClient.h:313
virtual void _OnRecv(void *buf, unsigned int size)=0
bool HasSSL()
Indicates if we support HTTPS requestsIndicates if we support HTTPS requests.
Definition: HttpClient.cpp:165
std::string extraGetHeaders
Definition: HttpClient.h:284
unsigned int GetStatusCode() const
Definition: HttpClient.h:344
Request()
Definition: HttpClient.h:271
bool ExpectMoreData() const
Definition: HttpClient.h:356
bool _OpenRequest(const Request &req)
bool _EnqueueOrSend(const Request &req, bool forceQueue=false)
std::string host
Definition: HttpClient.h:281
bool Download(const std::string &url, const char *extraRequest=NULL, void *user=NULL, const POST *post=NULL)
void StopNetwork()
Stop the Network for HTTP requestsStops the Network for HTTP requests and releases resources associat...
Definition: HttpClient.cpp:219
std::string _filename
Definition: HttpClient.h:415
bool update()
Definition: HttpClient.cpp:763