diff --git a/net/http/khttprepeatable.c b/net/http/khttprepeatable.c index 11360b35f..184823e70 100644 --- a/net/http/khttprepeatable.c +++ b/net/http/khttprepeatable.c @@ -77,6 +77,7 @@ const bool kHttpRepeatable[kHttpHeadersMax] = { [kHttpVia] = true, [kHttpWarning] = true, [kHttpWwwAuthenticate] = true, + [kHttpXForwardedFor] = true, [kHttpAccessControlAllowHeaders] = true, [kHttpAccessControlAllowMethods] = true, [kHttpAccessControlRequestHeaders] = true, diff --git a/net/http/parseforwarded.c b/net/http/parseforwarded.c index 4b25697eb..90759ca90 100644 --- a/net/http/parseforwarded.c +++ b/net/http/parseforwarded.c @@ -24,13 +24,13 @@ * * This header is used by reverse proxies. For example: * - * X-Forwarded-For: 203.0.113.42:31337 + * X-Forwarded-For: 203.0.110.2, 203.0.113.42:31337 * * The port is optional and will be set to zero if absent. * * @param s is input data * @param n if -1 implies strlen - * @param ip receives ip on success if not NULL + * @param ip receives last/right ip on success if not NULL * @param port receives port on success if not NULL * @return 0 on success or -1 on failure * @see RFC7239's poorly designed Forwarded header @@ -41,7 +41,15 @@ int ParseForwarded(const char *s, size_t n, uint32_t *ip, uint16_t *port) { uint32_t x; if (n == -1) n = s ? strlen(s) : 0; if (n) { - t = x = i = 0; + t = x = 0; + i = n; + while (i > 0) { + if (s[--i] & 255 == ',') { + // skip optional space + if (s[++i] & 255 == ' ') ++i; + break; // i points to the start of the address + } + } do { c = s[i++] & 255; if (isdigit(c)) {