diff src/http/ngx_http_request.c @ 10:46833bd150cb NGINX_0_1_5

nginx 0.1.5 *) Bugfix: on Solaris and Linux there may be too many "recvmsg() returned not enough data" alerts. *) Bugfix: there were the "writev() failed (22: Invalid argument)" errors on Solaris in proxy mode without sendfile. On other platforms that do not support sendfile at all the process got caught in an endless loop. *) Bugfix: segmentation fault on Solaris in proxy mode and using sendfile. *) Bugfix: segmentation fault on Solaris. *) Bugfix: on-line upgrade did not work on Linux. *) Bugfix: the ngx_http_autoindex_module module did not escape the spaces, the quotes, and the percent signs in the directory listing. *) Change: the decrease of the copy operations. *) Feature: the userid_p3p directive.
author Igor Sysoev <http://sysoev.ru>
date Thu, 11 Nov 2004 00:00:00 +0300
parents 80ba094c6b3e
children 6f8b0dc0f8dd
line wrap: on
line diff
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -34,24 +34,22 @@ static void ngx_http_lingering_close_han
 
 static void ngx_http_client_error(ngx_http_request_t *r,
                                   int client_error, int error);
-static size_t ngx_http_log_error(void *data, char *buf, size_t len);
+static u_char *ngx_http_log_error(void *data, u_char *buf, size_t len);
 
 
 /* NGX_HTTP_PARSE_... errors */
 
 static char *client_header_errors[] = {
-    "client %s sent invalid method",
-    "client %s sent invalid request",
-    "client %s sent too long URI",
-    "client %s sent invalid method in HTTP/0.9 request",
-
-    "client %s sent invalid header, URL: %s",
-    "client %s sent too long header line, URL: %s",
-    "client %s sent HTTP/1.1 request without \"Host\" header, URL: %s",
-    "client %s sent invalid \"Content-Length\" header, URL: %s",
-    "client %s sent POST method without \"Content-Length\" header, URL: %s",
-    "client %s sent plain HTTP request to HTTPS port, URL: %s",
-    "client %s sent invalid \"Host\" header \"%s\", URL: %s"
+    "client %V sent invalid method \"%V\"",
+    "client %V sent invalid request \"%V\"",
+    "client %V sent too long URI in request \"%V\"",
+    "client %V sent invalid method in HTTP/0.9 request \"%V\"",
+
+    "client %V sent invalid header, URL: \"%V\"",
+    "client %V sent too long header line, URL: \"%V\"",
+    "client %V sent HTTP/1.1 request without \"Host\" header, URL: \"%V\"",
+    "client %V sent invalid \"Content-Length\" header, URL: \"%V\"",
+    "client %V sent POST method without \"Content-Length\" header, URL: \"%V\"",
 };
 
 
@@ -105,14 +103,15 @@ void ngx_http_init_connection(ngx_connec
     ngx_event_t         *rev;
     ngx_http_log_ctx_t  *ctx;
 
-    if (!(ctx = ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)))) {
+    if (!(ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t)))) {
         ngx_http_close_connection(c);
         return;
     }
 
     ctx->connection = c->number;
-    ctx->client = c->addr_text.data;
+    ctx->client = &c->addr_text;
     ctx->action = "reading client request line";
+    ctx->request = NULL;
     c->log->data = ctx;
     c->log->handler = ngx_http_log_error;
     c->log_error = NGX_ERROR_INFO;
