I'm using the Arduino Wifi Nina Library to connect an Arduino Uno Wifi Rev2 to wifi and then using the Arduino HTTP Client library to make HTTP post calls to the internet. It is working. However when I switch from HTTP to HTTPs (ie: switching the port to 443 from 80) the code below fails. I understand This is because I don't have a cert on the Arduino. I need to purchase/obtain a cert and download it to the Arduino.
I need to find a solution to this problem that meets the following constraints I have:
- I will only be sending https requests to one URL: https://api.mailgun.net
- The amount of memory storage available on Arduinos is severely constrained
- I plan to deploy this Arduino into the field. After I deploy it, I will no longer be able to physically access it to manually update any expired certificates. But the Arduino unit must be able to send HTTPs requests to https://api.mailgun.net in perpetuity.
- I plan to deploy not just this Arduino unit, but a fleet of similarly functioning Arduino units with the same functionality. And I need to keep the costs of any certificate(s) to an absolute minimum.
#include <WiFiNINA.h>
#include <ArduinoHttpClient.h>
#define REMOTE_SERVER_DOMAIN "api.mailgun.net"
#define REMOTE_SERVER_PORT 443
#define MAILGUN_USER "my-user"
#define MAILGUN_PASSWORD "my-secret"
bool sendEmailViaHTTPS()
{
WiFiClient wifiClient;
HttpClient httpClient = HttpClient(wifiClient, REMOTE_SERVER_DOMAIN, REMOTE_SERVER_PORT);
httpClient.beginRequest();
httpClient.post("/v3/sandbox7d1aaf2f157f42d8844b1ac4c38a0ef7.mailgun.org/messages");
httpClient.sendHeader("Content-Type", "application/x-www-form-urlencoded");
httpClient.sendBasicAuth(MAILGUN_USER, MAILGUN_PASSWORD);
String postData = String("from=Mailgun%20Sandbox%20%3Cpostmaster%40sandbox7d1aaf2f157f42d8844b1ac4c38a0ef7.mailgun.org%3E&to=Me%20%3Cmyemail%40gmail.com%3E&subject=Hello%20World1&text=Hello%20World2");
httpClient.sendHeader("Content-Length", postData.length());
httpClient.beginBody();
httpClient.print(postData);
httpClient.endRequest();
int statusCode = httpClient.responseStatusCode();
String response = httpClient.responseBody();
Serial.print("Status code: ");
Serial.println(statusCode);
Serial.print("Response: ");
Serial.println(response);
return statusCode == 200;
}
What is the best solution to enabling my Arduino to send HTTPs requests as stated above with the least cost and friction?