HTTP status codes missing description in header for proxy_pass

We’re using nginx as a middle layer in front of our application server
(mod_perl). When mod_perl returns an error page, the HTTP status line
is
missing the “reason phrase” after the status code, like “Not Found”,
e.g.

HTTP/1.1 404
Server: nginx/1.2.1
…etc

should be

HTTP/1.1 404 Not Found
…etc…

AFAICT, the HTTP spec requires at least a space after the status code:


http://www.w3.org/Protocols/rfc1945/rfc1945
The first line of a Full-Response message is the Status-Line,
consisting of the protocol version followed by a numeric status code
and its associated textual phrase, with each element separated by SP
characters. No CR or LF is allowed except in the final CRLF sequence.

   Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

Since a status line always begins with the protocol version and
status code

   "HTTP/" 1*DIGIT "." 1*DIGIT SP 3DIGIT SP

(e.g., "HTTP/1.0 200 "),

   Reason-Phrase  = *<TEXT, excluding CR, LF>

The reason we noticed is that putting Perlbal in front of nginx got the
status rejected, since Perlbal is written to strictly follow the spec:


return fail(“Bogus response line”) unless
$self->{responseLine} =~
m!^HTTP/(\d+).(\d+)\s+(\d+)(?:\s+(.*))$!;

Hi,

nginx does its job correctly:

$ curl -I http://nginx.org/404
$ HTTP/1.1 404 Not Found
$ […]

I guess the irregular response comes from your mod_perl backend? Did you
check that out?

Capturing nginx’s debug output of such a request will probably help.

http://nginx.org/en/docs/debugging_log.html

Regards,
Lukas

Hello!

On Mon, Jun 03, 2013 at 07:07:50PM -0400, kgoess wrote:

HTTP/1.1 404 Not Found
…etc…

[…]

Is this a bug in nginx, or a configuration issue that we can fix? The patch
to Perlbal is simple enough, is it worth looking for a patch to nginx? Or
did we miss something else entirely?

As soon as you proxy requests to another server - nginx just
returns a status line as got from a backend as soon as it’s able
to recognize it.


Maxim D.
http://nginx.org/en/donation.html

I guess the irregular response comes from your mod_perl backend?

Aha, from ngrep listening on port 8080 responding to nginx, it is indeed
missing the description:

T 10.200.1.59:8080 → 10.200.1.59:57990 [AP]
HTTP/1.1 404…Server: Apache/2.2.16 (Debian) mod_perl/2.0.4
Perl/v5.10.1

If apache is in the middle layer, instead of nginx, it looks like apache
fills in the status line

T 127.0.0.1:8082 → 127.0.0.1:37887 [AP]
HTTP/1.1 404 Not Found…Date: Tue, 04 Jun 2013 20:02:03 GMT…Server:
Apache/2.2.16 (Debian) mod_perl/2.0.4 Perl/v5.10.1…

but if nginx is in the middle, it just passes it straight through:

T 127.0.0.1:8083 → 127.0.0.1:46829 [AP]
HTTP/1.1 404…Server: nginx/1.2.1…

And sure enough, some pretty old cgi code needed this fix

 if (! -e $file) {
   bepress::Statsd->increment('viewcontent.error.native_not_found');
  •  $self->out( $cgiutils->header( -status => 404 ) );
    
  •  $self->out( $cgiutils->header( -status => '404 Not Found' ) );
     $self->out( $cgiutils->start_html(
    

Thanks for the help!

Posted at Nginx Forum: