Reputation: 45
I am trying to submit an image on the web to Google Vision Face detection. Submitting the image directly on the Google Vision page:
https://cloud.google.com/vision/docs/ocr?apix_params=%7B%22resource%22%3A%7B%22requests%22%3A%5B%7B%22features%22%3A%5B%7B%22type%22%3A%22FACE_DETECTION%22%7D%5D%2C%22image%22%3A%7B%22source%22%3A%7B%22imageUri%22%3A%22http%3A%2F%2Fwww.newdesignfile.com%2Fpostpic%2F2010%2F05%2Ffree-stock-photos-people_102217.jpg%22%7D%7D%2C%22imageContext%22%3A%7B%22languageHints%22%3A%5B%22pt%22%5D%7D%7D%5D%7D%7D
works OK. Also using NodeRed on a raspberry Pi works ok. But I can not make it work with ESP32. It always responds on the console with: HTTP Response code: -5 Error code: -5
My code is as below:
/*
Rui Santos
Complete project details at Complete project details at https://RandomNerdTutorials.com/esp32-http-get-post-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "mySSID";
const char* password = "myPass";
//Your Domain name with URL path or IP address with path
const char* serverName = "https://vision.googleapis.com/v1/images:annotate?key=MyAPIKey";
String _request = "{\"requests\":[{\"image\":{\"source\":{\"imageUri\":\"http://www.newdesignfile.com/postpic/2010/05/free-stock-photos-people_102217.jpg\"}},\"features\":[{\"type\":\"FACE_DETECTION\",\"maxResults\":10}]}]}";
// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastTime = 0;
unsigned long timerDelay = 15000;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
}
void loop() {
//Send an HTTP POST request every 10 minutes
if ((millis() - lastTime) > timerDelay) {
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED){
WiFiClient client;
HTTPClient http;
// Your Domain name with URL path or IP address with path
http.begin(client, serverName);
Serial.print("Conected to Server: ");
Serial.println(serverName);
//If you need an HTTP request with a content type: application/json, use the following:
http.addHeader("Content-Type", "application/json");
Serial.print("Posting request: ");
Serial.println(_request);
int httpResponseCode = http.POST(_request);
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
String payload = "{}";
if(httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
Serial.println(payload);
}else{
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
}else {
Serial.println("WiFi Disconnected");
}
lastTime = millis();
}
}
Assistance welcome.
Upvotes: 1
Views: 179
Reputation: 7109
You're trying to load an HTTPS URL over an HTTP connection.
You'll need to use WiFiClientSecure
in order to use HTTPS - you can find examples in the HTTPClient
library.
Your code needs to look like:
WiFiClientSecure client;
HTTPClient http;
client.setCACert(rootCACertificate);
// Your Domain name with URL path or IP address with path
http.begin(client, serverName);
You'll need to find and store a copy of the root certificate authority certificate for the domain you're accessing. If it ever changes (and it will eventually expire) you'll need to update that. Generally you'd define that at the start of your file - most people unnecessarily define it as a global variable, like so:
#include <WiFi.h>
#include <HTTPClient.h>
const char* rootCACertificate = \
"-----BEGIN CERTIFICATE-----\n" \
...
"-----END CERTIFICATE-----\n";
You'd replace the ...
with the actual contents of the certificate. You can find many explanations of how to do this via a search engine or here on Stack Overflow. Make sure you write each line of it as a C string ending with \n" \
so that the lines are concatenated into a single string.
You can sidestep the need for the root CA certificate by writing your code like this:
WiFiClientSecure client;
HTTPClient http;
client.setInsecure();
// Your Domain name with URL path or IP address with path
http.begin(client, serverName);
this is fine for testing but it defeats the security that HTTPS gives you and should not be used in production or deployed code. Running it as insecure means you don't know that the server you connected to is the correct server and you don't know that the data you exchange with it (including any passwords or API keys) will actually be private from anyone trying to eavesdrop on network traffic.
Upvotes: 1