简体   繁体   中英

ESP32 HTTPS POST JSON to AWS

I'm trying to post some data to AWS over HTTPS post but seems not to reach there.

Setting host to server address and path to /prod No authentication is required yet on the method. When I connect it just gets frozen and no response, despite saying it's connected.

Also tried not to use path and set the full path to the host

Not really sure why it's happening, these are 2 ways I tried:

    void postToAmazonSecure(String jsonToSend){
  WiFiClientSecure client;
  
  Serial.print("connecting to : '");
  Serial.print(emonDataAPI);
  Serial.println("'");
  Serial.println(emonDataAPI.c_str());
  client.connect(emonDataAPI.c_str(), 443);
  
  Serial.print("requesting URL: '");
  Serial.print(emonDataAPI);
  Serial.println("'");
  String requestString = String("POST ") + emonDataAPIPath + " HTTP/1.1\r\n" +
    "Host: " + emonDataAPI + "\r\n" +
    "Connection: close\r\n" +
    "Content-Type: application/json" +
    //"Authorization: Bearer " + authorization_code + "\r\n" +
    "Content-Length: " + jsonToSend.length() + "\r\n" +
    "\r\n" +
    jsonToSend + "\r\n";
    Serial.println(requestString);
  client.print(requestString);
  
  Serial.println("request sent");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
}
}

void postSecure(String jsonToSend){
 WiFiClientSecure client;

 Serial.print("connect: "); Serial.println(emonDataAPI);
 while ( ! client.connect(emonDataAPI.c_str(), 443)) {
    Serial.print(".");
 }
 Serial.println("Connected");
 String msg = "POST " + emonDataAPIPath + " HTTP/1.1\r\n"
                "Host: " + emonDataAPI + "\r\n"
                "Content-Type: application/json\r\n"
                "Content-Length: " + jsonToSend.length() + "\r\n"
                "\r\n" + jsonToSend;
                
 client.print(msg);
 Serial.print(msg);
 
 Serial.print("\n*** Request sent, receiving response...");
 while (!!!client.available()) {
    delay(50);
 Serial.print(".");
  }
  
Serial.println();
Serial.println("Got response");  
  while(client.available()){
  Serial.write(client.read());
  }
Serial.println(); Serial.println("closing connection");
  client.stop();
}

You forgot the \r\n at the end of the Content-Type line. It should be:

"Content-Type: application/json\r\n" +

You're also not providing WiFiClientSecure with a fingerprint or certificate so that it can verify the server you're connecting to. This is also going to stop your code from working. You should provide the root certificate for the certificate chain securing the endpoint you're trying to connect to:

const char* test_root_ca= \
     "-----BEGIN CERTIFICATE-----\n" \
...
     "-----END CERTIFICATE-----\n";


...

  client.setCACert(test_root_ca);
  client.connect(emonDataAPI.c_str(), 443);

You can find a more complete example in the WiFiClientSecure library examples .

You can also check out the README for WiFiClientSecure for more detailed information.

Without the root certificate WiFiClientSecure cannot verify the identity of the server you're connecting to. Windows, Linux and macOS systems all handle this automatically; the overhead to doing this is more than the ESP32's operating environment can handle.

You can tell WiFiClientSecure not to bother verifying the server, but by doing so you're also saying "I don't really care about security". You might do this for debugging but it's an extremely poor and dangerous practice to leave it in code that's actually being used.

  client.setInsecure();
  client.connect(emonDataAPI.c_str(), 443);

These kinds of mistakes are a big part of why you're almost always better off using a library like HTTPClient than rolling your own HTTP(S) implementation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM