@@ -41,6 +41,8 @@ httpClient::httpClient() {
4141 _reuse = false ;
4242 _https = false ;
4343
44+ _userAgent = " ESP8266httpClient" ;
45+
4446 _headerKeysCount = 0 ;
4547 _currentHeaders = NULL ;
4648
@@ -77,7 +79,7 @@ httpClient::~httpClient() {
7779 * @param httpsFingerprint const char *
7880 */
7981void httpClient::begin (const char *url, const char * httpsFingerprint) {
80- begin (String (url), String (httpsFingerprint));
82+ begin (String (url), String (httpsFingerprint));
8183}
8284
8385/* *
@@ -111,7 +113,7 @@ void httpClient::begin(String url, String httpsFingerprint) {
111113 _host = url.substring (0 , index); // hostname
112114 url.remove (0 , (index + 1 )); // remove hostname + :
113115
114- index = url.indexOf (' /' );
116+ index = url.indexOf (' /' );
115117 _port = url.substring (0 , index).toInt (); // get port
116118 url.remove (0 , index); // remove port
117119 hasPort = true ;
@@ -200,7 +202,6 @@ bool httpClient::connected() {
200202 return false ;
201203}
202204
203-
204205/* *
205206 * try to reuse the connection to the server
206207 * keep-alive
@@ -210,6 +211,14 @@ void httpClient::setReuse(bool reuse) {
210211 _reuse = reuse;
211212}
212213
214+ /* *
215+ * set User Agent
216+ * @param userAgent const char *
217+ */
218+ void httpClient::setUserAgent (const char * userAgent) {
219+ _userAgent = userAgent;
220+ }
221+
213222/* *
214223 * send a GET request
215224 * @return http code
@@ -240,7 +249,7 @@ int httpClient::POST(String payload) {
240249 * @return -1 if no info or > 0 when Content-Length is set by server
241250 */
242251int httpClient::sendRequest (const char * type, uint8_t * payload, size_t size) {
243- // connect ro server
252+ // connect to server
244253 if (!connect ()) {
245254 return HTTPC_ERROR_CONNECTION_REFUSED;
246255 }
@@ -265,6 +274,77 @@ int httpClient::sendRequest(const char * type, uint8_t * payload, size_t size) {
265274 return handleHeaderResponse ();
266275}
267276
277+ /* *
278+ * sendRequest
279+ * @param type const char * "GET", "POST", ....
280+ * @param stream Stream * data stream for the message body
281+ * @param size size_t size for the message body if 0 not Content-Length is send
282+ * @return -1 if no info or > 0 when Content-Length is set by server
283+ */
284+ int httpClient::sendRequest (const char * type, Stream * stream, size_t size) {
285+
286+ if (!stream) {
287+ return HTTPC_ERROR_NO_STREAM;
288+ }
289+
290+ // connect to server
291+ if (!connect ()) {
292+ return HTTPC_ERROR_CONNECTION_REFUSED;
293+ }
294+
295+ if (size > 0 ) {
296+ addHeader (" Content-Length" , String (size));
297+ }
298+
299+ // send Header
300+ if (!sendHeader (type)) {
301+ return HTTPC_ERROR_SEND_HEADER_FAILED;
302+ }
303+
304+ // create buffer for read
305+ uint8_t buff[1460 ] = { 0 };
306+
307+ int len = size;
308+ int bytesWritten = 0 ;
309+
310+ if (len == 0 ) {
311+ len = -1 ;
312+ }
313+
314+ // read all data from stream and send it to server
315+ while (connected () && stream->available () && (len > 0 || len == -1 )) {
316+
317+ // get available data size
318+ size_t s = stream->available ();
319+
320+ if (s) {
321+ int c = stream->readBytes (buff, ((s > sizeof (buff)) ? sizeof (buff) : s));
322+
323+ // write it to Stream
324+ bytesWritten += _tcp->write ((const uint8_t *)buff, c);
325+
326+ if (len > 0 ) {
327+ len -= c;
328+ }
329+
330+ delay (0 );
331+ } else {
332+ delay (1 );
333+ }
334+ }
335+
336+ if (size && (int )size != bytesWritten) {
337+ DEBUG_HTTPCLIENT (" [HTTP-Client][sendRequest] Stream payload bytesWritten %d and size %d mismatch!.\n " , bytesWritten, _size);
338+ DEBUG_HTTPCLIENT (" [HTTP-Client][sendRequest] ERROR SEND PAYLOAD FAILED!" );
339+ return HTTPC_ERROR_SEND_PAYLOAD_FAILED;
340+ } else {
341+ DEBUG_HTTPCLIENT (" [HTTP-Client][sendRequest] Stream payload written: %d\n " , bytesWritten);
342+ }
343+
344+ // handle Server Response (Header)
345+ return handleHeaderResponse ();
346+ }
347+
268348/* *
269349 * size of message body / payload
270350 * @return -1 if no info or > 0 when Content-Length is set by server
@@ -374,7 +454,6 @@ String httpClient::getString(void) {
374454 return sstring;
375455}
376456
377-
378457/* *
379458 * adds Header to the request
380459 * @param name
@@ -383,16 +462,20 @@ String httpClient::getString(void) {
383462 */
384463void httpClient::addHeader (const String& name, const String& value, bool first) {
385464
386- String headerLine = name;
387- headerLine += " : " ;
388- headerLine += value;
389- headerLine += " \r\n " ;
465+ // not allow set of Header handled by code
466+ if (!name.equalsIgnoreCase (" Connection" ) && !name.equalsIgnoreCase (" User-Agent" ) && !name.equalsIgnoreCase (" Host" )) {
467+ String headerLine = name;
468+ headerLine += " : " ;
469+ headerLine += value;
470+ headerLine += " \r\n " ;
390471
391- if (first) {
392- _Headers = headerLine + _Headers;
393- } else {
394- _Headers += headerLine;
472+ if (first) {
473+ _Headers = headerLine + _Headers;
474+ } else {
475+ _Headers += headerLine;
476+ }
395477 }
478+
396479}
397480
398481void httpClient::collectHeaders (const char * headerKeys[], const size_t headerKeysCount) {
@@ -448,7 +531,6 @@ bool httpClient::connect(void) {
448531 return true ;
449532 }
450533
451-
452534 if (_https) {
453535 DEBUG_HTTPCLIENT (" [HTTP-Client] connect https...\n " );
454536 if (_tcps) {
@@ -502,9 +584,10 @@ bool httpClient::sendHeader(const char * type) {
502584 if (!connected ()) {
503585 return false ;
504586 }
587+
505588 String header = String (type) + " " + _url + " HTTP/1.1\r\n "
506589 " Host: " + _host + " \r\n "
507- " User-Agent: ESP8266httpClient \r\n "
590+ " User-Agent: " + _userAgent + " \r\n "
508591 " Connection: " ;
509592
510593 if (_reuse) {
0 commit comments