31
31
httpClient::httpClient () {
32
32
_tcp = NULL ;
33
33
_tcps = NULL ;
34
+
35
+ _headerKeysCount = 0 ;
36
+ _currentHeaders = NULL ;
37
+
38
+ _returnCode = 0 ;
39
+ _size = 0 ;
34
40
}
35
41
36
42
httpClient::~httpClient () {
37
43
if (connected ()) {
38
44
_tcp->stop ();
39
45
}
40
- }
41
46
47
+ if (_currentHeaders) {
48
+ delete[] _currentHeaders;
49
+ }
50
+ _headerKeysCount = 0 ;
51
+ }
42
52
43
53
void httpClient::begin (const char *host, uint16_t port, const char * url, bool https, const char * httpsFingerprint) {
44
54
_host = host;
45
55
_port = port;
46
- _url = url;
56
+ _url = url;
47
57
_https = https;
48
58
_httpsFingerprint = httpsFingerprint;
49
59
}
@@ -63,24 +73,32 @@ bool httpClient::connected() {
63
73
return false ;
64
74
}
65
75
66
- bool httpClient::GET () {
76
+ /* *
77
+ * send a GET request
78
+ * @return http code
79
+ */
80
+ int httpClient::GET () {
67
81
68
82
bool status;
69
83
status = connect ();
70
84
if (status) {
71
85
status = sendHeader (" GET" );
72
86
}
73
87
74
- return status;
88
+ if (status) {
89
+ return handleHeaderResponse ();
90
+ }
91
+
92
+ return 0 ;
75
93
}
76
94
77
95
/* *
78
96
* sends a post request to the server
79
97
* @param payload uint8_t *
80
98
* @param size size_t
81
- * @return status
99
+ * @return http code
82
100
*/
83
- bool httpClient::POST (uint8_t * payload, size_t size) {
101
+ int httpClient::POST (uint8_t * payload, size_t size) {
84
102
85
103
bool status;
86
104
status = connect ();
@@ -93,10 +111,13 @@ bool httpClient::POST(uint8_t * payload, size_t size) {
93
111
status = _tcp->write (&payload[0 ], size);
94
112
}
95
113
96
- return status;
114
+ if (status) {
115
+ return handleHeaderResponse ();
116
+ }
117
+ return 0 ;
97
118
}
98
119
99
- bool httpClient::POST (String payload) {
120
+ int httpClient::POST (String payload) {
100
121
return POST ((uint8_t *) payload.c_str (), payload.length ());
101
122
}
102
123
@@ -131,6 +152,56 @@ void httpClient::addHeader(const String& name, const String& value, bool first)
131
152
}
132
153
}
133
154
155
+ void httpClient::collectHeaders (const char * headerKeys[], const size_t headerKeysCount) {
156
+ _headerKeysCount = headerKeysCount;
157
+ if (_currentHeaders)
158
+ delete[] _currentHeaders;
159
+ _currentHeaders = new RequestArgument[_headerKeysCount];
160
+ for (int i = 0 ; i < _headerKeysCount; i++) {
161
+ _currentHeaders[i].key = headerKeys[i];
162
+ }
163
+ }
164
+
165
+ String httpClient::header (const char * name) {
166
+ for (int i = 0 ; i < _headerKeysCount; ++i) {
167
+ if (_currentHeaders[i].key == name)
168
+ return _currentHeaders[i].value ;
169
+ }
170
+ return String ();
171
+ }
172
+
173
+ String httpClient::header (int i) {
174
+ if (i < _headerKeysCount)
175
+ return _currentHeaders[i].value ;
176
+ return String ();
177
+ }
178
+
179
+ String httpClient::headerName (int i) {
180
+ if (i < _headerKeysCount)
181
+ return _currentHeaders[i].key ;
182
+ return String ();
183
+ }
184
+
185
+ int httpClient::headers () {
186
+ return _headerKeysCount;
187
+ }
188
+
189
+ bool httpClient::hasHeader (const char * name) {
190
+ for (int i = 0 ; i < _headerKeysCount; ++i) {
191
+ if ((_currentHeaders[i].key == name) && (_currentHeaders[i].value .length () > 0 ))
192
+ return true ;
193
+ }
194
+ return false ;
195
+ }
196
+
197
+ /* *
198
+ * size of message body / payload
199
+ * @return 0 if no info or > 0 when Content-Length is set by server
200
+ */
201
+ size_t httpClient::getSize (void ) {
202
+ return _size;
203
+ }
204
+
134
205
/* *
135
206
* init TCP connection and handle ssl verify if needed
136
207
* @return true if connection is ok
@@ -151,7 +222,6 @@ bool httpClient::connect(void) {
151
222
_tcp = new WiFiClient ();
152
223
}
153
224
154
-
155
225
if (!_tcp->connect (_host.c_str (), _port)) {
156
226
DEBUG_HTTPCLIENT (" [HTTP-Client] failed connect to %s:%u.\n " , _host.c_str (), _port);
157
227
return false ;
@@ -184,12 +254,64 @@ bool httpClient::connect(void) {
184
254
* @return status
185
255
*/
186
256
bool httpClient::sendHeader (const char * type) {
257
+ if (!connected ()) {
258
+ return false ;
259
+ }
187
260
String header = String (type) + " " + _url + " HTTP/1.1\r\n "
188
261
" Host: " + _host + " \r\n "
189
262
" User-Agent: ESP8266httpClient\r\n "
190
- " Connection: close\r\n " +
191
- _Headers +
192
- " \r\n " ;
263
+ " Connection: close\r\n " + _Headers + " \r\n " ;
193
264
194
265
return _tcp->write (header.c_str (), header.length ());
195
266
}
267
+
268
+ /* *
269
+ * reads the respone from the server
270
+ * @return int http code
271
+ */
272
+ int httpClient::handleHeaderResponse () {
273
+
274
+ if (!connected ()) {
275
+ return false ;
276
+ }
277
+
278
+ while (connected ()) {
279
+ size_t len = _tcp->available ();
280
+ if (len > 0 ) {
281
+ String headerLine = _tcp->readStringUntil (' \n ' );
282
+ headerLine.trim (); // remove \r
283
+
284
+ DEBUG_HTTPCLIENT (" [HTTP][handleHeaderResponse] RX: '%s'\n " , headerLine.c_str ());
285
+
286
+ if (headerLine.startsWith (" HTTP/1." )) {
287
+ _returnCode = headerLine.substring (9 , headerLine.indexOf (' ' , 9 )).toInt ();
288
+ } else if (headerLine.indexOf (' :' )) {
289
+ String headerName = headerLine.substring (0 , headerLine.indexOf (' :' ));
290
+ String headerValue = headerLine.substring (headerLine.indexOf (' :' ) + 2 );
291
+
292
+ if (headerName.equalsIgnoreCase (" Content-Length" )) {
293
+ _size = headerValue.toInt ();
294
+ }
295
+
296
+ for (size_t i = 0 ; i < _headerKeysCount; i++) {
297
+ if (_currentHeaders[i].key == headerName) {
298
+ _currentHeaders[i].value = headerValue;
299
+ return true ;
300
+ }
301
+ }
302
+
303
+ }
304
+
305
+ if (headerLine == " " ) {
306
+ DEBUG_HTTPCLIENT (" [HTTP][handleHeaderResponse] code: '%s'\n " , String (_returnCode).c_str ());
307
+ if (_size) {
308
+ DEBUG_HTTPCLIENT (" [HTTP][handleHeaderResponse] size: '%s'\n " , String (_size).c_str ());
309
+ }
310
+ return _returnCode;
311
+ }
312
+
313
+ } else {
314
+ delay (0 );
315
+ }
316
+ }
317
+ }
0 commit comments