Custom page for 400 (Bad Request)

Igor Sysoev igor at sysoev.ru
Wed Dec 15 16:38:29 MSK 2010


On Wed, Dec 15, 2010 at 03:09:14PM +0300, Igor Sysoev wrote:

> On Wed, Dec 15, 2010 at 01:57:58PM +0200, Eugaia wrote:
> 
> > Hi,
> > 
> > On 15/12/2010 13:50, Igor Sysoev wrote:
> > > Yes, mention of "cookie" is useful here, since this is the main cause
> > > of these errors. "Header line or cookie too big". I use "line"
> > > because nginx has another couse of 400 error: large header.
> > > "Header line is too long" is logged when a single line of client header
> > > is bigger than a buffer in large_client_header_buffers.
> > > "Header is too large" is logged when sum of all header lines are bigger
> > > than client_header_buffer_size plus large_client_header_buffers.
> > Is this for a single header, all the headers or either?
> 
> I have looked in the sources.
> "client sent too large request" is logged if all request headers can not
> be read in client_header_buffer_size plus large_client_header_buffers.
> "client sent too long header line: "...." is logged if a single header line
> does not fit in a buffer of large_client_header_buffers.
> 
> > It might be 
> > useful to have 'Headers too large' if more than a single header is 
> > included in the calculation.
> > > Probably this reason should cause 494 error too. And the resulting
> > > message should be as you have suggested: "Request header or cookie too big".
> > Sounds good to me.
> 
> The current edition is "Request header or cookie too large".
> 
> > It might also be useful to specify 'Cookie too large' in the log file, 
> > if it is the cookie that is too large.
> 
> The header line name and about 1800 value charecters are logged.

New patch verision.


-- 
Igor Sysoev
http://sysoev.ru/en/
-------------- next part --------------
Index: src/http/ngx_http_request.h
===================================================================
--- src/http/ngx_http_request.h	(revision 3164)
+++ src/http/ngx_http_request.h	(working copy)
@@ -95,8 +95,10 @@
 /* The special code to close connection without any response */
 #define NGX_HTTP_CLOSE                     444
 
-#define NGX_HTTP_OWN_CODES                 495
+#define NGX_HTTP_NGINX_CODES               494
 
+#define NGX_HTTP_REQUEST_HEADER_TOO_LARGE  494
+
 #define NGX_HTTPS_CERT_ERROR               495
 #define NGX_HTTPS_NO_CERT                  496
 
Index: src/http/ngx_http_special_response.c
===================================================================
--- src/http/ngx_http_special_response.c	(revision 3164)
+++ src/http/ngx_http_special_response.c	(working copy)
@@ -201,6 +201,16 @@
 ;
 
 
+static char ngx_http_error_494_page[] =
+"<html>" CRLF
+"<head><title>400 Request Header Or Cookie Too Large</title></head>"
+CRLF
+"<body bgcolor=\"white\">" CRLF
+"<center><h1>400 Bad Request</h1></center>" CRLF
+"<center>Request Header Or Cookie Too Large</center>" CRLF
+;
+
+
 static char ngx_http_error_495_page[] =
 "<html>" CRLF
 "<head><title>400 The SSL certificate error</title></head>"
@@ -315,6 +325,7 @@
 #define NGX_HTTP_LAST_LEVEL_400  417
 #define NGX_HTTP_LEVEL_400       (NGX_HTTP_LAST_LEVEL_400 - 400)
 
+    ngx_string(ngx_http_error_494_page), /* 494, request header too large */
     ngx_string(ngx_http_error_495_page), /* 495, https certificate error */
     ngx_string(ngx_http_error_496_page), /* 496, https no certificate */
     ngx_string(ngx_http_error_497_page), /* 497, http to https */
@@ -429,17 +440,18 @@
         err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_LEVEL_200
                                            + NGX_HTTP_LEVEL_300;
 
-    } else if (error >= NGX_HTTP_OWN_CODES
+    } else if (error >= NGX_HTTP_NGINX_CODES
                && error < NGX_HTTP_LAST_LEVEL_500)
     {
         /* 49X, 5XX */
-        err = error - NGX_HTTP_OWN_CODES + NGX_HTTP_LEVEL_200
-                                         + NGX_HTTP_LEVEL_300
-                                         + NGX_HTTP_LEVEL_400;
+        err = error - NGX_HTTP_NGINX_CODES + NGX_HTTP_LEVEL_200
+                                           + NGX_HTTP_LEVEL_300
+                                           + NGX_HTTP_LEVEL_400;
         switch (error) {
             case NGX_HTTP_TO_HTTPS:
             case NGX_HTTPS_CERT_ERROR:
             case NGX_HTTPS_NO_CERT:
+            case NGX_HTTP_REQUEST_HEADER_TOO_LARGE:
                 r->err_status = NGX_HTTP_BAD_REQUEST;
                 break;
         }
Index: src/http/ngx_http_request.c
===================================================================
--- src/http/ngx_http_request.c	(revision 3165)
+++ src/http/ngx_http_request.c	(working copy)
@@ -978,10 +978,13 @@
                 if (rv == NGX_DECLINED) {
                     p = r->header_name_start;
 
+                    r->lingering_close = 1;
+
                     if (p == NULL) {
                         ngx_log_error(NGX_LOG_INFO, c->log, 0,
                                       "client sent too large request");
-                        ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+                        ngx_http_finalize_request(r,
+                                            NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
                         return;
                     }
 
@@ -995,7 +998,9 @@
                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
                                   "client sent too long header line: \"%*s\"",
                                   len, r->header_name_start);
-                    ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+
+                    ngx_http_finalize_request(r,
+                                            NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
                     return;
                 }
             }


More information about the nginx mailing list