Http.hpp
Go to the documentation of this file.
1 
6 #pragma once
7 
8 #include <enet/Tcp.hpp>
9 #include <vector>
10 #include <map>
11 #include <thread>
12 #include <ethread/tools.hpp>
13 
14 namespace enet {
15  enum class HTTPAnswerCode {
16  c000_unknow = 0,
17  //1xx: Information
18  c100_continue = 100,
21  //2xx: Successful
22  c200_ok = 200,
23  c201_created,
29  //3xx: Redirection
30  c300_multipleChoices = 300,
32  c302_found,
38  //4xx: Client Error,
39  c400_badRequest = 400,
49  c410_gone,
57  //5xx: Server Error
65  };
66  std::ostream& operator <<(std::ostream& _os, enum enet::HTTPAnswerCode _obj);
67 
68  enum class HTTPProtocol {
69  http_0_1,
70  http_0_2,
71  http_0_3,
72  http_0_4,
73  http_0_5,
74  http_0_6,
75  http_0_7,
76  http_0_8,
77  http_0_9,
78  http_0_10,
79  http_1_0,
80  http_1_1,
81  http_1_2,
82  http_1_3,
83  http_1_4,
84  http_1_5,
85  http_1_6,
86  http_1_7,
87  http_1_8,
88  http_1_9,
89  http_1_10,
90  http_2_0,
91  http_2_1,
92  http_2_2,
93  http_2_3,
94  http_2_4,
95  http_2_5,
96  http_2_6,
97  http_2_7,
98  http_2_8,
99  http_2_9,
100  http_2_10,
101  http_3_0,
102  http_3_1,
103  http_3_2,
104  http_3_3,
105  http_3_4,
106  http_3_5,
107  http_3_6,
108  http_3_7,
109  http_3_8,
110  http_3_9,
111  http_3_10,
112  };
113  std::ostream& operator <<(std::ostream& _os, enum enet::HTTPProtocol _obj);
114  class HttpHeader {
115  protected:
116  // key, val
117  std::map<std::string, std::string> m_map;
118  enum HTTPProtocol m_protocol;
119  public:
120  void setKey(const std::string& _key, const std::string& _value);
121  void rmKey(const std::string& _key);
122  std::string getKey(const std::string& _key) const;
123  protected:
124  std::string generateKeys() const;
125  public:
126  enum HTTPProtocol getProtocol() const {
127  return m_protocol;
128  }
129  void setProtocol(enum HTTPProtocol _protocol) {
130  m_protocol = _protocol;
131  }
132  HttpHeader();
133  virtual ~HttpHeader() = default;
134  virtual std::string generate() const = 0;
135  };
136 
137  class HttpAnswer : public HttpHeader {
138  private:
139  enet::HTTPAnswerCode m_what;
140  std::string m_helpMessage;
141  public:
142  HttpAnswer(enum HTTPAnswerCode _code = enet::HTTPAnswerCode::c400_badRequest, const std::string& _help="");
143  void display() const;
144  std::string generate() const;
145  void setErrorCode(enum HTTPAnswerCode _value) {
146  m_what = _value;
147  }
148  enum HTTPAnswerCode getErrorCode() const {
149  return m_what;
150  }
151  void setHelp(const std::string& _value) {
152  m_helpMessage = _value;
153  }
154  const std::string& getHelp() const {
155  return m_helpMessage;
156  }
157  };
158  enum class HTTPReqType {
159  HTTP_GET,
160  HTTP_HEAD,
161  HTTP_POST,
162  HTTP_PUT,
163  HTTP_DELETE,
164  };
165  std::ostream& operator <<(std::ostream& _os, enum enet::HTTPReqType _obj);
166  class HttpRequest : public HttpHeader {
167  private:
168  // key, val
169  enum HTTPReqType m_req;
170  std::string m_uri;
171  public:
172  HttpRequest(enum enet::HTTPReqType _type=enet::HTTPReqType::HTTP_GET);
173  void display() const;
174  std::string generate() const;
175  void setType(enum enet::HTTPReqType _value) {
176  m_req = _value;
177  }
178  enum enet::HTTPReqType getType() const{
179  return m_req;
180  }
181  void setUri(const std::string& _value) {
182  m_uri = _value;
183  }
184  const std::string& getUri() const {
185  return m_uri;
186  }
187  };
188  class Http {
189  public:
190  Http(enet::Tcp _connection, bool _isServer=false);
191  virtual ~Http();
192  private:
193  bool m_isServer;
194  public:
195  bool getServerState() {
196  return m_isServer;
197  }
198  bool isServer() {
199  return m_isServer;
200  }
201  protected:
202  enet::HttpRequest m_requestHeader;
203  void setRequestHeader(const enet::HttpRequest& _req);
204  public:
205  const enet::HttpRequest& getRequestHeader() {
206  return m_requestHeader;
207  }
208  protected:
209  enet::HttpAnswer m_answerHeader;
210  void setAnswerHeader(const enet::HttpAnswer& _req);
211  public:
212  const enet::HttpAnswer& getAnswerHeader() {
213  return m_answerHeader;
214  }
215  protected:
216  enet::Tcp m_connection;
217  bool m_headerIsSend;
218  std::thread* m_thread;
219  bool m_threadRunning;
220  std::vector<uint8_t> m_temporaryBuffer;
221  private:
222  void threadCallback();
223  private:
224  void getHeader();
225  public:
226  void start();
227  void stop(bool _inThread=false);
228  bool isAlive() const {
229  return m_connection.getConnectionStatus() == enet::Tcp::status::link;
230  }
231  public:
232  using Observer = std::function<void(std::vector<uint8_t>&)>;
233  Observer m_observer;
240  template<class CLASS_TYPE>
241  void connect(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(std::vector<uint8_t>&)) {
242  m_observer = [=](std::vector<uint8_t>& _value){
243  (*_class.*_func)(_value);
244  };
245  }
246  void connect(Observer _func) {
247  m_observer = _func;
248  }
249  public:
250  using ObserverRaw = std::function<void(enet::Tcp&)>;
251  ObserverRaw m_observerRaw;
258  template<class CLASS_TYPE>
259  void connectRaw(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(enet::Tcp&)) {
260  m_observerRaw = [=](enet::Tcp& _connection){
261  (*_class.*_func)(_connection);
262  };
263  }
264  void connectRaw(ObserverRaw _func) {
265  m_observerRaw = _func;
266  }
267  public:
268  using ObserverRequest = std::function<void(const enet::HttpRequest&)>;
269  protected:
270  ObserverRequest m_observerRequest;
271  public:
272  using ObserverAnswer = std::function<void(const enet::HttpAnswer&)>;
273  protected:
274  ObserverAnswer m_observerAnswer;
275  public:
283  int32_t write(const void* _data, int32_t _len);
291  int32_t write(const std::string& _data, bool _writeBackSlashZero = true) {
292  if (_data.size() == 0) {
293  return 0;
294  }
295  if (_writeBackSlashZero == true) {
296  return write(_data.c_str(), _data.size()+1);
297  }
298  return write(_data.c_str(), _data.size());
299  }
307  template <class T>
308  int32_t write(const std::vector<T>& _data) {
309  if (_data.size() == 0) {
310  return 0;
311  }
312  size_t ret = write(&_data[0], _data.size()*sizeof(T));
313  if (ret <=0) {
314  return ret;
315  }
316  return ret/sizeof(T);
317  }
318  };
319 
320  class HttpClient : public Http {
321  public:
322  HttpClient(enet::Tcp _connection);
323  public:
324  void setHeader(const enet::HttpRequest& _header) {
325  setRequestHeader(_header);
326  }
327  public:
328  //bool get(const std::string& _address);
329  //bool post(const std::string& _address, const std::map<std::string, std::string>& _values);
330  //bool post(const std::string& _address, const std::string& _contentType, const std::string& _data);
331  public:
338  template<class CLASS_TYPE>
339  void connectHeader(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(const enet::HttpAnswer&)) {
340  m_observerAnswer = [=](const enet::HttpAnswer& _value){
341  (*_class.*_func)(_value);
342  };
343  }
344  void connectHeader(Http::ObserverAnswer _func) {
345  m_observerAnswer = _func;
346  }
347  };
348 
349  class HttpServer : public Http {
350  public:
351  HttpServer(enet::Tcp _connection);
352  public:
353  void setHeader(const enet::HttpAnswer& _header) {
354  setAnswerHeader(_header);
355  }
356  public:
363  template<class CLASS_TYPE>
364  void connectHeader(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(const enet::HttpRequest&)) {
365  m_observerRequest = [=](const enet::HttpRequest& _value){
366  (*_class.*_func)(_value);
367  };
368  }
369  void connectHeader(Http::ObserverRequest _func) {
370  m_observerRequest = _func;
371  }
372  };
373 }
374 
The server will not accept the request, because the request entity is too large.
std::function< void(std::vector< uint8_t > &)> Observer
Define an Observer: function pointer.
Definition: Http.hpp:232
Definition: Http.hpp:137
The server is delivering only part of the resource due to a range header sent by the client...
void connectHeader(CLASS_TYPE *_class, void(CLASS_TYPE::*_func)(const enet::HttpAnswer &))
Connect an function member on the signal with the shared_ptr object.
Definition: Http.hpp:339
The request was a legal request, but the server is refusing to respond to it. For use when authentica...
The server can only generate a response that is not accepted by the client.
The server either does not recognize the request method, or it lacks the ability to fulfill the reque...
The request could not be completed because of a conflict in the request.
Used in the resumable requests proposal to resume aborted PUT or POST requests.
The requester has asked the server to switch protocols.
The "Content-Length" is not defined. The server will not accept the request without it...
HTTPAnswerCode
Definition: Http.hpp:15
The requested page could not be found but may be available again in the future.
The request has been successfully processed, but is not returning any content.
Definition: Http.hpp:188
std::function< void(const enet::HttpRequest &)> ObserverRequest
Define an Observer: function pointer.
Definition: Http.hpp:268
The server will not accept the request, because the media type is not supported.
Definition: Http.hpp:320
The request has been accepted for processing, but the processing has not been completed.
Used in the resumable requests proposal to resume aborted PUT or POST requests.
The request cannot be fulfilled due to bad syntax.
The request has been successfully processed, but is not returning any content, and requires that the ...
The requested page has moved to a new URL.
The server will not accept the request, because the URL is too long. Occurs when you convert a POST r...
int32_t write(const std::vector< T > &_data)
Write a chunk of data on the socket.
Definition: Http.hpp:308
The client needs to authenticate to gain network access.
The requested page is no longer available.
The server does not support the HTTP protocol version used in the request.
The request is OK (this is the standard response for successful HTTP requests)
A link list. The user can select a link and go to that location. Maximum five addresses.
A generic error message, given when no more specific message is suitable.
The server is currently unavailable (overloaded or down)
The request has been successfully processed, but is returning information that may be from another so...
Indicates the requested page has not been modified since last requested.
void connectRaw(CLASS_TYPE *_class, void(CLASS_TYPE::*_func)(enet::Tcp &))
Connect an function member on the signal with the shared_ptr object.
Definition: Http.hpp:259
The server has received the request headers, and the client should proceed to send the request body...
The requested page has moved temporarily to a new URL.
enum status getConnectionStatus() const
Get the current Status of the connection.
Definition: Tcp.hpp:62
A request was made of a page using a request method not supported by that page.
std::function< void(const enet::HttpAnswer &)> ObserverAnswer
Define an Observer: function pointer.
Definition: Http.hpp:272
int32_t write(const std::string &_data, bool _writeBackSlashZero=true)
Write a chunk of data on the socket.
Definition: Http.hpp:291
The precondition given in the request evaluated to false by the server.
The server was acting as a gateway or proxy and received an invalid response from the upstream server...
The server timed out waiting for the request.
Definition: Http.hpp:114
The client has asked for a portion of the file, but the server cannot supply that portion...
void connect(CLASS_TYPE *_class, void(CLASS_TYPE::*_func)(std::vector< uint8_t > &))
Connect an function member on the signal with the shared_ptr object.
Definition: Http.hpp:241
Definition: Tcp.hpp:16
The server cannot meet the requirements of the Expect request-header field.
The request was a legal request, but the server is refusing to respond to it.
Definition: Http.hpp:166
The requested page has moved temporarily to a new URL.
The client must first authenticate itself with the proxy.
Main esvg namespace.
Definition: enet.hpp:17
The server was acting as a gateway or proxy and did not receive a timely response from the upstream s...
std::function< void(enet::Tcp &)> ObserverRaw
Define an Observer: function pointer.
Definition: Http.hpp:250
void connectHeader(CLASS_TYPE *_class, void(CLASS_TYPE::*_func)(const enet::HttpRequest &))
Connect an function member on the signal with the shared_ptr object.
Definition: Http.hpp:364
The requested page can be found under a different URL.
Definition: Http.hpp:349
The request has been fulfilled, and a new resource is created.