@@ -298,7 +298,7 @@ int HTTPClient::POST(String payload) {
298
298
int HTTPClient::sendRequest (const char * type, uint8_t * payload, size_t size) {
299
299
// connect to server
300
300
if (!connect ()) {
301
- return HTTPC_ERROR_CONNECTION_REFUSED;
301
+ return returnError ( HTTPC_ERROR_CONNECTION_REFUSED) ;
302
302
}
303
303
304
304
if (payload && size > 0 ) {
@@ -307,18 +307,18 @@ int HTTPClient::sendRequest(const char * type, uint8_t * payload, size_t size) {
307
307
308
308
// send Header
309
309
if (!sendHeader (type)) {
310
- return HTTPC_ERROR_SEND_HEADER_FAILED;
310
+ return returnError ( HTTPC_ERROR_SEND_HEADER_FAILED) ;
311
311
}
312
312
313
313
// send Payload if needed
314
314
if (payload && size > 0 ) {
315
315
if (_tcp->write (&payload[0 ], size) != size) {
316
- return HTTPC_ERROR_SEND_PAYLOAD_FAILED;
316
+ return returnError ( HTTPC_ERROR_SEND_PAYLOAD_FAILED) ;
317
317
}
318
318
}
319
319
320
320
// handle Server Response (Header)
321
- return handleHeaderResponse ();
321
+ return returnError ( handleHeaderResponse () );
322
322
}
323
323
324
324
/* *
@@ -348,7 +348,7 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) {
348
348
return HTTPC_ERROR_SEND_HEADER_FAILED;
349
349
}
350
350
351
- size_t buff_size = HTTP_TCP_BUFFER_SIZE;
351
+ int buff_size = HTTP_TCP_BUFFER_SIZE;
352
352
353
353
int len = size;
354
354
int bytesWritten = 0 ;
@@ -371,7 +371,7 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) {
371
371
while (connected () && (stream->available () > -1 ) && (len > 0 || len == -1 )) {
372
372
373
373
// get available data size
374
- size_t s = stream->available ();
374
+ int s = stream->available ();
375
375
376
376
if (len) {
377
377
s = ((s > len) ? len : s);
@@ -461,11 +461,11 @@ WiFiClient * HTTPClient::getStreamPtr(void) {
461
461
int HTTPClient::writeToStream (Stream * stream) {
462
462
463
463
if (!stream) {
464
- return HTTPC_ERROR_NO_STREAM;
464
+ return returnError ( HTTPC_ERROR_NO_STREAM) ;
465
465
}
466
466
467
467
if (!connected ()) {
468
- return HTTPC_ERROR_NOT_CONNECTED;
468
+ return returnError ( HTTPC_ERROR_NOT_CONNECTED) ;
469
469
}
470
470
471
471
// get length of document (is -1 when Server sends no Content-Length header)
@@ -474,28 +474,56 @@ int HTTPClient::writeToStream(Stream * stream) {
474
474
475
475
if (_transferEncoding == HTTPC_TE_IDENTITY) {
476
476
ret = writeToStreamDataBlock (stream, len);
477
+
478
+ // have we an error?
479
+ if (ret < 0 ) {
480
+ return returnError (ret);
481
+ }
477
482
} else if (_transferEncoding == HTTPC_TE_CHUNKED) {
483
+ int size = 0 ;
478
484
while (1 ) {
485
+ if (!connected ()) {
486
+ return returnError (HTTPC_ERROR_CONNECTION_LOST);
487
+ }
479
488
String chunkHeader = _tcp->readStringUntil (' \n ' );
489
+
490
+ if (chunkHeader.length () <= 0 ) {
491
+ return returnError (HTTPC_ERROR_READ_TIMEOUT);
492
+ }
493
+
480
494
chunkHeader.trim (); // remove \r
481
495
482
496
// read size of chunk
483
497
len = (uint32_t ) strtol ((const char *) chunkHeader.c_str (), NULL , 16 );
498
+ size += len;
484
499
DEBUG_HTTPCLIENT (" [HTTP-Client] read chunk len: %d\n " , len);
500
+
501
+ // data left?
485
502
if (len > 0 ) {
486
503
int r = writeToStreamDataBlock (stream, len);
487
504
if (r < 0 ) {
488
505
// error in writeToStreamDataBlock
489
- return r ;
506
+ return returnError (r) ;
490
507
}
491
508
ret += r;
492
509
} else {
510
+
511
+ // if no length Header use global chunk size
512
+ if (_size <= 0 ) {
513
+ _size = size;
514
+ }
515
+
516
+ // check if we have write all data out
517
+ if (ret != _size) {
518
+ return returnError (HTTPC_ERROR_STREAM_WRITE);
519
+ }
493
520
break ;
494
521
}
522
+
495
523
delay (0 );
496
524
}
497
525
} else {
498
- return HTTPC_ERROR_ENCODING;
526
+ return returnError ( HTTPC_ERROR_ENCODING) ;
499
527
}
500
528
501
529
end ();
@@ -546,6 +574,10 @@ String HTTPClient::errorToString(int error) {
546
574
return String (" too less ram" );
547
575
case HTTPC_ERROR_ENCODING:
548
576
return String (" Transfer-Encoding not supported" );
577
+ case HTTPC_ERROR_STREAM_WRITE:
578
+ return String (" Stream write error" );
579
+ case HTTPC_ERROR_READ_TIMEOUT:
580
+ return String (" read Timeout" );
549
581
default :
550
582
return String ();
551
583
}
@@ -829,23 +861,50 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) {
829
861
}
830
862
831
863
// read data
832
- int c = _tcp->readBytes (buff, readBytes);
864
+ int bytesRead = _tcp->readBytes (buff, readBytes);
833
865
834
866
// write it to Stream
835
- int w = stream->write (buff, c);
836
- bytesWritten += w;
837
- if (w != c) {
838
- DEBUG_HTTPCLIENT (" [HTTP-Client][writeToStreamDataBlock] short write asked for %d but got %d\n " , c, w);
839
- break ;
867
+ int bytesWrite = stream->write (buff, bytesRead);
868
+ bytesWritten += bytesWrite;
869
+
870
+ // are all Bytes a writen to stream ?
871
+ if (bytesWrite != bytesRead) {
872
+ DEBUG_HTTPCLIENT (" [HTTP-Client][writeToStream] short write asked for %d but got %d retry...\n " , bytesRead, bytesWrite);
873
+
874
+ // check for write error
875
+ if (stream->getWriteError ()) {
876
+ DEBUG_HTTPCLIENT (" [HTTP-Client][writeToStreamDataBlock] stream write error %d\n " , stream->getWriteError ());
877
+
878
+ // reset write error for retry
879
+ stream->clearWriteError ();
880
+ }
881
+
882
+ // some time for the stream
883
+ delay (1 );
884
+
885
+ int leftBytes = (readBytes - bytesWrite);
886
+
887
+ // retry to send the missed bytes
888
+ bytesWrite = stream->write ((buff + bytesWrite), leftBytes);
889
+ bytesWritten += bytesWrite;
890
+
891
+ if (bytesWrite != leftBytes) {
892
+ // failed again
893
+ DEBUG_HTTPCLIENT (" [HTTP-Client][writeToStream] short write asked for %d but got %d failed.\n " , leftBytes, bytesWrite);
894
+ free (buff);
895
+ return HTTPC_ERROR_STREAM_WRITE;
896
+ }
840
897
}
841
898
899
+ // check for write error
842
900
if (stream->getWriteError ()) {
843
901
DEBUG_HTTPCLIENT (" [HTTP-Client][writeToStreamDataBlock] stream write error %d\n " , stream->getWriteError ());
844
- break ;
902
+ return HTTPC_ERROR_STREAM_WRITE ;
845
903
}
846
904
905
+ // count bytes to read left
847
906
if (len > 0 ) {
848
- len -= c ;
907
+ len -= readBytes ;
849
908
}
850
909
851
910
delay (0 );
@@ -869,3 +928,19 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) {
869
928
870
929
return bytesWritten;
871
930
}
931
+
932
+ /* *
933
+ * called to handle error return, may disconnect the connection if still exists
934
+ * @param error
935
+ * @return error
936
+ */
937
+ int HTTPClient::returnError (int error) {
938
+ if (error < 0 ) {
939
+ DEBUG_HTTPCLIENT (" [HTTP-Client][returnError] error(%d): %s\n " , error, errorToString (error).c_str ());
940
+ if (connected ()) {
941
+ DEBUG_HTTPCLIENT (" [HTTP-Client][returnError] tcp stop\n " );
942
+ _tcp->stop ();
943
+ }
944
+ }
945
+ return error;
946
+ }
0 commit comments