OpenZWave Library  1.5.0
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 
51 namespace OpenZWave
52 {
58 namespace SimpleHTTPClient
59 {
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 
139 {
140 public:
141  TcpSocket();
142  virtual ~TcpSocket();
143 
144  virtual bool HasPendingTask() const { return false; }
145 
146  bool open(const char *addr = NULL, unsigned int port = 0);
147  void close();
148  bool update(); // returns true if something interesting happened (incoming data, closed connection, etc)
149 
150  bool isOpen(void);
151 
152  void SetBufsizeIn(unsigned int s);
153  bool SetNonBlocking(bool nonblock);
154  unsigned int GetBufSize() { return _inbufSize; }
155  const char *GetHost(void) { return _host.c_str(); }
156  bool SendBytes(const void *buf, unsigned int len);
157 
158  // SSL related
159  bool initSSL(const char *certs);
160  bool hasSSL() const { return !!_sslctx; }
161  void shutdownSSL();
163 
164 protected:
165  virtual void _OnCloseInternal();
166  virtual void _OnData(); // data received callback. Internal, should only be overloaded to call _OnRecv()
167 
168  virtual void _OnRecv(void *buf, unsigned int size) = 0;
169  virtual void _OnClose() {}; // close callback
170  virtual void _OnOpen() {} // called when opened
171  virtual bool _OnUpdate() { return true; } // called before reading from the socket
172 
173  void _ShiftBuffer();
174 
175  char *_inbuf;
176  char *_readptr; // part of inbuf, optionally skipped header
177  char *_writeptr; // passed to recv(). usually equal to _inbuf, but may point inside the buffer in case of a partial transfer.
178 
179  unsigned int _inbufSize; // size of internal buffer
180  unsigned int _writeSize; // how many bytes can be written to _writeptr;
181  unsigned int _recvSize; // incoming size, max _inbufSize - 1
182 
183  unsigned int _lastport; // port used in last open() call
184 
185  bool _nonblocking; // Default true. If false, the current thread is blocked while waiting for input.
186 
187 #ifdef _WIN32
188  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.
189 #else
190  long _s;
191 #endif
192 
193  std::string _host;
194 
195 private:
196  int _writeBytes(const unsigned char *buf, size_t len);
197  int _readBytes(unsigned char *buf, size_t maxlen);
198  void *_sslctx;
199 };
200 
201 #ifdef MINIHTTP_SUPPORT_HTTP
202 
204 {
205  HTTP_OK = 200,
207 };
208 
215 class POST
216 {
217 public:
218  void reserve(size_t res) { data.reserve(res); }
219  POST& add(const char *key, const char *value);
220  const char *c_str() const { return data.c_str(); }
221  const std::string& str() const { return data; }
222  bool empty() const { return data.empty(); }
223  size_t length() const { return data.length(); }
224 private:
225  std::string data;
226 };
227 
234 struct Request
235 {
236  Request() : port(80), user(NULL) {}
237  Request(const std::string& h, const std::string& res, int p = 80, void *u = NULL)
238  : host(h), resource(res), port(80), user(u), useSSL(false) {}
239 
240  std::string protocol;
241  std::string host;
242  std::string header; // set by socket
243  std::string resource;
244  std::string extraGetHeaders;
245  int port;
246  void *user;
247  bool useSSL;
248  POST post; // if this is empty, it's a GET request, otherwise a POST request
249 };
250 
258 {
259 public:
260 
261  HttpSocket();
262  virtual ~HttpSocket();
263 
264  virtual bool HasPendingTask() const
265  {
266  return ExpectMoreData() || _requestQ.size();
267  }
268 
269  void SetKeepAlive(unsigned int secs) { _keep_alive = secs; }
270  void SetUserAgent(const std::string &s) { _user_agent = s; }
271  void SetAcceptEncoding(const std::string& s) { _accept_encoding = s; }
272  void SetFollowRedirect(bool follow) { _followRedir = follow; }
273  void SetAlwaysHandle(bool h) { _alwaysHandle = h; }
274  void SetDownloadFile(std::string filename) { _filename = filename; }
275 
276  bool Download(const std::string& url, const char *extraRequest = NULL, void *user = NULL, const POST *post = NULL);
277  bool SendRequest(Request& what, bool enqueue);
278  bool SendRequest(const std::string what, const char *extraRequest = NULL, void *user = NULL);
279  bool QueueRequest(const std::string what, const char *extraRequest = NULL, void *user = NULL);
280 
281  unsigned int GetRemaining() const { return _remaining; }
282 
283  unsigned int GetStatusCode() const { return _status; }
284  unsigned int GetContentLen() const { return _contentLen; }
285  bool ChunkedTransfer() const { return _chunkedTransfer; }
286  bool ExpectMoreData() const { return _remaining || _chunkedTransfer; }
287 
288  const Request &GetCurrentRequest() const { return _curRequest; }
289  const char *Hdr(const char *h) const;
290 
291  bool IsRedirecting() const;
292  bool IsSuccess() const;
293 
294 protected:
295  virtual void _OnCloseInternal();
296  virtual void _OnClose();
297  virtual void _OnData(); // data received callback. Internal, should only be overloaded to call _OnRecv()
298  virtual void _OnRecv(void *buf, unsigned int size);
299  virtual void _OnOpen(); // called when opene
300  virtual bool _OnUpdate(); // called before reading from the socket
301 
302  // new ones:
303  virtual void _OnRequestDone() {}
304 
305  bool _Redirect(std::string loc, bool forceGET);
306 
307  void _ProcessChunk();
308  bool _EnqueueOrSend(const Request& req, bool forceQueue = false);
309  void _DequeueMore();
310  bool _OpenRequest(const Request& req);
311  void _ParseHeader();
312  void _ParseHeaderFields(const char *s, size_t size);
313  bool _HandleStatus(); // Returns whether the processed request was successful, or not
314  void _FinishRequest();
315  void _OnRecvInternal(void *buf, unsigned int size);
316 
317  std::string _user_agent;
318  std::string _accept_encoding; // Default empty.
319  std::string _tmpHdr; // used to save the http header if the incoming buffer was not large enough
320 
321  unsigned int _keep_alive; // http related
322  unsigned int _remaining; // http "Content-Length: X" - already recvd. 0 if ready for next packet.
323  // For chunked transfer encoding, this holds the remaining size of the current chunk
324  unsigned int _contentLen; // as reported by server
325  unsigned int _status; // http status code, HTTP_OK if things are good
326 
327  std::queue<Request> _requestQ;
328  std::map<std::string, std::string> _hdrs; // Maps HTTP header fields to their values
329 
331 
334  bool _mustClose; // keep-alive specified, or not
335  bool _followRedir; // Default true. Follow 3xx redirects if this is set.
336  bool _alwaysHandle; // Also deliver to _OnRecv() if a non-success code was received.
337  std::string _filename;
338  FILE* _pFile;
339 };
340 
341 
342 #endif
343 
344 // ------------------------------------------------------------------------
345 
346 #ifdef MINIHTTP_SUPPORT_SOCKET_SET
347 
355 {
356 public:
357  virtual ~SocketSet();
358  void deleteAll();
359  bool update();
360  void add(TcpSocket *s, bool deleteWhenDone = true);
361  bool has(TcpSocket *s);
362  void remove(TcpSocket *s);
363  inline size_t size() { return _store.size(); }
364 
365 //protected:
366 
368  {
370  // To be extended
371  };
372 
373  typedef std::map<TcpSocket*, SocketSetData> Store;
374 
376 };
377 
378 #endif
379 
380 } // end HttpClient namespace
381 } // end openzwave namespace
382 
383 
384 #endif
virtual void _OnClose()
Definition: HttpClient.h:169
bool _inProgress
Definition: HttpClient.h:332
void SetBufsizeIn(unsigned int s)
Definition: HttpClient.cpp:457
bool SplitURI(const std::string &uri, std::string &protocol, std::string &host, std::string &file, int &port, bool &useSSL)
Definition: HttpClient.cpp:267
Main class for making a HTTP request to a HTTP(s) serverMake a request to a HTTP Server.
Definition: HttpClient.h:234
std::string _host
Definition: HttpClient.h:193
virtual bool HasPendingTask() const
Definition: HttpClient.h:144
unsigned int GetRemaining() const
Definition: HttpClient.h:281
Definition: Bitfield.h:34
bool update()
Definition: HttpClient.cpp:845
bool _nonblocking
Definition: HttpClient.h:185
SSLResult verifySSL()
Definition: HttpClient.cpp:731
virtual void _OnOpen()
Definition: HttpClient.h:170
a Socket that speaks HTTP protocol.Talk to a HTTP(s) server
Definition: HttpClient.h:257
void _ShiftBuffer()
Definition: HttpClient.cpp:811
long _s
Definition: HttpClient.h:190
unsigned int GetStatusCode() const
Definition: HttpClient.h:283
bool hasSSL() const
Definition: HttpClient.h:160
POST post
Definition: HttpClient.h:248
bool open(const char *addr=NULL, unsigned int port=0)
Definition: HttpClient.cpp:563
void add(TcpSocket *s, bool deleteWhenDone=true)
bool HasSSL()
Indicates if we support HTTPS requestsIndicates if we support HTTPS requests.
Definition: HttpClient.cpp:158
POST & add(const char *key, const char *value)
const std::string & str() const
Definition: HttpClient.h:221
std::string _user_agent
Definition: HttpClient.h:317
void SetFollowRedirect(bool follow)
Definition: HttpClient.h:272
std::string header
Definition: HttpClient.h:242
SSLResult
Result Codes for SSL operations.
Definition: HttpClient.h:116
virtual bool HasPendingTask() const
Definition: HttpClient.h:264
void SetAcceptEncoding(const std::string &s)
Definition: HttpClient.h:271
const char * Hdr(const char *h) const
#define NULL
Definition: Defs.h:86
const char * c_str() const
Definition: HttpClient.h:220
bool _followRedir
Definition: HttpClient.h:335
bool InitNetwork()
Initialize the Network for HTTP requestsInitializes the Network for HTTP requests.
Definition: HttpClient.cpp:206
unsigned int _writeSize
Definition: HttpClient.h:180
char * _readptr
Definition: HttpClient.h:176
virtual void _OnData()
Definition: HttpClient.cpp:822
unsigned int _recvSize
Definition: HttpClient.h:181
std::queue< Request > _requestQ
Definition: HttpClient.h:327
size_t length() const
Definition: HttpClient.h:223
Definition: HttpClient.h:205
bool SetNonBlocking(bool nonblock)
Definition: HttpClient.cpp:448
Definition: HttpClient.h:118
TcpSocket()
Definition: HttpClient.cpp:381
unsigned int GetContentLen() const
Definition: HttpClient.h:284
bool QueueRequest(const std::string what, const char *extraRequest=NULL, void *user=NULL)
Support Multiple TCP Socket connectionsto Support multiple TCP Socket Connections.
Definition: HttpClient.h:354
Request()
Definition: HttpClient.h:236
virtual void _OnRecv(void *buf, unsigned int size)
void StopNetwork()
Stop the Network for HTTP requestsStops the Network for HTTP requests and releases resources associat...
Definition: HttpClient.cpp:221
std::string _filename
Definition: HttpClient.h:337
bool SendRequest(Request &what, bool enqueue)
Request(const std::string &h, const std::string &res, int p=80, void *u=NULL)
Definition: HttpClient.h:237
bool useSSL
Definition: HttpClient.h:247
Store _store
Definition: HttpClient.h:375
void SetAlwaysHandle(bool h)
Definition: HttpClient.h:273
void shutdownSSL()
Definition: HttpClient.cpp:716
bool _alwaysHandle
Definition: HttpClient.h:336
std::map< TcpSocket *, SocketSetData > Store
Definition: HttpClient.h:373
std::string _tmpHdr
Definition: HttpClient.h:319
bool isOpen(void)
Definition: HttpClient.cpp:406
a TCP Socket that can optionally be protected via SSLThis represents a TCP Socket that can be encrypt...
Definition: HttpClient.h:138
const Request & GetCurrentRequest() const
Definition: HttpClient.h:288
bool _Redirect(std::string loc, bool forceGET)
virtual void _OnCloseInternal()
Definition: HttpClient.cpp:441
bool _EnqueueOrSend(const Request &req, bool forceQueue=false)
This class is used for Posting data to a HTTP(s) serverPost some data to a HTTP(s) server.
Definition: HttpClient.h:215
Definition: HttpClient.h:120
void _ParseHeaderFields(const char *s, size_t size)
Request _curRequest
Definition: HttpClient.h:330
const char * GetHost(void)
Definition: HttpClient.h:155
bool initSSL(const char *certs)
Definition: HttpClient.cpp:722
size_t size()
Definition: HttpClient.h:363
void SetDownloadFile(std::string filename)
Definition: HttpClient.h:274
char * _inbuf
Definition: HttpClient.h:175
Definition: HttpClient.h:119
virtual ~TcpSocket()
Definition: HttpClient.cpp:397
unsigned int GetBufSize()
Definition: HttpClient.h:154
bool _OpenRequest(const Request &req)
unsigned int _keep_alive
Definition: HttpClient.h:321
void SetUserAgent(const std::string &s)
Definition: HttpClient.h:270
std::string _accept_encoding
Definition: HttpClient.h:318
unsigned int _status
Definition: HttpClient.h:325
std::string extraGetHeaders
Definition: HttpClient.h:244
virtual void _OnRequestDone()
Definition: HttpClient.h:303
unsigned int _contentLen
Definition: HttpClient.h:324
char * _writeptr
Definition: HttpClient.h:177
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:325
std::map< std::string, std::string > _hdrs
Definition: HttpClient.h:328
bool _chunkedTransfer
Definition: HttpClient.h:333
void close()
Definition: HttpClient.cpp:413
int port
Definition: HttpClient.h:245
bool deleteWhenDone
Definition: HttpClient.h:369
void * user
Definition: HttpClient.h:246
bool Download(const std::string &url, const char *extraRequest=NULL, void *user=NULL, const POST *post=NULL)
unsigned int _remaining
Definition: HttpClient.h:322
void reserve(size_t res)
Definition: HttpClient.h:218
HttpCode
Definition: HttpClient.h:203
bool _mustClose
Definition: HttpClient.h:334
void SetKeepAlive(unsigned int secs)
Definition: HttpClient.h:269
std::string host
Definition: HttpClient.h:241
bool ChunkedTransfer() const
Definition: HttpClient.h:285
unsigned int _inbufSize
Definition: HttpClient.h:179
void _OnRecvInternal(void *buf, unsigned int size)
unsigned int _lastport
Definition: HttpClient.h:183
virtual void _OnRecv(void *buf, unsigned int size)=0
Definition: HttpClient.h:206
std::string resource
Definition: HttpClient.h:243
FILE * _pFile
Definition: HttpClient.h:338
bool ExpectMoreData() const
Definition: HttpClient.h:286
bool SendBytes(const void *buf, unsigned int len)
Definition: HttpClient.cpp:739
virtual bool _OnUpdate()
Definition: HttpClient.h:171
std::string protocol
Definition: HttpClient.h:240
bool empty() const
Definition: HttpClient.h:222