No response for HTTP GET request (arduino/esp8266)


#1

I am working on a small device to display arrival information for stops. So far I have been testing with my raspberry pi and python, but due to size & power I switched to the esp8266 module with arduino. I have been able to use other APIs with the code sample provided below, but don’t get a response when changing the host and URI to work with TfL.

Any help would be welcome!

/*
 *  HTTP over TLS (HTTPS) example sketch
 *
 *  This example demonstrates how to use
 *  WiFiClientSecure class to access HTTPS API.
 *  We fetch and display the status of
 *  esp8266/Arduino project continuous integration
 *  build.
 *
 *  Created by Ivan Grokhotkov, 2015.
 *  This example is in public domain.
 */

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <WiFiClient.h>
#include <ArduinoJson.h>

const char* ssid     = "VM*******";
const char* password = "v******";

const char* host = "api.tfl.gov.uk";
const int httpsPort = 80;

// Use web browser to view and copy
// SHA1 fingerprint of the certificate
const char* fingerprint = "CF 05 98 89 CA FF 8E D8 5E 5C E0 C2 E4 F7 E6 C3 C7 50 DD 5C";

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.print("connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Use WiFiClientSecure class to create TLS connection
  WiFiClient client;
  Serial.print("connecting to ");
  Serial.println(host);
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    return;
  }

//https fingerprint verification
  //if (client.verify(fingerprint, host)) {
  //  Serial.println("certificate matches");
  //} else {
  //  Serial.println("certificate doesn't match");
  //}

  String url = "/StopPoint/940GZZLUODS/Arrivals?mode=tube";
  Serial.print("requesting URL: ");
  Serial.println(url);

  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "User-Agent: BuildFailureDetectorESP8266\r\n" +
               "Connection: close\r\n\r\n");

  Serial.println("request sent");
  StaticJsonBuffer<200> jsonBuffer;
  while (client.connected()) {
    String line = client.readString();
    Serial.println("processing response...");
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
  }
  String line = client.readString();
  Serial.println("processing response...");
  JsonObject& root = jsonBuffer.parseObject(line);
  Serial.print(line);
  if (line.startsWith("{\"state\":\"success\"")) {
    Serial.println("esp8266/Arduino CI successfull!");
  } else {
    Serial.println("esp8266/Arduino CI has failed");
  }
  const char*  lineID = root["lineID"];
  Serial.println("reply was:");
  Serial.println("==========");
  Serial.println(line);
  Serial.print(lineID);
  Serial.println("==========");
  Serial.println("closing connection");
}

void loop() {
}

#2

httpsPort should be 443


#3

This is very true. However, in general the HTTPS implementation on the ESP8266 is very poor and doesn’t include all the latest protocols and such.

You might be better proxying it through your own (HTTP) server - this has a further benefit in that you can strip down the verbose TfL API JSON into something a little more suitable for such a tiny chip - They’ll eat power if you’re not careful and you want to spend as little time on WiFi/Processing as you can! (Also JSON and C aren’t necessarily the easiest of bed fellows)

The best option might be to use the ESP8266 purely for WiFi, and put it into deep sleep between uses, and then use a low powered chip such as the AT Tiny 85 to power the display or whatever you are planning to do to use this data.