libwww-perl / libwww-perl/HTTP-Message
`request_type_with_data` sets `Content-Type: application/x-www-form-urlencoded` even when no body is provided
Nobody has claimed this yet.
- Dominant language
- Perl
- Stars
- 32
- Forks
- 63
- Avg merge
- 5h 14m
- Merged PRs (30d)
- 1
Description
Description
request_type_with_data (used by POST, PUT, PATCH, and OPTIONS) unconditionally sets a Content-Type header to application/x-www-form-urlencoded even when no body content is supplied.
In lib/HTTP/Request/Common.pm:
sub request_type_with_data {
my $type = shift;
my $url = shift;
my $req = HTTP::Request->new($type => $url);
my $content;
$content = shift if @_ and ref $_[0];
my($k, $v);
while (($k,$v) = splice(@_, 0, 2)) {
if (lc($k) eq 'content') {
$content = $v;
}
else {
$req->push_header($k, $v);
}
}
my $ct = $req->header('Content-Type');
unless ($ct) {
$ct = 'application/x-www-form-urlencoded'; # default
}
elsif ($ct eq 'form-data') {
$ct = 'multipart/form-data';
}
# ... content encoding ...
$req->header('Content-Type' => $ct); # always set
if (defined($content)) {
$req->header('Content-Length' =>
length($content)) unless ref($content);
$req->content($content);
}
else {
$req->header('Content-Length' => 0);
}
$req;
}
Content-Type is resolved before checking whether $content is defined, and the assignment at the end is unconditional.
Impact
For HTTP methods that commonly have no body (e.g. OPTIONS without a body), a caller doing:
use HTTP::Request::Common;
my $req = OPTIONS 'http://example.com';
receives a request with:
Content-Type: application/x-www-form-urlencodedContent-Length: 0
Neither header is meaningful for a bodyless OPTIONS request.
Suggested fix
Move the Content-Type assignment inside the if (defined($content)) block so it only applies when there is actual content to describe:
if (defined($content)) {
$req->header('Content-Type' => $ct);
$req->header('Content-Length' =>
length($content)) unless ref($content);
$req->content($content);
}
else {
$req->header('Content-Length' => 0);
}
This would make request_type_with_data consistent with _simple_req (used by GET, HEAD, DELETE), which does not set Content-Type at all.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read lib/HTTP/Request/Common.pm, focusing on request_type_with_data and the _simple_req behavior described in the issue. Use the bodyless OPTIONS example to verify that Content-Type is not set without content, while requests with content still receive the resolved type and Content-Length remains handled as described.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- perl
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100