@@ -278,7 +277,7 @@ static void ngx_http_init_request(ngx_ev
          * AcceptEx() already gave this address.
          */
 
-#if (WIN32)
+#if (NGX_WIN32)
         if (c->local_sockaddr) {
             r->in_addr =
                    ((struct sockaddr_in *) c->local_sockaddr)->sin_addr.s_addr;
@@ -295,7 +294,7 @@ static void ngx_http_init_request(ngx_ev
 
             r->in_addr = addr_in.sin_addr.s_addr;
 
-#if (WIN32)
+#if (NGX_WIN32)
         }
 #endif
 
@@ -428,9 +427,9 @@ static void ngx_http_init_request(ngx_ev
 
 static void ngx_http_ssl_handshake(ngx_event_t *rev)
 {
-    int                  n;
+    u_char               buf[1];
+    ssize_t              n;
     ngx_int_t            rc;
-    u_char               buf[1];
     ngx_connection_t    *c;
     ngx_http_request_t  *r;
 
@@ -454,7 +453,7 @@ static void ngx_http_ssl_handshake(ngx_e
     if (n == 1) {
         if (buf[0] == 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) {
             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0,
-                           "https ssl handshake: 0x%X", buf[0]);
+                           "https ssl handshake: 0x%02Xd", buf[0]);
 
             c->recv = ngx_ssl_recv;
             c->send_chain = ngx_ssl_send_chain;
@@ -488,7 +487,6 @@ static void ngx_http_ssl_handshake(ngx_e
 
 static void ngx_http_process_request_line(ngx_event_t *rev)
 {
-    u_char              *p;
     ssize_t              n;
     ngx_int_t            rc, rv;
     ngx_connection_t    *c;
@@ -524,21 +522,9 @@ static void ngx_http_process_request_lin
 
             /* the request line has been parsed successfully */
 
-            /* copy unparsed URI */
-
-            r->unparsed_uri.len = r->uri_end - r->uri_start;
-            r->unparsed_uri.data = ngx_palloc(r->pool, r->unparsed_uri.len + 1);
-            if (r->unparsed_uri.data == NULL) {
-                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                ngx_http_close_connection(c);
-                return;
-            }
-
-            ngx_cpystrn(r->unparsed_uri.data, r->uri_start,
-                        r->unparsed_uri.len + 1);
-
-
-            /* copy URI */
+            r->request_line.len = r->request_end - r->request_start;
+            r->request_line.data = r->request_start;
+
 
             if (r->args_start) {
                 r->uri.len = r->args_start - 1 - r->uri_start;
@@ -546,13 +532,14 @@ static void ngx_http_process_request_lin
                 r->uri.len = r->uri_end - r->uri_start;
             }
 
-            if (!(r->uri.data = ngx_palloc(r->pool, r->uri.len + 1))) {
-                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                ngx_http_close_connection(c);
-                return;
-            }
-
             if (r->complex_uri || r->quoted_uri) {
+
+                if (!(r->uri.data = ngx_palloc(r->pool, r->uri.len + 1))) {
+                    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                    ngx_http_close_connection(c);
+                    return;
+                }
+
                 rc = ngx_http_parse_complex_uri(r);
 
                 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
@@ -562,74 +549,55 @@ static void ngx_http_process_request_lin
                 }
 
                 if (rc != NGX_OK) {
-                    r->request_line.len = r->request_end - r->request_start;
-                    r->request_line.data = r->request_start;
-
                     ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST);
                     return;
                 }
 
             } else {
-                ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
+                r->uri.data = r->uri_start;
             }
 
-
-            r->request_line.len = r->request_end - r->request_start;
-            r->request_line.data = r->request_start;
-            r->request_line.data[r->request_line.len] = '\0';
+            r->unparsed_uri.len = r->uri_end - r->uri_start;
+            r->unparsed_uri.data = r->uri_start;
+
 
             if (r->method == 0) {
                 r->method_name.len = r->method_end - r->request_start + 1;
                 r->method_name.data = r->request_line.data;
             }
 
+
             if (r->uri_ext) {
-
-                /* copy URI extention */
-
                 if (r->args_start) {
                     r->exten.len = r->args_start - 1 - r->uri_ext;
                 } else {
                     r->exten.len = r->uri_end - r->uri_ext;
                 }
 
-                if (!(r->exten.data = ngx_palloc(r->pool, r->exten.len + 1))) {
-                    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                    ngx_http_close_connection(c);
-                    return;
-                }
-
-                ngx_cpystrn(r->exten.data, r->uri_ext, r->exten.len + 1);
+                r->exten.data = r->uri_ext;
             }
 
+
             if (r->args_start && r->uri_end > r->args_start) {
-
-                /* copy URI arguments */
-
                 r->args.len = r->uri_end - r->args_start;
-
-                if (!(r->args.data = ngx_palloc(r->pool, r->args.len + 1))) {
-                    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                    ngx_http_close_connection(c);
-                    return;
-                }
-
-                ngx_cpystrn(r->args.data, r->args_start, r->args.len + 1);
+                r->args.data = r->args_start;
             }
 
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                           "http request line: \"%V\"", &r->request_line);
+
             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                           "http request line: \"%s\"", r->request_line.data);
-
-            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                           "http uri: \"%s\"", r->uri.data);
+                           "http uri: \"%V\"", &r->uri);
 
             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                           "http args: \"%s\"",
-                           r->args.data ? r->args.data : (u_char *) "");
+                           "http args: \"%V\"", &r->args);
 
             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                           "http exten: \"%s\"",
-                           r->exten.data ? r->exten.data : (u_char *) "");
+                           "http exten: \"%V\"", &r->exten);
+
+            ctx = c->log->data;
+            ctx->request = r;
 
             if (r->http_version < NGX_HTTP_VERSION_10) {
                 rev->event_handler = ngx_http_block_read;
@@ -655,10 +623,7 @@ static void ngx_http_process_request_lin
                 return;
             }
 
