libhomegear-base  0.7
Base library for Homegear and Homegear family modules.
Http.h
Go to the documentation of this file.
1 /* Copyright 2013-2019 Homegear GmbH
2  *
3  * libhomegear-base is free software: you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public License as
5  * published by the Free Software Foundation, either version 3 of the
6  * License, or (at your option) any later version.
7  *
8  * libhomegear-base is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with libhomegear-base. If not, see
15  * <http://www.gnu.org/licenses/>.
16  *
17  * In addition, as a special exception, the copyright holders give
18  * permission to link the code of portions of this program with the
19  * OpenSSL library under certain conditions as described in each
20  * individual source file, and distribute linked combinations
21  * including the two.
22  * You must obey the GNU Lesser General Public License in all respects
23  * for all of the code used other than OpenSSL. If you modify
24  * file(s) with this exception, you may extend this exception to your
25  * version of the file(s), but you are not obligated to do so. If you
26  * do not wish to do so, delete this exception statement from your
27  * version. If you delete this exception statement from all source
28  * files in the program, then also delete it here.
29 */
30 
31 #ifndef HTTP_H_
32 #define HTTP_H_
33 
34 #include "../Variable.h"
35 #include "../Exception.h"
36 #include "../HelperFunctions/Math.h"
37 
38 #include <string>
39 #include <map>
40 #include <cstring>
41 #include <memory>
42 #include <vector>
43 #include <set>
44 #include <unordered_set>
45 
46 namespace BaseLib {
48  private:
49  int32_t _responseCode = -1;
50  public:
51  HttpException(std::string message) : Exception(message) {}
52  HttpException(std::string message, int32_t responseCode) : Exception(message), _responseCode(responseCode) {}
53 
54  int32_t responseCode() const { return _responseCode; }
55 };
56 
57 class Http {
58  public:
59  struct Type {
60  enum Enum { none, request, response };
61  };
62  struct AcceptEncoding {
63  enum Enum { none = 0, deflate = 4, gzip = 8, br = 32 };
64  };
65  struct ContentEncoding {
66  enum Enum { none = 0, gzip = 8 };
67  };
69  enum Enum { none = 0, chunked = 1, compress = 2, deflate = 4, gzip = 8, identity = 16, trailers = 32 };
70  };
71  struct Connection {
72  enum Enum { none = 0, keepAlive = 1, close = 2, upgrade = 4 };
73  };
74  struct Protocol {
75  enum Enum { none, http10, http11, http20 };
76  };
77  struct Header {
78  bool parsed = false;
79  std::string method;
80  Protocol::Enum protocol = Protocol::Enum::none;
81  int32_t responseCode = -1;
82  uint32_t contentLength = 0;
83  std::string path;
84  std::string pathInfo;
85  std::string args;
86  std::string host;
87  std::string contentType;
88  std::string contentTypeFull;
89  AcceptEncoding::Enum acceptEncoding = AcceptEncoding::Enum::none;
90  ContentEncoding::Enum contentEncoding = ContentEncoding::Enum::none;
91  TransferEncoding::Enum transferEncoding = TransferEncoding::Enum::none;
92  Connection::Enum connection = Connection::Enum::none;
93  std::string authorization;
94  std::string cookie;
95  std::unordered_map<std::string, std::string> cookies;
96  std::string remoteAddress;
97  int32_t remotePort = 0;
98  std::map<std::string, std::string> fields;
99  };
100 
101  struct FormData {
102  std::string contentDisposition;
103  std::string name;
104  std::string filename;
105  std::string contentType;
106  std::string contentTypeFull;
107  std::unordered_map<std::string, std::string> header;
108  std::shared_ptr<std::vector<char>> data;
109  std::set<std::shared_ptr<FormData>> multipartMixed;
110  };
111 
112  Http();
113  virtual ~Http();
114 
115  Type::Enum getType() { return _type; }
116  bool headerIsFinished() { return _header.parsed; }
117  bool isFinished() { return _finished; }
118  std::string getRedirectUrl() { return _redirectUrl; }
119  void setRedirectUrl(std::string value) { _redirectUrl = value; }
120  std::string getRedirectQueryString() { return _redirectQueryString; }
121  void setRedirectQueryString(std::string value) { _redirectQueryString = value; }
122  int32_t getRedirectStatus() { return _redirectStatus; }
123  void setRedirectStatus(int32_t value) { _redirectStatus = value; }
124  size_t getMaxHeaderSize() { return _maxHeaderSize; }
125  void setMaxHeaderSize(size_t value) { _maxHeaderSize = value; }
126  size_t getMaxContentSize() { return _maxContentSize; }
127  void setMaxContentSize(size_t value) { _maxContentSize = value; }
128 
135  void setFinished();
136  const std::vector<char> &getRawHeader() const { return _rawHeader; }
137  const std::vector<char> &getContent() const { return _content; }
138  uint32_t getContentSize() const { return _content.empty() ? 0 : (_finished ? _content.size() - 1 : _content.size()); }
139  Header &getHeader() { return _header; }
140  std::unordered_map<std::string, std::string> getParsedQueryString();
141  void reset();
142 
152  int32_t process(char *buffer, int32_t bufferLength, bool checkForChunkedXml = false, bool checkForChunkedJson = false);
153  bool headerProcessingStarted() { return _headerProcessingStarted; }
154  bool dataProcessingStarted() { return _dataProcessingStarted; }
155  static std::string encodeURL(const std::string &url);
156  static std::string decodeURL(const std::string &url);
157  size_t readStream(char *buffer, size_t requestLength);
158  size_t readContentStream(char *buffer, size_t requestLength);
159  size_t readFirstContentLine(char *buffer, size_t requestLength);
160  std::string getMimeType(std::string extension);
161  std::string getStatusText(int32_t code);
162  std::set<std::shared_ptr<FormData>> decodeMultipartFormdata();
163  std::set<std::shared_ptr<FormData>> decodeMultipartMixed(std::string &boundary, char *buffer, size_t bufferSize, char **pos);
164  static void constructHeader(uint32_t contentLength, std::string contentType, int32_t code, std::string codeDescription, const std::vector<std::string> &additionalHeaders, std::string &header);
172  static std::string stripHeader(const std::string &header, const std::unordered_set<std::string> &fieldsToStrip, const std::string &fieldsToAdd);
173  PVariable serialize();
174  void unserialize(PVariable data);
175  private:
176  bool _contentLengthSet = false;
177  bool _headerProcessingStarted = false;
178  bool _dataProcessingStarted = false;
179  bool _crlf = true;
180  Header _header;
181  std::vector<char> _rawHeader;
182  Type::Enum _type = Type::Enum::none;
183  std::vector<char> _content;
184  std::vector<char> _chunk;
185  bool _chunkNewLineMissing = false;
186  bool _finished = false;
187  int32_t _chunkSize = -1;
188  int32_t _endChunkSizeBytes = -1;
189  std::string _partialChunkSize;
190  size_t _streamPos = 0;
191  size_t _contentStreamPos = 0;
192  static const std::map<std::string, std::string> _extMimeTypeMap;
193  static const std::map<int32_t, std::string> _statusCodeMap;
194  std::string _redirectUrl;
195  std::string _redirectQueryString;
196  int32_t _redirectStatus = -1;
197  size_t _maxHeaderSize = 102400;
198  size_t _maxContentSize = 104857600;
199 
200  int32_t processHeader(char **buffer, int32_t &bufferLength);
201  void processHeaderField(char *name, uint32_t nameSize, char *value, uint32_t valueSize);
202  int32_t processContent(char *buffer, int32_t bufferLength);
203  int32_t processChunkedContent(char *buffer, int32_t bufferLength);
204  void readChunkSize(char **buffer, int32_t &bufferLength);
205 
206  char *findNextString(std::string &needle, char *buffer, size_t bufferSize);
207 
208  int32_t strnaicmp(char const *a, char const *b, uint32_t size);
209 };
210 }
211 #endif
std::string contentDisposition
Definition: Http.h:102
int32_t getRedirectStatus()
Definition: Http.h:122
std::string name
Definition: Http.h:103
std::set< std::shared_ptr< FormData > > multipartMixed
Definition: Http.h:109
std::string filename
Definition: Http.h:104
void setMaxHeaderSize(size_t value)
Definition: Http.h:125
void setRedirectQueryString(std::string value)
Definition: Http.h:121
std::string contentType
Definition: Http.h:87
size_t getMaxHeaderSize()
Definition: Http.h:124
std::string pathInfo
Definition: Http.h:84
Enum
Definition: Http.h:63
std::string getRedirectUrl()
Definition: Http.h:118
Enum
Definition: Http.h:75
Type::Enum getType()
Definition: Http.h:115
Definition: BaseLib.cpp:34
bool headerIsFinished()
Definition: Http.h:116
Definition: Http.h:74
std::string remoteAddress
Definition: Http.h:96
Enum
Definition: Http.h:66
Definition: Http.h:68
std::string args
Definition: Http.h:85
bool isFinished()
Definition: Http.h:117
void setRedirectStatus(int32_t value)
Definition: Http.h:123
std::string contentTypeFull
Definition: Http.h:106
PVariable value
Definition: UiElements.h:217
int32_t responseCode() const
Definition: Http.h:54
std::shared_ptr< Variable > PVariable
Definition: PhysicalInterfaceSettings.h:41
std::string host
Definition: Http.h:86
Definition: Http.h:47
Enum
Definition: Http.h:72
bool dataProcessingStarted()
Definition: Http.h:154
std::unordered_map< std::string, std::string > header
Definition: Http.h:107
std::string contentTypeFull
Definition: Http.h:88
std::shared_ptr< std::vector< char > > data
Definition: Http.h:108
uint32_t getContentSize() const
Definition: Http.h:138
Definition: Http.h:59
void setRedirectUrl(std::string value)
Definition: Http.h:119
Definition: Http.h:57
std::string contentType
Definition: Http.h:105
Definition: Http.h:62
Definition: Http.h:101
std::string method
Definition: Http.h:79
bool headerProcessingStarted()
Definition: Http.h:153
const std::vector< char > & getContent() const
Definition: Http.h:137
Definition: Http.h:75
Definition: Http.h:65
std::string authorization
Definition: Http.h:93
std::map< std::string, std::string > fields
Definition: Http.h:98
HttpException(std::string message, int32_t responseCode)
Definition: Http.h:52
std::string getRedirectQueryString()
Definition: Http.h:120
Header & getHeader()
Definition: Http.h:139
std::string cookie
Definition: Http.h:94
Enum
Definition: Http.h:60
std::unordered_map< std::string, std::string > cookies
Definition: Http.h:95
std::string name
Definition: UiElements.h:216
Definition: Http.h:77
Base class for all exceptions defined in Homegear.
Definition: Exception.h:41
HttpException(std::string message)
Definition: Http.h:51
std::string path
Definition: Http.h:83
void setMaxContentSize(size_t value)
Definition: Http.h:127
const std::vector< char > & getRawHeader() const
Definition: Http.h:136
Definition: Http.h:71
size_t getMaxContentSize()
Definition: Http.h:126
Enum
Definition: Http.h:69