csquared / arduino-restclient

Arduino RESTful HTTP Request Library
MIT License
206 stars 134 forks source link

Status code of response randomly zero #19

Open adadgio opened 7 years ago

adadgio commented 7 years ago

I'm using node red to log simple data values from arduino send with this library.

Everything works but the status code of the response is sometime 200, but most of the time randomly 0 with an empty response. The NodeRed workflow works (its only an hTTP in and http out nodes

String response = "";
  int statusCode = client.post("/api/garden", data, &response);
  Serial.println(statusCode); // sometimes 200, often zero..
  Serial.println(response); // sometime "ok", often empty

Note: i do get my values right at every request in nodered debug node. So the request is properly made...

When i make ONE post request the debug shows:

HTTP: connect
HTTP: connected
REQUEST: 
POST /api/garden HTTP/1.1
Host: 37.139.14.78
Connection: close
Content-Length: 17
Content-Type: application/x-www-form-urlencoded

soil_humidity=719

HTTP: call readResponse
HTTP: NON-NULL RESPONSE POINTER: 
HTTP: RESPONSE: 
HTTP: return readResponse3
HTTP: return readResponse
HTTP: stop client
HTTP: client stopped
0
adadgio commented 7 years ago

I get it. I see in the code that youa re using a delay(100)when reading the response... But my server most of the time responds withing less than 100ms (50 or so...). In this case the response is not parsed.

When i delay my response by at least 100ms, i get a proper parsed response every time ! Could this maybe be fixed in a near future ? (I could'nt do it, i'm not sharp enough in C++)... ;-)

rodrigosalinas commented 6 years ago

I'm having the same issue. I really need to get the response so my Arduino proceed to do other things depending on the response. But most of the time I'm getting an empty response. Please help.

pho-enix commented 6 years ago

Hi @rodrigosalinas I had the same problem.

I fixed it by using the flush() of the client used in RestClient.cpp. This will only wait until the data of the write buffer has been written out.

Tommy-LSA commented 6 years ago

I have the same Problem in ESP8266 fork of this code. I have commented out the delay. With delay(100) 90% of all POST queries return statuscode 0 on ESP8266 with an node Express as server. By commenting out this line I was able to reduce the statuscode 0 responses to ~10%. My client works fire&forget, so it's not critical but it is not really clean.

Tommy-LSA commented 6 years ago

@pho-enix could you provide us with a code snipped for the flush() approach? Im not that C nerd.

pho-enix commented 6 years ago

@Tommy-LSA you simple call the flush on the correct client:

diff --git a/Arduino/libraries/ESP8266RestClient/RestClient.cpp b/Arduino/libraries/ESP8266RestClient/RestClient.cpp
index 4363fd8..a13c4de 100644
--- a/Arduino/libraries/ESP8266RestClient/RestClient.cpp
+++ b/Arduino/libraries/ESP8266RestClient/RestClient.cpp
@@ -133,6 +133,14 @@ void RestClient::write(const char* string){
   }
 }

+void RestClient::flush(){
+  if(use_https) {
+    client_s->flush();
+  } else {
+    client->flush();
+  }
+}
+
 void RestClient::setHeader(const char* header){
   headers[num_headers] = header;
   num_headers++;
@@ -207,7 +215,7 @@ int RestClient::request(const char* method, const char* path,
   }

   //make sure you write all those bytes.
-  delay(100);
+  flush();

   HTTP_DEBUG_PRINT("HTTP: call readResponse\n");
   int statusCode = readResponse(response);
diff --git a/Arduino/libraries/ESP8266RestClient/RestClient.h b/Arduino/libraries/ESP8266RestClient/RestClient.h
index 772716a..703f6b1 100644
--- a/Arduino/libraries/ESP8266RestClient/RestClient.h
+++ b/Arduino/libraries/ESP8266RestClient/RestClient.h
@@ -51,6 +51,7 @@ class RestClient {
     WiFiClientSecure *client_s;
     int readResponse(String*);
     void write(const char*);
+    void flush();
     const char* host;
     int port;
     int num_headers;
Tommy-LSA commented 6 years ago

@pho-enix , unfortunately it doesn't build for ESP8266 fork `error: base operand of '->' has non-pointer type 'WiFiClient'

 client->flush();

       ^`
pho-enix commented 6 years ago

@Tommy-LSA indeed. In C you use -> to reference the fields or functions of a pointer *. Whereas you use . to reference the fields or functions of a non-pointer (a struct in out case).

Please try client.flush();

raffobaffo commented 2 years ago

@pho-enix Great, I just came across this and still helped me after 2+ years. Maybe would be good to have it as a PR?