- Tue Aug 09, 2016 11:27 am
#52564
Hi,
Yes, if you want to connect to random.org you must use a SSL connection. Fortunately that works (now) surprisingly good and reliable. Since I did exactly the same some time ago I have a working example for you to test and build upon.
But as "rudy" also mentioned the SSL connection uses quite some memory, keep that in mind.
Here is a small summary of the FreeHeap:
After connecting to the wifi network, getFreeHeap() shows "42.248 KB".
After creating the SSL connection only "25.736 KB" is left.
Directly after receiving the server response: "25.920 KB" (This is a the end of the setup() function)
After entering the loop() the free heap goes instantly up again to about "42.128 KB".
And here is the Arduino sketch: (For a first test only the ssid and password must be configured)
Code: Select all/*
* random.org SSL example
* JohSka, 17. Apr 2016
*
* What it does:
* Connects to the wifi network and waits for a IP from the DHCP
* Connects to random.org using a SSL connection
* Requests this URL: /integers/?num=1&min=1&max=6&col=1&base=10&format=plain&rnd=new
* Prints the server response
*
* Configuration:
* For a first test only the ssid and password must be set
*
* How to get the SHA1 fingerprint of the certificate: (using a web browser)
* 1. Open a browser and navigate to the website you want to connect to
* 2. Open the "Page Info" window (using Strg + i or the context menu or...) and navigate to the Security tab
* 3. Click on "View Certificate" and copy the SHA1 Fingerprint
* 4. If the fingerprint has colons (:) in it replace them with spaces!
*
* random.org API infos:
* API Guidelines, IMPORTANT!: https://www.random.org/clients/
* HTTP Interface Description: https://www.random.org/clients/http/
*/
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
// WIFI Config
const char* ssid = "xxxxx";
const char* password = "xxxxx";
// random.org API URL
const char* request_url = "/integers/?num=1&min=1&max=6&col=1&base=10&format=plain&rnd=new";
// random.org recommends to supply your email address in the User-Agent field
// so they can send you a email if your client is causing trouble instead of just banning your IP.
const char* user_agent = "your@emailaddress.com";
// SSL / Host Config
const char* host = "www.random.org";
const int httpsPort = 443;
// SHA1 fingerprint of the random.org SSL certificate (Note: This may change!)
const char* fingerprint = "EC 1B 71 CC 42 EB 65 E9 01 60 83 1E 14 19 21 3E A7 1C 75 ED";
// Debug remaining memory
void printHeap() {
Serial.printf(" Free heap: %i\n", ESP.getFreeHeap());
}
// SETUP
void setup()
{
Serial.begin(115200);
Serial.println("");
// WIFI config
WiFi.mode(WIFI_STA);
// Connect to the ap
Serial.print("Connecting to the wifi network...");
WiFi.begin(ssid, password);
// Wait for a IP
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
// Wifi connectetd
Serial.println(" WiFi connected");
Serial.print(" IP address: ");
Serial.println(WiFi.localIP());
printHeap();
// Connect to random.org
Serial.print("\nConnecting to ");
Serial.println(host);
// Create the SSL connection
WiFiClientSecure client;
if (!client.connect(host, httpsPort)) {
Serial.println(" Connection failed");
return;
}
// Verify the certificate
if (client.verify(fingerprint, host)) {
Serial.println(" Done. Certificate matches");
}
else {
Serial.println(" FAIL. certificate doesn't match");
}
printHeap();
// Send the GET request
Serial.print("Requesting URL: ");
Serial.println(request_url);
client.print(String("GET ") + request_url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"User-Agent: " + host + "\r\n" +
"Connection: close\r\n\r\n");
Serial.println(" Done.\n");
// Handle client timeout
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
// If got a response print the server headers
Serial.println("Server headers:");
while (client.connected()) {
String line = client.readStringUntil('\n');
Serial.println(line);
if (line == "\r") {
Serial.println("End of headers");
break;
}
}
// Print the server message
Serial.println("\nServer message: (Random number)");
while (client.available()) {
String line = client.readStringUntil('\n');
Serial.println(line);
}
Serial.println("End of message");
printHeap();
Serial.println("");
}
void loop() {
printHeap();
delay(2000);
}
The Serial Monitor will show something like this:
Code: Select allConnecting to the wifi network........
WiFi connected
IP address: 192.168.1.37
Free heap: 42248
Connecting to www.random.org
Done. Certificate matches
Free heap: 25736
Requesting URL: /integers/?num=1&min=1&max=6&col=1&base=10&format=plain&rnd=new
Done.
Server headers:
HTTP/1.1 200 OK
Date: Tue, 09 Aug 2016 11:28:16 GMT
Content-Type: text/plain;charset=utf-8
Transfer-Encoding: chunked
Connection: close
Set-Cookie: __cfduid=d7e9f9de1133af27be28add4c83ec67b91470749295; expires=Wed, 09-Aug-17 13:28:15 GMT; path=/; domain=.random.org; HttpOnly
X-Powered-By: PHP/5.4.45-0+deb7u4
Set-Cookie: RDOSESSION=221c9qg24ij4amcnah7cir6732; path=/; domain=.random.org
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
RDO-Authenticated-Login: -
Access-Control-Allow-Origin: *
Vary: Accept-Encoding
Server: cloudflare-nginx
CF-RAY: 2cfb8cdb519c3934-VIE
End of headers
Server message: (Random number)
2
5
End of message
Free heap: 25920
Free heap: 42128
Free heap: 42128
...
Two other things i noticed:
The fingerprint of the certificate has changed since I first tried this.
The response from random.org always contains two numbers and the first one is always a 2. I have no idea where the 2 is comming from. The actual random number is the second one.
PS: Thanks for the interessting link rudy. But at least on "www.random.org" and "www.googleapis.com" this HTTPSRedirect class is not needed. You have to use the right link though. ("random.org" or "gooogleapis.com" without the "www" doesn't work or they will return "301 Moved permanently" or "404 Not Found" resp. )