Status Code 400 responses after posting successfully for a long time

Moderators: adafruit_support_bill, adafruit

Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.
Locked
User avatar
EMichel
 
Posts: 6
Joined: Tue Sep 12, 2017 2:48 pm

Status Code 400 responses after posting successfully for a long time

Post by EMichel »

After posting data to my feed using REST API requests for a long time, on December 14 2022 I began receiving Status Code 400 responses (Bad Request). I am using a Feather MO board with ATWINC1500, and appear to be connecting to io.adafruit.com. I have not changed my code. I note that the SSL certificates were updated last August. My ATWINC SSL certificates were updated in 2019. Do I need to update to the latest? Are there any other changes made to io.adafruit.com that may be causing this failure to post?

User avatar
mikeysklar
 
Posts: 13936
Joined: Mon Aug 01, 2016 8:10 pm

Re: Status Code 400 responses after posting successfully for a long time

Post by mikeysklar »

It could be the SSL certificates or AIO Keys have expired. I don't see any upgrade notifications. Can you update both certificates and keys?

https://learn.adafruit.com/welcome-to-a ... aq-3009755
I'm using an Feather M0 WiFi (ATWINC1500) and it's not connecting to Adafruit IO.

If you're using a Feather M0 WiFi and receiving a Disconnected from Adafruit IO message in your serial monitor, you'll want to check two things:

Make sure that you have the correct Adafruit IO Keys in your sketch, and that the router/network configuration is correct. 
The SSL ceritifcates on your device for Adafruit IO need to be up-to-date. It's hard to check if they're up-to-date from the device, so we suggest running through the process of adding a new SSL certificate through the Arduino IDE. You can find the guide for that here.

User avatar
EMichel
 
Posts: 6
Joined: Tue Sep 12, 2017 2:48 pm

Re: Status Code 400 responses after posting successfully for a long time

Post by EMichel »

Thank you for your reply. It seems I am getting connected to io.adafruit.com. Following is the Serial Monitor printout of a typical session. This suggests the problem is not the SSL Certificate in my ATWIN1500.

Got packet from #2
[RSSI :-26] :
16%20C2023-01-11T15:03:15Z3.99V
16
68.00
2023-01-11T15:03:15Z3.99V

Attempting to connect to SSID: redacted
Connected to WiFi
IP Address: 192.168.1.112


