-1

For a project we are trying to monitor a status protocol sent on local network over TCP and post these status messages over HTTPS to a InfluxDB instance on AWS at https://www.influxdata.com/products/influxdb-cloud/.

We are using a teensy 4.1 with a ethernet kit in combination with the Native Ethernet library by vjmuzik https://github.com/vjmuzik/NativeEthernet.

Posting a string to a test instance over LAN to a IP works fine, but whenever we try to post to the AWS subdomain we are greeted with this response:

HTTP/1.1 400 Bad Request
Server: awselb/2.0
Date: Mon, 27 Sep 2021 18:13:02 GMT
Content-Type: text/html
Content-Length: 122
Connection: close

<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
</body>
</html>

Since we verified the headers and body of the post are correct when we post locally, and posting to AWS works when using Postman, we are at a loss at the moment. Unfortunately I have no information about the configuration of the server we try to POST to.

We have tried:

  • Using different ethernet libraries, at the moment we are using NativeEthernet from vjmuzik https://github.com/vjmuzik/NativeEthernet
  • Different sets of headers
  • Adding google dns in ethernet.begin()
  • Post over http followed by a post over https after following the redirect response generated by the plain html request
  • Adding certificates
  • Verifying the InfluxDB line protocol with postman

As a test we set-up the WebClientRepeatingTLS example using our own POST headers and body.

#include <NativeEthernet.h>

uint8_t mac[6];
void teensyMAC(uint8_t *mac) {
  for (uint8_t by = 0; by < 2; by++) mac[by] = (HW_OCOTP_MAC1 >> ((1 - by) * 8)) & 0xFF;
  for (uint8_t by = 0; by < 4; by++) mac[by + 2] = (HW_OCOTP_MAC0 >> ((3 - by) * 8)) & 0xFF;
  Serial.printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}

// initialize the library instance:
EthernetClient client;
const int port = 443;

char server[] = "influxdata.com";  

//IPAddress server(192, 168, 1, 246);

String outputMSG = "measurementName,tagKey=tagValue fieldKey=1i";
unsigned long lastConnectionTime = 0;           // last time you connected to the server, in milliseconds
const unsigned long postingInterval = 5 * 1000; // delay between updates, in milliseconds

void setup() {
  teensyMAC(mac);
  Serial.begin(9600);
  while (!Serial) {
    ; 
  }

  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    if (Ethernet.hardwareStatus() == EthernetNoHardware) {
      Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
      while (true) {
        delay(1);
      }
    }
    if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }
  } else {
    Serial.print("  DHCP assigned IP ");
    Serial.println(Ethernet.localIP());
  }
  delay(1000);
}

void loop() {
  if (client.available()) {
    char c = client.read();
    Serial.write(c);
  }
  if (millis() - lastConnectionTime > postingInterval) {
    httpRequest();
  }

}

void httpRequest() {
  client.stop();
  Serial.print("Content-Length: ");
  Serial.println(outputMSG.length());
  Serial.println("");

  if (client.connect(server, port, true)) { 
    Serial.println("connecting to ");
    Serial.print(server);
    Serial.print(":");
    Serial.println(port);

        client.println("POST /api/v2/write?org=ORG_HERE&bucket=BUCKET_HERE&precision=s HTTP/1.1");
        client.println("Host: https://eu-central-1-1.aws.cloud2.influxdata.com");
        client.println("Authorization: Token <<TOKEN HERE>>");
        client.println("Content-Type: text/plain");
        client.print("Content-Length: ");
        client.println(outputMSG.length());
        client.println("Accept-Encoding: gzip, deflate, br");
        client.println("Connection: keep-alive");
        client.println();
        client.println(outputMSG);
        client.println();
        
    lastConnectionTime = millis();
  } else {
    Serial.println("connection failed");
  }
}

Could anyone help us understand why the post to aws is not going through?

Cheers, Boy

  • remove https:// from Host header – Juraj Sep 30 '21 at 15:31
  • Thanks for the response! I have tried this in the past but get the following response: HTTP/1.1 301 Moved Permanently Server: awselb/2.0 Date: Sat, 02 Oct 2021 09:54:02 GMT Content-Type: text/html Content-Length: 0 Connection: close Location: https://www.influxdata.com/api/v2/write Upon which I tried to make a new request by following the 301, unfortunately that still resulted in the original 400 bad request response. – bvanpoortvliet Oct 02 '21 at 10:00
  • the Host header should only contain the host name. the 301 is a step forward, the 400 is a step back – Juraj Oct 02 '21 at 10:14
  • I see. Would you happen to know how to proceed from that point on? – bvanpoortvliet Oct 02 '21 at 12:40
  • why is your Host field different then the host name used for connect? – Juraj Oct 02 '21 at 12:50
  • Excellent question, whenever I use eu-central-1-1.aws.cloud2.influxdata.com instead of influxdata.com I cannot connect to the server and the serial monitor would just print "connection failed". – bvanpoortvliet Oct 02 '21 at 13:26
  • did you try to put only influxdata.com into the Host header? – Juraj Oct 02 '21 at 13:28
  • No I have not, good one. I just checked it and when I use both influxdata.com as the server to connect to as well as using it as the host in the request it results in the same 301 response as before. If I use eu-central-1-1.aws.cloud2.influxdata.com as the server to connect to and influxdata.com as the host it won't connect to the server. – bvanpoortvliet Oct 02 '21 at 13:37

1 Answers1

0

Using the EthernetWebServerSSL library in combination with theQNEthernet library made it possible for the teensy to connect to the AWS subdomain and therefor allowed it to post to the Influxdb database.