static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r) { u_char *p; size_t len; ngx_str_t *value; ngx_uint_t i, hash; ngx_addr_t addr; ngx_array_t *xfwd; ngx_list_part_t *part; ngx_table_elt_t *header; ngx_connection_t *c; ngx_http_realip_ctx_t *ctx; ngx_http_realip_loc_conf_t *rlcf; ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module); if (ctx) { return NGX_DECLINED; } rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module); if (rlcf->from == NULL) { return NGX_DECLINED; } switch (rlcf->type) { case NGX_HTTP_REALIP_XREALIP: if (r->headers_in.x_real_ip == NULL) { return NGX_DECLINED; } value = &r->headers_in.x_real_ip->value; xfwd = NULL; break; case NGX_HTTP_REALIP_XFWD: xfwd = &r->headers_in.x_forwarded_for; if (xfwd->elts == NULL) { return NGX_DECLINED; } value = NULL; break; case NGX_HTTP_REALIP_PROXY: value = &r->connection->proxy_protocol_addr; if (value->len == 0) { return NGX_DECLINED; } xfwd = NULL; break; default: /* NGX_HTTP_REALIP_HEADER */ part = &r->headers_in.headers.part; header = part->elts; hash = rlcf->hash; len = rlcf->header.len; p = rlcf->header.data; for (i = 0; /* void */ ; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } if (hash == header[i].hash && len == header[i].key.len && ngx_strncmp(p, header[i].lowcase_key, len) == 0) { value = &header[i].value; xfwd = NULL; goto found; } } return NGX_DECLINED; } found: c = r->connection; addr.sockaddr = c->sockaddr; addr.socklen = c->socklen; /* addr.name = c->addr_text; */ if (ngx_http_get_forwarded_addr(r, &addr, xfwd, value, rlcf->from, rlcf->recursive) != NGX_DECLINED) { return ngx_http_realip_set_addr(r, &addr); } return NGX_DECLINED; }
static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r) { u_char *ip, *p; size_t len; ngx_uint_t i, hash; ngx_list_part_t *part; ngx_table_elt_t *header; struct sockaddr_in *sin; ngx_connection_t *c; ngx_http_realip_ctx_t *ctx; ngx_http_realip_from_t *from; ngx_http_realip_loc_conf_t *rlcf; ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module); if (ctx) { return NGX_DECLINED; } rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module); if (rlcf->from == NULL #if (NGX_HAVE_UNIX_DOMAIN) && !rlcf->unixsock #endif ) { return NGX_DECLINED; } switch (rlcf->type) { case NGX_HTTP_REALIP_XREALIP: if (r->headers_in.x_real_ip == NULL) { return NGX_DECLINED; } len = r->headers_in.x_real_ip->value.len; ip = r->headers_in.x_real_ip->value.data; break; case NGX_HTTP_REALIP_XFWD: if (r->headers_in.x_forwarded_for == NULL) { return NGX_DECLINED; } len = r->headers_in.x_forwarded_for->value.len; ip = r->headers_in.x_forwarded_for->value.data; for (p = ip + len - 1; p > ip; p--) { if (*p == ' ' || *p == ',') { p++; len -= p - ip; ip = p; break; } } break; default: /* NGX_HTTP_REALIP_HEADER */ part = &r->headers_in.headers.part; header = part->elts; hash = rlcf->hash; len = rlcf->header.len; p = rlcf->header.data; for (i = 0; /* void */ ; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } if (hash == header[i].hash && len == header[i].key.len && ngx_strncmp(p, header[i].lowcase_key, len) == 0) { len = header[i].value.len; ip = header[i].value.data; goto found; } } return NGX_DECLINED; } found: c = r->connection; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip); /* AF_INET only */ if (c->sockaddr->sa_family == AF_INET) { sin = (struct sockaddr_in *) c->sockaddr; from = rlcf->from->elts; for (i = 0; i < rlcf->from->nelts; i++) { ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: %08XD %08XD %08XD", sin->sin_addr.s_addr, from[i].mask, from[i].addr); if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) { return ngx_http_realip_set_addr(r, ip, len); } } } #if (NGX_HAVE_UNIX_DOMAIN) if (c->sockaddr->sa_family == AF_UNIX && rlcf->unixsock) { return ngx_http_realip_set_addr(r, ip, len); } #endif return NGX_DECLINED; }