@@ -298,7 +298,7 @@ int HTTPClient::POST(String payload) {
298298int HTTPClient::sendRequest (const char * type, uint8_t * payload, size_t size) {
299299 // connect to server
300300 if (!connect ()) {
301- return HTTPC_ERROR_CONNECTION_REFUSED;
301+ return returnError ( HTTPC_ERROR_CONNECTION_REFUSED) ;
302302 }
303303
304304 if (payload && size > 0 ) {
@@ -307,18 +307,18 @@ int HTTPClient::sendRequest(const char * type, uint8_t * payload, size_t size) {
307307
308308 // send Header
309309 if (!sendHeader (type)) {
310- return HTTPC_ERROR_SEND_HEADER_FAILED;
310+ return returnError ( HTTPC_ERROR_SEND_HEADER_FAILED) ;
311311 }
312312
313313 // send Payload if needed
314314 if (payload && size > 0 ) {
315315 if (_tcp->write (&payload[0 ], size) != size) {
316- return HTTPC_ERROR_SEND_PAYLOAD_FAILED;
316+ return returnError ( HTTPC_ERROR_SEND_PAYLOAD_FAILED) ;
317317 }
318318 }
319319
320320 // handle Server Response (Header)
321- return handleHeaderResponse ();
321+ return returnError ( handleHeaderResponse () );
322322}
323323
324324/* *
@@ -348,7 +348,7 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) {
348348 return HTTPC_ERROR_SEND_HEADER_FAILED;
349349 }
350350
351- size_t buff_size = HTTP_TCP_BUFFER_SIZE;
351+ int buff_size = HTTP_TCP_BUFFER_SIZE;
352352
353353 int len = size;
354354 int bytesWritten = 0 ;
@@ -371,7 +371,7 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) {
371371 while (connected () && (stream->available () > -1 ) && (len > 0 || len == -1 )) {
372372
373373 // get available data size
374- size_t s = stream->available ();
374+ int s = stream->available ();
375375
376376 if (len) {
377377 s = ((s > len) ? len : s);
@@ -461,11 +461,11 @@ WiFiClient * HTTPClient::getStreamPtr(void) {
461461int HTTPClient::writeToStream (Stream * stream) {
462462
463463 if (!stream) {
464- return HTTPC_ERROR_NO_STREAM;
464+ return returnError ( HTTPC_ERROR_NO_STREAM) ;
465465 }
466466
467467 if (!connected ()) {
468- return HTTPC_ERROR_NOT_CONNECTED;
468+ return returnError ( HTTPC_ERROR_NOT_CONNECTED) ;
469469 }
470470
471471 // get length of document (is -1 when Server sends no Content-Length header)
@@ -474,28 +474,56 @@ int HTTPClient::writeToStream(Stream * stream) {
474474
475475 if (_transferEncoding == HTTPC_TE_IDENTITY) {
476476 ret = writeToStreamDataBlock (stream, len);
477+
478+ // have we an error?
479+ if (ret < 0 ) {
480+ return returnError (ret);
481+ }
477482 } else if (_transferEncoding == HTTPC_TE_CHUNKED) {
483+ int size = 0 ;
478484 while (1 ) {
485+ if (!connected ()) {
486+ return returnError (HTTPC_ERROR_CONNECTION_LOST);
487+ }
479488 String chunkHeader = _tcp->readStringUntil (' \n ' );
489+
490+ if (chunkHeader.length () <= 0 ) {
491+ return returnError (HTTPC_ERROR_READ_TIMEOUT);
492+ }
493+
480494 chunkHeader.trim (); // remove \r
481495
482496 // read size of chunk
483497 len = (uint32_t ) strtol ((const char *) chunkHeader.c_str (), NULL , 16 );
498+ size += len;
484499 DEBUG_HTTPCLIENT (" [HTTP-Client] read chunk len: %d\n " , len);
500+
501+ // data left?
485502 if (len > 0 ) {
486503 int r = writeToStreamDataBlock (stream, len);
487504 if (r < 0 ) {
488505 // error in writeToStreamDataBlock
489- return r ;
506+ return returnError (r) ;
490507 }
491508 ret += r;
492509 } 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+ }
493520 break ;
494521 }
522+
495523 delay (0 );
496524 }
497525 } else {
498- return HTTPC_ERROR_ENCODING;
526+ return returnError ( HTTPC_ERROR_ENCODING) ;
499527 }
500528
501529 end ();
@@ -546,6 +574,10 @@ String HTTPClient::errorToString(int error) {
546574 return String (" too less ram" );
547575 case HTTPC_ERROR_ENCODING:
548576 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" );
549581 default :
550582 return String ();
551583 }
@@ -829,23 +861,50 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) {
829861 }
830862
831863 // read data
832- int c = _tcp->readBytes (buff, readBytes);
864+ int bytesRead = _tcp->readBytes (buff, readBytes);
833865
834866 // 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+ }
840897 }
841898
899+ // check for write error
842900 if (stream->getWriteError ()) {
843901 DEBUG_HTTPCLIENT (" [HTTP-Client][writeToStreamDataBlock] stream write error %d\n " , stream->getWriteError ());
844- break ;
902+ return HTTPC_ERROR_STREAM_WRITE ;
845903 }
846904
905+ // count bytes to read left
847906 if (len > 0 ) {
848- len -= c ;
907+ len -= readBytes ;
849908 }
850909
851910 delay (0 );
@@ -869,3 +928,19 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) {
869928
870929 return bytesWritten;
871930}
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