Skip to content

Getting HTTP 400 Bad Request from Google Cloud Run as of March 2023 #150

Open
@sosandstrom

Description

@sosandstrom

As of a few days ago, the following code is getting HTTP 400 Bad Request from Google Cloud Run, where it used to get proper HTTP 200 OK:

            httpClient.beginRequest();
            httpClient.post(_cloudPostPath);
            httpClient.sendHeader(HTTP_HEADER_CONTENT_LENGTH, strlen(_cloudRequestBody));
            httpClient.sendHeader(HTTP_HEADER_CONTENT_TYPE, ApplicationJson);
            httpClient.sendHeader("Host", cloudHost);
            sprintf(value, "%s/%s", CurrentlyOne, VERSION);
            httpClient.sendHeader(HTTP_HEADER_USER_AGENT, value);
            httpClient.endRequest();
            httpClient.print(_cloudRequestBody);
            memset(_cloudRequestBody, 0, RESPONSE_BUF_SIZE);
            status = httpClient.responseStatusCode();
            LOG("HTTP %d", status);

The HttpClient is backed by a WiFiClientSecure on an ESP32C3 module.

If I instead use a custom (incomplete fwiw) implementation of the HttpClient, it starts working again:

#if(CORE_DEBUG_LEVEL>=4)
#define ENABLE_LOG4ARDUINO
#endif
#include <log4arduino.h>
#include <Arduino.h>
#include <WiFiClientSecure.h>

#include "http_client.h"

HttpClient::HttpClient(WiFiClientSecure& aClient, const char* aServerName, uint16_t aServerPort) {
    client = &aClient;
    host = aServerName;
    port = aServerPort;
    statusCode = -1;
    responseContentLength = -1;
    memset(responseData, 0, RESPONSE_BUF_SIZE);
}

void HttpClient::beginRequest() {
    client->connect(host, port);
    statusCode = -1;
    responseContentLength = -1;
    memset(responseData, 0, RESPONSE_BUF_SIZE);
}

int HttpClient::get(const char* aURLPath) {
    char buf[RESPONSE_BUF_SIZE];
    sprintf(buf, "GET %s HTTP/1.1\r\n", aURLPath);
    return print(buf);
}

int HttpClient::post(const char* aURLPath) {
    char buf[RESPONSE_BUF_SIZE];
    sprintf(buf, "POST %s HTTP/1.1\r\n", aURLPath);
    return print(buf);
}

void HttpClient::sendHeader(const char* aHeaderName, const char* aHeaderValue) {
    char buf[RESPONSE_BUF_SIZE];
    sprintf(buf, "%s: %s\r\n", aHeaderName, aHeaderValue);
    print(buf);
}

void HttpClient::sendHeader(const char* aHeaderName, const int aHeaderValue) {
    char buf[RESPONSE_BUF_SIZE];
    sprintf(buf, "%s: %d\r\n", aHeaderName, aHeaderValue);
    print(buf);
}

void HttpClient::endRequest() {
    print(HTTP_CRLF);
}

int HttpClient::print(const char *data) {
    LOGS(data);
    return client->print(data);
}

int HttpClient::responseStatusCode() {
    if (-1 == statusCode) {
        char buf[RESPONSE_BUF_SIZE], statusMessage[128];
        memset(statusMessage, 0, 128);

        readLine(buf, RESPONSE_BUF_SIZE);
        LOGS(buf);
        sscanf(buf, "HTTP/1.1 %d %s", &statusCode, statusMessage);
    }
    return statusCode;
}

int HttpClient::contentLength() {
    return responseContentLength;
}

const char * HttpClient::responseBody() {
    if (-1 == responseContentLength) {
        char buf[RESPONSE_BUF_SIZE];

        // read headers:
        readLine(buf, RESPONSE_BUF_SIZE);
        while (0 < strlen(buf) && strcmp(buf, HTTP_CRLF)) {
            LOG(buf);
            if (strstr(buf, HTTP_HEADER_CONTENT_LENGTH) || strstr(buf, "content-length")) {
                sscanf(&buf[strlen(HTTP_HEADER_CONTENT_LENGTH)], ": %d", &responseContentLength);
            }
            readLine(buf, RESPONSE_BUF_SIZE);
        }

        // read body
        client->read((uint8_t *)responseData, RESPONSE_BUF_SIZE);
        if (responseContentLength != strlen(responseData)) {
            LOG("content length mismatch, header=%d, read=%d", responseContentLength, strlen(responseData));
            responseContentLength = strlen(responseData);
        }
    }
    return responseData;
}

void HttpClient::stop() {
    client->stop();
}

int HttpClient::readLine(char *buf, int size) {
    const uint32_t ms = millis();
    int pos = 0, ch = 0;
    memset(buf, 0, size);

    while (0x0A != ch && 0 <= ch) {
        while (!client->available() && millis() < ms + 30000) {
            delay(10);
        }
        ch = client->read();
        if (pos < size-1) {
            buf[pos] = ch;
        }
        pos++;
    }
    return pos;
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: imperfectionPerceived defect in any part of project

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Getting HTTP 400 Bad Request from Google Cloud Run as of March 2023 · Issue #150 · arduino-libraries/ArduinoHttpClient