Starting connection to server...
Connected to server // Response to this code snippet:
if (wifisslClient.connect(AIO_SERVER, AIO_SERVERPORT)) {
Serial.println("Connected to server");
Indicates connection to io.adafruit.com successful.


Post data and retrieve responses

{ "value" : "16" } // JSON data sent
/api/v2/EMichel/feeds/redacted/data // path for post
Status Code: 400 // Response from io.adafruit.com

Trying to POST...
{ "value" : "16" }
/api/v2/EMichel/feeds/redacted/data
Status Code: 400

Trying to POST...
{ "value" : "16" }
/api/v2/EMichel/feeds/redacted/data
Status Code: 400

Trying to POST...
{ "value" : "16" }
/api/v2/EMichel/feeds/redacted/data
Status Code: 400

Trying to POST...
POSTING failed, three tries...

The code I use (REST API) has been connecting successfully for some time, until Dec 14, 2022.

User avatar
jwcooper
 
Posts: 1004
Joined: Tue May 01, 2012 9:08 pm

Re: Status Code 400 responses after posting successfully for a long time

Post by jwcooper »

I think step #1 is to get the ssl certs updated. Without the proper certs, it's hard to tell what could be causing the issues.

Steps for updating the certs are here:
https://learn.adafruit.com/adafruit-win ... rtificates

If it continues to fail after updating certs, please post your code (with secrets removed) so we can help diagnose the issue.

User avatar
EMichel
 
Posts: 6
Joined: Tue Sep 12, 2017 2:48 pm

Re: Status Code 400 responses after posting successfully for a long time

Post by EMichel »

Thanks for the suggestions. The Feather MO SSL certificates, Arduino IDE Feather MO board, and WiFi101 were updated, but I still get the Status Code 400 noted in the above posting. Below are relevant code snippets that are producing this result, whereas in the past they have worked as indicated:

Code: Select all

 //Code Snippets from Soil Moisture Sensor using Feather MO WiFi//
 
 ********************************************************************************/
#include <ArduinoHttpClient.h>
#include <WiFi101.h>
#include <SPI.h>
#include <PString.h>
#include <RH_RF69.h>
#include <RHReliableDatagram.h>

/************** Adafruit IO Set Up **********************************************/
// URL endpoints for Adafruit API and connection info
  const char pathHedgeSoilMoisture[] = "/api/v2/EMichel/feeds/redacted/data";
  const char pathCircuitBoardTempf[] = "/api/v2/EMichel/feeds/redacted/data";
  const char AIO_SERVER[] = "io.adafruit.com";  // server address for io.adafruit.com
  uint16_t   AIO_SERVERPORT = 443; // results in secure SSL connection to server at Adafruit///
  
  
  
  ///////   Send data to io.adafruit.com     ////////////////////
  
   Serial.print("Post data and retrieve responses");
   Serial.println();
    
   // Identify source of the radio packet, format data, send to Adafruit IO
   String postBody; // data to be sent as JSON
   bool isHSMPosted = false; // Hedge Soil Moisture post status
   bool isCBTPosted = false; // Circuit Board Temp post status
   bool moisturePosted = false;
 
   uint8_t counter = 0;

   do{ // this sets up three HTTP POST tries with same radio packet
    switch(from) {  // The server is Radio Address 1; Hedge is 2
      case 2 : // Radio 2 is hedge location, so send update for 
               // VWC, tempF 
         beginSeconds = millis();        
         do {  // Re-try for 15 seconds or success
                  
           if (!moisturePosted) {     
              postBody = assembleFeedData(VWC, dtStr); //dtStr not used now 10/30 // JSON data 
              isHSMPosted = sendHttpRequest(pathHedgeSoilMoisture,postBody); // HTTP request function
        
 ///////////////////     Functions     /////////////////////////////////////////////

bool sendHttpRequest(const char* URLPATH, String postData) {
  Serial.println(URLPATH);
  
  httpClient.beginRequest();
  httpClient.post(URLPATH); //this should yield <POST /api/v2/EMichel/feeds/redacted/data >
  httpClient.sendHeader("Host: io.adafruit.com");
  httpClient.sendHeader("Content-Type", "application/json");
  httpClient.sendHeader("Content-Length", postData.length());
  httpClient.sendHeader("x-aio-key", "redacted");
  httpClient.sendHeader("Connection: close");
  httpClient.sendHeader("Accept: application/json; charset=utf-8");
  httpClient.sendHeader("Accept: text/html");
  httpClient.sendHeader("Accept-Encoding: identity");
  httpClient.sendHeader("Accept-language: en-us");
  
  httpClient.beginBody();
  httpClient.print(postData);
  httpClient.endRequest();

  // check response code for success
      statusCode = httpClient.responseStatusCode();
      if ( statusCode == 200 ) {
        Serial.print("Status Code: ");
        Serial.println(statusCode);
        response = httpClient.responseBody();
          Serial.print("Response: ");
          Serial.println(response);
      }
      else {
        Serial.print("Status Code: ");
        Serial.println(statusCode);
        statusCode = 0;
      }
  

  if (statusCode == 0){
     return false;
  }   
  else {
  return true;
  }
}

/////////////// Assemble the Body for POSTING ///////////////////////
String assembleFeedData(int dataValue, PString timeStamp) {
  
    // Assemble feed data for "value"  
      String postBodyStr = ("{ \"value\" : \"");
      postBodyStr += dataValue;
      postBodyStr += ("\" }"); // should read  { "value": "<VWC>" }
      
      Serial.println(postBodyStr);
      return postBodyStr;
The response printout by Serial Monitor:
Got packet from #2
[RSSI :-26] :
16%20C2023-01-12T16:03:15Z3.96V
16
68.00
2023-01-12T16:03:15Z3.96V
Attempting to connect to SSID: redacted
Connected to WiFi
IP Address: 192.168.1.112


Starting connection to server...
Connected to server
Post data and retrieve responses
{ "value" : "16" }
/api/v2/EMichel/feeds/hedge-soil-moisture/data
Status Code: 400
Trying to POST...
{ "value" : "16" }
/api/v2/EMichel/feeds/hedge-soil-moisture/data
Status Code: 400
Trying to POST...
{ "value" : "16" }
/api/v2/EMichel/feeds/hedge-soil-moisture/data
Status Code: 400
Trying to POST...
{ "value" : "16" }
/api/v2/EMichel/feeds/hedge-soil-moisture/data
Status Code: 400
Trying to POST...
POSTING failed, three tries...

User avatar
jwcooper
 
Posts: 1004
Joined: Tue May 01, 2012 9:08 pm

Re: Status Code 400 responses after posting successfully for a long time

Post by jwcooper »

The 400 error indicates there is something wrong with the client posting to the server (not much more to go off of than that status code, unfortunately).

Do you see anything on the monitor page when trying to post? Any errors?

https://io.adafruit.com/monitor

Could you also try logging the responseBody to the serial output when getting that 400? Might be useful to see what IO is responding, as we do include useful error messages sometimes.

User avatar
EMichel
 
Posts: 6
Joined: Tue Sep 12, 2017 2:48 pm

Re: Status Code 400 responses after posting successfully for a long time

Post by EMichel »

Thanks for these suggestions. I did monitor during the last post attempt, and the Live Monitor showed no results during the posting (I had the page open.) Below is the print out of the responseBody you suggested:

Got packet from #2
[RSSI :-26] :
16%19C2023-01-13T13:03:15Z3.94V
16
66.20
2023-01-13T13:03:15Z3.94V
Attempting to connect to SSID: redacted
Connected to WiFi
IP Address: 192.168.1.112


Starting connection to server...
Connected to server
Post data and retrieve responses
{ "value" : "16" }
/api/v2/EMichel/feeds/hedge-soil-moisture/data
Status Code: 400
Response: <html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>



Trying to POST...
POSTING failed, three tries...

User avatar
EMichel
 
Posts: 6
Joined: Tue Sep 12, 2017 2:48 pm

Re: Status Code 400 responses after posting successfully for a long time

Post by EMichel »

Do Adafruit IO keys expire? Has anything changed about the way the key may be submitted using the HTTP API in a request header? i.e. httpClient.sendHeader("x-aio-key", "(key)");

Does ArduinoHttpClient.h still comply with Adafruit IO API docs? Latest release is 0.4

Is the correct method for adding data to a feed using ArduinoHttpClient, httpClient.print(newData)?

User avatar
mikeysklar
 
Posts: 13936
Joined: Mon Aug 01, 2016 8:10 pm

Re: Status Code 400 responses after posting successfully for a long time

Post by mikeysklar »

The Adafruit keys do not expire unless you manually generate a new key.

x-aio-key works the same.

That is a good question about ArduionHttpClient being compatible. It is not a recommended library for Adafruit IO usage so you might be on to something by suspecting that the library and AIO could have a recent incompatibility.

Normally for Arduino usage the Adafruit IO Arduino Library is recommended.

https://github.com/adafruit/Adafruit_IO_Arduino

Locked
Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.

Return to “Internet of Things: Adafruit IO and Wippersnapper”