diff src/http/modules/ngx_http_realip_module.c @ 286:5bef04fc3fd5 NGINX_0_5_13

nginx 0.5.13 *) Feature: the COPY and MOVE methods. *) Bugfix: the ngx_http_realip_module set garbage for requests passed via keep-alive connection. *) Bugfix: nginx did not work on big-endian 64-bit Linux. Thanks to Andrei Nigmatulin. *) Bugfix: now when IMAP/POP3 proxy receives too long command it closes the connection right away, but not after timeout. *) Bugfix: if the "epoll" method was used and a client closed a connection prematurely, then nginx closed the connection after a send timeout only. *) Bugfix: nginx could not be built on platforms different from i386, amd64, sparc and ppc; bug appeared in 0.5.8.
author Igor Sysoev <http://sysoev.ru>
date Mon, 19 Feb 2007 00:00:00 +0300
parents 29a6403156b0
children 9fc4ab6673f9
line wrap: on
line diff
--- a/src/http/modules/ngx_http_realip_module.c
+++ b/src/http/modules/ngx_http_realip_module.c
@@ -97,6 +97,7 @@ ngx_http_realip_handler(ngx_http_request
 {
     u_char                      *ip, *p;
     size_t                       len;
+    in_addr_t                    addr;
     ngx_uint_t                   i;
     struct sockaddr_in          *sin;
     ngx_http_realip_from_t      *from;
@@ -128,16 +129,19 @@ ngx_http_realip_handler(ngx_http_request
         len = r->headers_in.x_forwarded_for->value.len;
         ip = r->headers_in.x_forwarded_for->value.data;
 
-        for (p = ip + len; p > ip; p--) {
+        for (p = ip + len - 1; p > ip; p--) {
             if (*p == ' ' || *p == ',') {
-               p++;
-               len -= p - ip;
-               ip = p;
-               break;
+                p++;
+                len -= p - ip;
+                ip = p;
+                break;
             }
         }
     }
 
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "realip: \"%s\"", ip);
+
     /* AF_INET only */
 
     sin = (struct sockaddr_in *) r->connection->sockaddr;
@@ -151,12 +155,25 @@ ngx_http_realip_handler(ngx_http_request
 
         if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) {
 
-            r->connection->addr_text.len = len;
-            r->connection->addr_text.data = ip;
+            r->realip_set = 1;
+
+            addr = inet_addr((char *) ip);
+
+            if (addr == INADDR_NONE) {
+                return NGX_DECLINED;
+            }
 
-            sin->sin_addr.s_addr = inet_addr((char *) ip);
+            p = ngx_palloc(r->connection->pool, len);
+            if (p == NULL) {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
 
-            r->realip_set = 1;
+            ngx_memcpy(p, ip, len);
+
+            sin->sin_addr.s_addr = addr;
+
+            r->connection->addr_text.len = len;
+            r->connection->addr_text.data = p;
 
             return NGX_DECLINED;
         }