Esp32 error 400 upload spiffs wav file to web server using http post

An aside about examining binary data

When dealing with binary data, use something like hexdump, which should be installed on Linux or Mac

$ hexdump -C test_8u_16.wav | head -n 4
00000000  52 49 46 46 84 64 00 00  57 41 56 45 66 6d 74 20  |RIFF.d..WAVEfmt |
00000010  12 00 00 00 01 00 01 00  80 3e 00 00 80 3e 00 00  |.........>...>..|
00000020  01 00 08 00 00 00 64 61  74 61 cd 3f 00 00 80 80  |......data.?....|
00000030  80 80 80 80 80 7f 7e 80  7e 80 7e 7e 7e 7f 7d 7f  |......~.~.~~~.}.|

I found that file in the ESP8266Audio library I happen to have installed. Looking at the (little-endian) size after "RIFF", 0x6484 is 8 less than the size of the file, 25740 bytes, as expected. The size of the "fmt " chunk happens to be 0x12 bytes instead of your 0x10; the "data" starts in the expected place accordingly, that many bytes after the four-byte size.

The file fragment you posted has some binary-to-text conversion: for one thing looks like all the 00 are presented as spaces (hex 20)

00000000  52 49 46 46 24 71 02 20  57 41 56 45 66 6d 74 20  |RIFF$q. WAVEfmt |
00000010  10 20 20 20 01 20 01 20  e2 82 ac 3e 20 20 20 7d  |.   . . ...>   }|
00000020  01 c3 bf 02 20 10 20 64  61 74 61 20 71 02 20 20  |.... . data q.  |

And looking at the text here in the forum, there is the sign at offset 24, which has 0x80 in the wavHeader function. But that's the appropriate character only on Windows; in any case, the UTF-8 encoding for it is that "e2 82 ac", as shown just above. So brute-force reversing this -- unfortunately changing any legitimate 20 to 00 (like at the end of "fmt ")

$ pbpaste | tr ' ' '\000' | iconv -f utf-8 -t windows-1252 | hexdump -C
00000000  52 49 46 46 24 71 02 00  57 41 56 45 66 6d 74 00  |RIFF$q..WAVEfmt.|
00000010  10 00 00 00 01 00 01 00  80 3e 00 00 00 7d 01 ff  |.........>...}..|
00000020  02 00 10 00 64 61 74 61  00 71 02 00 00 03 00 ff  |....data.q......|

For whatever reason, after "7d 01", at offset 31 should be "00" but is instead 0xFF. I don't know enough about the .wav format to say whether that is significant.

Anyway, the particulars of how the binary data got mangled don't matter if you can avoid it in the first place :slight_smile: The "RIFF" size is 0x027124, or 160036. That's a lot closer to 160884, but still off by eight hundred bytes, more than all the extra stuff that is added. But not nearly as bad as 32812.

Back to the main problem

To troubleshoot this, verify the size/length at each step; e.g. did concatenating the body actually work? And you don't actually have to set the Content-Length manually when sending a String, HTTPClient will do it for you.

So for example

  int contentLength = body.length();
  Serial.println(contentLength);  // did the concat work?
  int httpResponseCode = client.sendRequest("POST", body );

Unfortunately, that doesn't tell you about the next step: how many bytes were actually sent. If you use a Stream, HTTPClient will print a debug message with that info. ESP32 actually has a StreamString that combines the two (HTTPClient uses it). You'll need

#include <StreamString.h>

and then change the body initialization slightly

  StreamString body;
  body += "--" + boundary + "\r\n";

Unlike with a String, for a Stream, the sendRequest takes a pointer; and because it's a stream, you need to pass the length, otherwise it won't set the Content-Length

  int contentLength = body.length();
  Serial.println(contentLength);  // did the concat work?
  int httpResponseCode = client.sendRequest("POST", &body, contentLength);

With Debug messages enabled, the output will be something like

[  2134][D][HTTPClient.cpp:812] sendRequest(): Stream payload written: 161000
[  3063][D][HTTPClient.cpp:1257] handleHeaderResponse(): code: 200

(I made up that 161000.) Does it match the contentLength, or the 33KB?