dlang-requests icon indicating copy to clipboard operation
dlang-requests copied to clipboard

No automatic Content-Length on POST

Open zorael opened this issue 6 months ago • 6 comments

EndeavourOS/Arch x86_64, requests v2.1.3.

When sending a POST with a body, a Content-Length header is not automatically added, even when posting a string (which is not chunked and has a known length).

import std;
import requests;

void main()
{
    auto res = postContent("http://httpbin.org/post", "Hello, World!");
    writeln(res);
}
{
  "args": {}, 
  "data": "Hello, World!", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept-Encoding": "gzip,deflate", 
    "Content-Type": "application/octet-stream", 
    "Host": "httpbin.org", 
    "Transfer-Encoding": "chunked", 
    "User-Agent": "dlang-requests", 
    "X-Amzn-Trace-Id": "Root=1-65b758d9-61bde2ce4c6309560ebd0cc7"
  }, 
  "json": null, 
  "origin": "194.117.188.126", 
  "url": "http://httpbin.org/post"
}

This is not a problem with httpbin.org, but some services do require the header. An example is batsign.me, with which you can mail small reports to yourself by sending a quick POST to a custom URL.

import std;
import requests;

void main()
{
    auto res = postContent("https://batsign.me/at/[email protected]/asdfasdf", "Warning: server is down");
    writeln(res);
}
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>411 Length Required</title>
</head><body>
<h1>Length Required</h1>
<p>A request of the requested method POST requires a valid Content-length.<br />
</p>
<hr>
<address>Apache/2.4.38 (Debian) Server at batsign.me Port 443</address>
</body></html>

It can be worked around by using Request.post instead of postContent and manually adding the header.

import std;
import requests;

void main()
{
    enum body_ = "Warning: server is down";
    auto rq = Request();
    rq.addHeaders([ "Content-Length": body_.length.to!string ]);
    auto res = rq.post("https://batsign.me/at/[email protected]/asdfasdf", body_);
    writeln(cast(string)res.responseBody);
}

Looking through the examples in the readme, it seems like the length is properly calculated and added if you use multi-part forms? (I didn't test and verify)

But it doesn't for simple strings at least. Is this intended behaviour?

zorael avatar Jan 29 '24 15:01 zorael