Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Do not send a chunked body for HEAD requests #87

Merged
merged 1 commit into from

2 participants

@therigu

The HTTP 1.1 spec states

The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response

If a Plack app does not set a body or a Content-Length for a response to a HEAD request (which I believe is correct), Starman currently enables chunked encoding and sends the chunked 'footer' in the body of the response. I believe this contradicts the spec (as above) and causes problems with my (nodejs) client.

Server.pm already disables chunked responses for status codes without a body (204 and 304) - this patch does the same for HEAD requests.

The test fails without the patch to the .pm, it has to use the low level IO::Socket::INET so we get the body before the chunked decoding is applied

@miyagawa miyagawa merged commit c27699c into from
@therigu therigu deleted the branch
@therigu

Ah, I've just realised I committed with the wrong email address. I have updated the branch, would you be willing to pull that instead? I realise that would require a forced update, so if you're not willing I understand.

@miyagawa
Owner

Yeah i wouldn't do forced update lightly. Sorry about that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 14, 2013
  1. @therigu

    Do not send a chunked body for HEAD requests

    Adam Guthrie authored therigu committed
This page is out of date. Refresh to see the latest.
Showing with 49 additions and 1 deletion.
  1. +1 −1  lib/Starman/Server.pm
  2. +48 −0 t/no_chunked_head.t
View
2  lib/Starman/Server.pm
@@ -473,7 +473,7 @@ sub _finalize_response {
if ( $protocol eq 'HTTP/1.1' ) {
if ( !exists $headers{'content-length'} ) {
- if ( $status !~ /^1\d\d|[23]04$/ ) {
+ if ( $status !~ /^1\d\d|[23]04$/ && $env->{REQUEST_METHOD} ne 'HEAD' ) {
DEBUG && warn "[$$] Using chunked transfer-encoding to send unknown length body\n";
push @headers, 'Transfer-Encoding: chunked';
$chunked = 1;
View
48 t/no_chunked_head.t
@@ -0,0 +1,48 @@
+use strict;
+use Test::TCP;
+use IO::Socket::INET;
+use HTTP::Request;
+use HTTP::Response;
+use Plack::Loader;
+use Test::More;
+
+$ENV{PLACK_SERVER} = 'Starman';
+
+test_tcp(
+ client => sub {
+ my $port = shift;
+
+ my $socket = IO::Socket::INET->new(
+ PeerAddr => 'localhost',
+ PeerPort => $port,
+ Proto => 'tcp'
+ ) or die "Failed to connect to server: $!";
+
+ my $request = HTTP::Request->new(
+ HEAD => '/', [ Host => 'localhost' ]
+ );
+ $request->protocol('HTTP/1.1');
+
+ $socket->send($request->as_string("\r\n"));
+ $socket->shutdown(1);
+
+ my $data;
+ while ($socket->connected) {
+ my $buf;
+ $socket->recv($buf, 1024);
+ $data .= $buf;
+ }
+
+ my $res = HTTP::Response->parse($data);
+
+ is $res->content, '';
+ },
+ server => sub {
+ my $port = shift;
+ my $server = Plack::Loader->auto(port => $port, host => '127.0.0.1');
+
+ $server->run(sub { return [ 200, [], [] ] });
+ }
+);
+
+done_testing;
Something went wrong with that request. Please try again.