Open
Description
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;
}