-
-            ctx = c->log->data;
             ctx->action = "reading client request headers";
-            ctx->url = r->unparsed_uri.data;
 
             rev->event_handler = ngx_http_process_request_headers;
             ngx_http_process_request_headers(rev);
@@ -669,6 +634,9 @@ static void ngx_http_process_request_lin
 
             /* there was error while a request line parsing */
 
+            ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST);
+
+#if 0
             for (p = r->request_start; p < r->header_in->last; p++) {
                 if (*p == CR || *p == LF) {
                     break;
@@ -686,6 +654,8 @@ static void ngx_http_process_request_lin
                                   (rc == NGX_HTTP_PARSE_INVALID_METHOD) ?
                                          NGX_HTTP_NOT_IMPLEMENTED:
                                          NGX_HTTP_BAD_REQUEST);
+#endif
+
             return;
         }
 
@@ -811,8 +781,8 @@ static void ngx_http_process_request_hea
             }
 
             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                           "http header: \"%s: %s\"",
-                           h->key.data, h->value.data);
+                           "http header: \"%V: %V\"",
+                           &h->key, &h->value);
 
             continue;
 
@@ -973,7 +943,7 @@ static ngx_int_t ngx_http_alloc_large_he
         b = hc->free[--hc->nfree];
 
         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "http large header free: " PTR_FMT " " SIZE_T_FMT,
+                       "http large header free: %p %uz",
                        b->pos, b->end - b->last);
 
     } else if (hc->nbusy < cscf->large_client_header_buffers.num) {
@@ -993,7 +963,7 @@ static ngx_int_t ngx_http_alloc_large_he
         }
 
         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "http large header alloc: " PTR_FMT " " SIZE_T_FMT,
+                       "http large header alloc: %p %uz",
                        b->pos, b->end - b->last);
 
     } else {
@@ -1095,7 +1065,7 @@ static ngx_int_t ngx_http_process_reques
         for (i = 0; i < r->virtual_names->nelts; i++) {
 
             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                           "server name: %s", name[i].name.data);
+                           "server name: %V", &name[i].name);
 
             if (name[i].wildcard) {
                 if (r->headers_in.host_name_len <= name[i].name.len) {
@@ -1579,7 +1549,7 @@ static void ngx_http_set_keepalive(ngx_h
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler");
 
-    ctx = (ngx_http_log_ctx_t *) c->log->data;
+    ctx = c->log->data;
     ctx->action = "closing request";
 
     hc = r->http_connection;
@@ -1677,7 +1647,7 @@ static void ngx_http_set_keepalive(ngx_h
         b->last = b->start;
     }
 
-    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: " PTR_FMT " %d",
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p %d",
                    hc->free, hc->nfree);
 
     if (hc->free) {
@@ -1689,7 +1659,7 @@ static void ngx_http_set_keepalive(ngx_h
         hc->nfree = 0;
     }
 
-    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: " PTR_FMT " %d",
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %d",
                    hc->busy, hc->nbusy);
 
     if (hc->busy) {
@@ -1785,8 +1755,9 @@ static void ngx_http_keepalive_handler(n
 
     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
         if (rev->pending_eof) {
+            rev->log->handler = NULL;
             ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
-                          "kevent() reported that client %s closed "
+                          "kevent() reported that client %V closed "
                           "keepalive connection", ctx->client);
             ngx_http_close_connection(c);
             return;
@@ -1841,7 +1812,7 @@ static void ngx_http_keepalive_handler(n
 
     if (n == 0) {
         ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno,
-                      "client %s closed keepalive connection", ctx->client);
+                      "client %V closed keepalive connection", ctx->client);
         ngx_http_close_connection(c);
         return;
     }
@@ -2055,7 +2026,7 @@ void ngx_http_close_request(ngx_http_req
     if (r->file.fd != NGX_INVALID_FILE) {
         if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
             ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
-                          ngx_close_file_n " \"%s\" failed", r->file.name.data);
+                          ngx_close_file_n " \"%V\" failed", &r->file.name);
         }
     }
 
@@ -2067,8 +2038,8 @@ void ngx_http_close_request(ngx_http_req
                                                              == NGX_FILE_ERROR)
         {
             ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
-                          ngx_close_file_n " deleted file \"%s\" failed",
-                          r->request_body->temp_file->file.name.data);
+                          ngx_close_file_n " deleted file \"%V\" failed",
+                          &r->request_body->temp_file->file.name);
         }
     }
 
