arduino-libraries / ArduinoHttpClient

Arduino HTTP Client library
287 stars 172 forks source link

Can't send complex POST request with begin/endRequest #178

Open kaysond opened 2 months ago

kaysond commented 2 months ago

My code looks roughly like:

char json_string[512];
int length = mylib.sprint_json(json_string);
Serial.println("Sending JSON:");
Serial.println(json_string);
Serial.print("Length: ");
Serial.println(length);

client.beginRequest();
client.post("/");
client.sendHeader("Host", "my.hostname.tld");
client.sendHeader("Content-Type", "application/json");
client.sendHeader("Content-Length", length);
client.beginBody();
client.print(json_string);
client.endRequest();
int statusCode = client.responseStatusCode();
String response = client.responseBody();

mylib.sprint_json is essentially an sprintf() wrapper.

This doesn't work. The request never goes out.

If I change the post request to:

client.post("/", "application/json", json_string);

it works just fine.

Am I doing something wrong? I copied the example. From the Serial.println()s, I can see that the string and length are correct...

jonasbarsten commented 1 month ago

Did some testing and it seems complex POST requests only work with json strings shorter than 504 characters.

jonasbarsten commented 1 month ago

I solved it like this for now:

  String input = "suuuuuuuper-loooooooooooooooong-striiiiiiiiiiiing";
  const size_t contentLength = input.length();

  client.beginRequest();
  client.post(path);
  client.sendHeader("Content-Type", "application/json");
  client.sendHeader("Content-Length", contentLength);
  client.beginBody();

  constexpr size_t chunkSize = 64;

  for (size_t i = 0; i < contentLength; i = i + chunkSize) {
    if (contentLength - i < chunkSize) {
      String chunk = input.substring(i);
      client.print(chunk);
    } else {
      String chunk = input.substring(i, chunkSize + i);
      client.print(chunk);
    }
  }

  client.endRequest();