diff src/http/ngx_http_header_filter.c @ 96:a23d010f356d

nginx-0.0.1-2003-05-27-16:18:54 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 27 May 2003 12:18:54 +0000
parents 637625a2acdb
children c9b243802a17
line wrap: on
line diff
--- a/src/http/ngx_http_header_filter.c
+++ b/src/http/ngx_http_header_filter.c
@@ -19,8 +19,6 @@ static int ngx_http_header_filter(ngx_ht
 
 
 static ngx_http_module_t  ngx_http_header_filter_module_ctx = {
-    NGX_HTTP_MODULE,
-
     NULL,                                  /* create main configuration */
     NULL,                                  /* init main configuration */
 
@@ -33,10 +31,10 @@ static ngx_http_module_t  ngx_http_heade
 
 
 ngx_module_t  ngx_http_header_filter_module = {
+    NGX_MODULE,
     &ngx_http_header_filter_module_ctx,    /* module context */
-    0,                                     /* module index */
     NULL,                                  /* module directives */
-    NGX_HTTP_MODULE_TYPE,                  /* module type */
+    NGX_HTTP_MODULE,                       /* module type */
     ngx_http_header_filter_init            /* init module */
 };
 
@@ -47,30 +45,41 @@ static char server_string[] = "Server: "
 static ngx_str_t http_codes[] = {
 
     ngx_string("200 OK"),
+    ngx_null_string,  /* "201 Created" */
+    ngx_null_string,  /* "202 Accepted" */
+    ngx_null_string,  /* "203 Non-Authoritative Information" */
+    ngx_null_string,  /* "204 No Content" */
+    ngx_null_string,  /* "205 Reset Content" */
+    ngx_string("206 Partial Content"),
+    ngx_null_string,  /* "207 Multi-Status" */
+
+#if 0
+    ngx_null_string,  /* "300 Multiple Choices" */
+#endif
 
     ngx_string("301 Moved Permanently"),
     ngx_string("302 Moved Temporarily"),
-    ngx_null_string,  /* 303 */
+    ngx_null_string,  /* "303 See Other" */
     ngx_string("304 Not Modified"),
 
     ngx_string("400 Bad Request"),
-    ngx_null_string,  /* 401 */
-    ngx_null_string,  /* 402 */
+    ngx_string("401 Unauthorized"),
+    ngx_null_string,  /* "402 Payment Required" */
     ngx_string("403 Forbidden"),
     ngx_string("404 Not Found"),
-    ngx_null_string,  /* 405 */
-    ngx_null_string,  /* 406 */
-    ngx_null_string,  /* 407 */
+    ngx_string("405 Not Allowed"),
+    ngx_null_string,  /* "406 Not Acceptable" */
+    ngx_null_string,  /* "407 Proxy Authentication Required" */
     ngx_string("408 Request Time-out"),
-    ngx_null_string,  /* 409 */
-    ngx_null_string,  /* 410 */
+    ngx_null_string,  /* "409 Conflict" */
+    ngx_null_string,  /* "410 Gone" */
     ngx_string("411 Length Required"),
-    ngx_null_string,  /* 412 */
+    ngx_null_string,  /* "412 Precondition Failed" */
     ngx_string("413 Request Entity Too Large"),
     ngx_null_string,  /* "414 Request-URI Too Large" but we never send it
                          because we treat such requests as the HTTP/0.9 requests
                          and send only the body without the header */
-    ngx_null_string,  /* 415 */
+    ngx_null_string,  /* "415 Unsupported Media Type" */
     ngx_string("416 Requested Range Not Satisfiable"),
 
     ngx_string("500 Internal Server Error"),
@@ -84,7 +93,7 @@ static ngx_str_t http_codes[] = {
 
 static int ngx_http_header_filter(ngx_http_request_t *r)
 {
-    int               len, status, i;
+    int               len, status, text, i;
     time_t            ims;
     ngx_hunk_t       *h;
     ngx_chain_t      *ch;
@@ -94,6 +103,10 @@ static int ngx_http_header_filter(ngx_ht
         return NGX_OK;
     }
 
+    if (r->method == NGX_HTTP_HEAD) {
+        r->header_only = 1;
+    }
+
     /* 9 is for "HTTP/1.x ", 2 is for trailing "\r\n"
        and 2 is for end of header */
     len = 9 + 2 + 2;
@@ -132,17 +145,17 @@ static int ngx_http_header_filter(ngx_ht
 
         } else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) {
             /* 3XX */
-            status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 1;
+            status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 8;
             r->header_only = 1;
 
         } else if (r->headers_out.status < NGX_HTTP_INTERNAL_SERVER_ERROR) {
             /* 4XX */
-            status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 1 + 4;
+            status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 8 + 4;
 
         } else {
             /* 5XX */
             status = r->headers_out.status
-                                 - NGX_HTTP_INTERNAL_SERVER_ERROR + 1 + 4 + 17;
+                                 - NGX_HTTP_INTERNAL_SERVER_ERROR + 8 + 4 + 17;
         }
 
         len += http_codes[status].len;
@@ -159,31 +172,55 @@ static int ngx_http_header_filter(ngx_ht
         len += r->headers_out.date->key.len
                + r->headers_out.date->value.len + 2;
     } else {
-        /* "Date: ... \r\n"; */
+        /* "Date: ... \r\n" */
         len += 37;
     }
 
-    /* 2^64 is 20 characters */
     if (r->headers_out.content_length >= 0) {
+        /* "Content-Length: ... \r\n", 2^64 is 20 characters */
         len += 48;
     }
 
-#if 0
-    if (r->headers_out.content_type.len)
-        len += r->headers_out.content_type.len + 16;
-#endif
+    text = 0;
+    if (r->headers_out.content_type && r->headers_out.content_type->value.len) {
+        r->headers_out.content_type->key.len = 0;
+        len += 16 + r->headers_out.content_type->value.len;
+        if (ngx_strncasecmp(r->headers_out.content_type->value.data,
+                                                            "text/", 5) == 0) {
+            text = 1;
+            /* "; charset=koi8-r" */
+            len += 16;
+        }
+    }
+
+    if (r->headers_out.location
+        && r->headers_out.location->value.len
+        && r->headers_out.location->value.data[0] == '/')
+    {
+        r->headers_out.location->key.len = 0;
+        /* "Location: http:// ... \r\n" */
+        len += 17 + r->server_name->len
+               + r->headers_out.location->value.len + 2;
+
+        if (r->port != 80) {
+            len += r->port_name->len;
+        }
+    }
 
     if (r->headers_out.last_modified && r->headers_out.last_modified->key.len) {
         len += r->headers_out.last_modified->key.len
                + r->headers_out.last_modified->value.len + 2;
+
     } else if (r->headers_out.last_modified_time != -1) {
-        /* "Last-Modified: ... \r\n"; */
+        /* "Last-Modified: ... \r\n" */
         len += 46;
     }
 
     if (r->keepalive == 0) {
+        /* "Connection: close\r\n" */
         len += 19;
     } else {
+        /* "Connection: keep-alive\r\n" */
         len += 24;
     }
 
@@ -199,30 +236,25 @@ static int ngx_http_header_filter(ngx_ht
     ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 64), NGX_ERROR);
 
     /* "HTTP/1.x " */
-    ngx_memcpy(h->last, "HTTP/1.1 ", 9);
-    h->last += 9;
+    h->last = ngx_cpymem(h->last, "HTTP/1.1 ", 9);
 
     /* status line */
     if (r->headers_out.status_line.len) {
-        ngx_memcpy(h->last, r->headers_out.status_line.data,
-                   r->headers_out.status_line.len);
-        h->last += r->headers_out.status_line.len;
+        h->last = ngx_cpymem(h->last, r->headers_out.status_line.data,
+                             r->headers_out.status_line.len);
 
     } else {
-        ngx_memcpy(h->last, http_codes[status].data,
-                   http_codes[status].len);
-        h->last += http_codes[status].len;
+        h->last = ngx_cpymem(h->last, http_codes[status].data,
+                             http_codes[status].len);
     }
     *(h->last++) = CR; *(h->last++) = LF;
 
     if (!(r->headers_out.server && r->headers_out.server->key.len)) {
-        ngx_memcpy(h->last, server_string, sizeof(server_string) - 1);
-        h->last += sizeof(server_string) - 1;
+        h->last = ngx_cpymem(h->last, server_string, sizeof(server_string) - 1);
     }
 
     if (!(r->headers_out.date && r->headers_out.date->key.len)) {
-        ngx_memcpy(h->last, "Date: ", 6);
-        h->last += 6;
+        h->last = ngx_cpymem(h->last, "Date: ", 6);
         h->last += ngx_http_get_time(h->last, time(NULL));
         *(h->last++) = CR; *(h->last++) = LF;
     }
@@ -230,39 +262,54 @@ static int ngx_http_header_filter(ngx_ht
     /* 2^64 is 20 characters  */
     if (r->headers_out.content_length >= 0) {
         h->last += ngx_snprintf(h->last, 49,
-                                    "Content-Length: " OFF_FMT CRLF,
-                                    r->headers_out.content_length);
+                                "Content-Length: " OFF_FMT CRLF,
+                                r->headers_out.content_length);
+    }
+
+    if (r->headers_out.content_type && r->headers_out.content_type->value.len) {
+        h->last = ngx_cpymem(h->last, "Content-Type: ", 14);
+        h->last = ngx_cpymem(h->last, r->headers_out.content_type->value.data,
+                   r->headers_out.content_type->value.len);
+
+        if (text) {
+            h->last = ngx_cpymem(h->last, "; charset=koi8-r", 16);
+        }
+
+        *(h->last++) = CR; *(h->last++) = LF;
     }
 
-#if 0
-    if (r->headers_out.content_type.len) {
-        ngx_memcpy(h->last, "Content-Type: ", 14);
-        h->last += 14;
-        ngx_memcpy(h->last, r->headers_out.content_type.data,
-                   r->headers_out.content_type.len);
-        h->last += r->headers_out.content_type.len;
+    if (r->headers_out.location
+        && r->headers_out.location->value.len
+        && r->headers_out.location->value.data[0] == '/')
+    {
+        h->last = ngx_cpymem(h->last, "Location: http://", 17);
+        h->last = ngx_cpymem(h->last, r->server_name->data,
+                             r->server_name->len);
+        if (r->port != 80) {
+            h->last = ngx_cpymem(h->last, r->port_name->data,
+                                 r->port_name->len);
+        }
+
+        h->last = ngx_cpymem(h->last, r->headers_out.location->value.data,
+                             r->headers_out.location->value.len);
+
         *(h->last++) = CR; *(h->last++) = LF;
     }
-#endif
 
-    if (!(r->headers_out.last_modified
-          && r->headers_out.last_modified->key.len)
+    if (!(r->headers_out.last_modified && r->headers_out.last_modified->key.len)
         && r->headers_out.last_modified_time != -1)
     {
-        ngx_memcpy(h->last, "Last-Modified: ", 15);
-        h->last += 15;
+        h->last = ngx_cpymem(h->last, "Last-Modified: ", 15);
         h->last += ngx_http_get_time(h->last,
                                          r->headers_out.last_modified_time);
         *(h->last++) = CR; *(h->last++) = LF;
     }
 
     if (r->keepalive == 0) {
-        ngx_memcpy(h->last, "Connection: close" CRLF, 19);
-        h->last += 19;
+        h->last = ngx_cpymem(h->last, "Connection: close" CRLF, 19);
 
     } else {
-        ngx_memcpy(h->last, "Connection: keep-alive" CRLF, 24);
-        h->last += 24;
+        h->last = ngx_cpymem(h->last, "Connection: keep-alive" CRLF, 24);
     }
 
     for (i = 0; i < r->headers_out.headers->nelts; i++) {
@@ -270,12 +317,11 @@ static int ngx_http_header_filter(ngx_ht
             continue;
         }
 
-        ngx_memcpy(h->last, header[i].key.data, header[i].key.len);
-        h->last += header[i].key.len;
+        h->last = ngx_cpymem(h->last, header[i].key.data, header[i].key.len);
         *(h->last++) = ':' ; *(h->last++) = ' ' ;
 
-        ngx_memcpy(h->last, header[i].value.data, header[i].value.len);
-        h->last += header[i].value.len;
+        h->last = ngx_cpymem(h->last, header[i].value.data,
+                             header[i].value.len);
         *(h->last++) = CR; *(h->last++) = LF;
     }
 
@@ -284,7 +330,7 @@ static int ngx_http_header_filter(ngx_ht
     ngx_log_debug(r->connection->log, "%s\n" _ h->pos);
     /**/
 
-    /* end of HTTP header */
+    /* the end of HTTP header */
     *(h->last++) = CR; *(h->last++) = LF;
 
     if (r->header_only) {