diff src/core/ngx_inet.c @ 6564:19db5a6bc34e

Realip: port support in X-Real-IP and X-Forwarded-For. Now, the module extracts optional port which may accompany an IP address. This custom extension is introduced, among other things, in order to facilitate logging of original client ports. Addresses with ports are expected to be in the RFC 3986 format, that is, with IPv6 addresses in square brackets. E.g., "X-Real-IP: [2001:0db8::1]:12345" sets client port ($remote_port) to 12345.
author Dmitry Volyntsev <xeioex@nginx.com>
date Mon, 23 May 2016 18:44:23 +0300
parents adf25b8d0431
children 5d8f16859ced
line wrap: on
line diff
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -526,6 +526,85 @@ ngx_parse_addr(ngx_pool_t *pool, ngx_add
 
 
 ngx_int_t
+ngx_parse_addr_port(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text,
+    size_t len)
+{
+    u_char               *p, *last;
+    size_t                plen;
+    ngx_int_t             rc, port;
+    struct sockaddr_in   *sin;
+#if (NGX_HAVE_INET6)
+    struct sockaddr_in6  *sin6;
+#endif
+
+    rc = ngx_parse_addr(pool, addr, text, len);
+
+    if (rc != NGX_DECLINED) {
+        return rc;
+    }
+
+    last = text + len;
+
+#if (NGX_HAVE_INET6)
+    if (len && text[0] == '[') {
+
+        p = ngx_strlchr(text, last, ']');
+
+        if (p == NULL || p == last - 1 || *++p != ':') {
+            return NGX_DECLINED;
+        }
+
+        text++;
+        len -= 2;
+
+    } else
+#endif
+
+    {
+        p = ngx_strlchr(text, last, ':');
+
+        if (p == NULL) {
+            return NGX_DECLINED;
+        }
+    }
+
+    p++;
+    plen = last - p;
+
+    port = ngx_atoi(p, plen);
+
+    if (port < 1 || port > 65535) {
+        return NGX_DECLINED;
+    }
+
+    len -= plen + 1;
+
+    rc = ngx_parse_addr(pool, addr, text, len);
+
+    if (rc != NGX_OK) {
+        return rc;
+    }
+
+    switch (addr->sockaddr->sa_family) {
+
+#if (NGX_HAVE_INET6)
+    case AF_INET6:
+        sin6 = (struct sockaddr_in6 *) addr->sockaddr;
+        sin6->sin6_port = htons(port);
+        break;
+#endif
+
+    default: /* AF_INET */
+        sin = (struct sockaddr_in *) addr->sockaddr;
+        sin->sin_port = htons(port);
+        break;
+    }
+
+    return NGX_OK;
+}
+
+
+ngx_int_t
 ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)
 {
     u_char  *p;