@@ -2088,9 +2059,9 @@ void ngx_http_close_request(ngx_http_req
         }
     }
 
-    /* ctx->url was allocated from r->pool */
+    /* the variuos request strings were allocated from r->pool */
     ctx = log->data;
-    ctx->url = NULL;
+    ctx->request = NULL;
 
     r->request_line.len = 0;
 
@@ -2148,6 +2119,7 @@ void ngx_http_close_connection(ngx_conne
 static void ngx_http_client_error(ngx_http_request_t *r,
                                   int client_error, int error)
 {
+    u_char                    *p;
     ngx_http_log_ctx_t        *ctx;
     ngx_http_core_srv_conf_t  *cscf;
 
@@ -2164,13 +2136,15 @@ static void ngx_http_client_error(ngx_ht
 
     r->connection->log->handler = NULL;
 
-    if (ctx->url) {
+    if (ctx->request) {
+
         switch (client_error) {
 
         case NGX_HTTP_PARSE_INVALID_HOST:
             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                    client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR],
-                    ctx->client, r->headers_in.host->value.data, ctx->url);
+                   "client %V sent invalid \"Host\" header \"%V\", URL: \"%V\"",
+                   ctx->client, &r->headers_in.host->value,
+                   &ctx->request->unparsed_uri);
 
             error = NGX_HTTP_INVALID_HOST;
 
@@ -2186,24 +2160,49 @@ static void ngx_http_client_error(ngx_ht
 
         case NGX_HTTP_PARSE_HTTP_TO_HTTPS:
             error = NGX_HTTP_TO_HTTPS;
-
-            /* fall through */
+            if (ctx->request->headers_in.referer) {
+                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                    "client %V sent plain HTTP request to HTTPS port, "
+                    "URL: \"%V\", referrer \"%V\"",
+                    ctx->client, &ctx->request->unparsed_uri,
+                    &ctx->request->headers_in.referer->value);
+
+            } else {
+                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                    "client %V sent plain HTTP request to HTTPS port, "
+                    "URL: \"%V\"", ctx->client, &ctx->request->unparsed_uri);
+            }
+
+            break;
 
         default:
             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                     client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR],
-                    ctx->client, ctx->url);
+                    ctx->client, &ctx->request->unparsed_uri);
         }
 
     } else {
+
         if (error == NGX_HTTP_REQUEST_URI_TOO_LARGE) {
             r->request_line.len = r->header_in->end - r->request_start;
             r->request_line.data = r->request_start;
+
+        } else {
+            if (r->request_line.data == NULL) {
+                for (p = r->request_start; p < r->header_in->last; p++) {
+                    if (*p == CR || *p == LF) {
+                        break;
+                    }
+                }
+
+                r->request_line.len = p - r->request_start;
+                r->request_line.data = r->request_start;
+            }
         }
 
         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                     client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR],
-                    ctx->client);
+                    ctx->client, &r->request_line);
     }
 
     r->connection->log->handler = ngx_http_log_error;
@@ -2212,20 +2211,35 @@ static void ngx_http_client_error(ngx_ht
 }
 
 
-static size_t ngx_http_log_error(void *data, char *buf, size_t len)
+static u_char *ngx_http_log_error(void *data, u_char *buf, size_t len)
 {
     ngx_http_log_ctx_t *ctx = data;
 
-    if (ctx->action && ctx->url) {
-        return ngx_snprintf(buf, len, " while %s, client: %s, URL: %s",
-                            ctx->action, ctx->client, ctx->url);
-
-    } else if (ctx->action == NULL && ctx->url) {
-        return ngx_snprintf(buf, len, ", client: %s, URL: %s",
-                            ctx->client, ctx->url);
-
-    } else {
-        return ngx_snprintf(buf, len, " while %s, client: %s",
-                            ctx->action, ctx->client);
+    u_char *p;
+
+    p = buf;
+
+    if (ctx->action) {
+        p = ngx_snprintf(p, len, " while %s", ctx->action);
+        len -= p - buf;
+    }
+
+    p = ngx_snprintf(p, len, ", client: %V", ctx->client);
+
+    if (ctx->request == NULL) {
+        return p;
     }
+
+    len -= p - buf;
+
+    p = ngx_snprintf(p, len, ", URL: \"%V\"", &ctx->request->unparsed_uri);
+
+    if (ctx->request->headers_in.referer == NULL) {
+        return p;
+    }
+
+    len -= p - buf;
+
+    return ngx_snprintf(p, len, ", referrer: \"%V\"",
+                        &ctx->request->headers_in.referer->value);
 }