# HG changeset patch # User Valentin Bartenev # Date 1361984812 0 # Node ID ac31fcecb464d219b1a64a477a2739edec97ec04 # Parent 66e0f9adbc8c774044f9e0677951307069b22c4d SNI: ignore captures in server_name regexes when matching by SNI. This change helps to decouple ngx_http_ssl_servername() from the request object. Note: now we close connection in case of error during server name lookup for request. Previously, we did so only for HTTP/0.9 requests. diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -34,8 +34,11 @@ static ngx_int_t ngx_http_process_reques static void ngx_http_process_request(ngx_http_request_t *r); static ngx_int_t ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc); -static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r, - u_char *host, size_t len); +static ngx_int_t ngx_http_set_virtual_server(ngx_http_request_t *r, + ngx_str_t *host); +static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c, + ngx_http_virtual_names_t *virtual_names, ngx_str_t *host, + ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp); static void ngx_http_request_handler(ngx_event_t *ev); static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc); @@ -643,11 +646,14 @@ ngx_http_ssl_handshake_handler(ngx_conne int ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) { - ngx_str_t host; - const char *servername; - ngx_connection_t *c; - ngx_http_request_t *r; - ngx_http_ssl_srv_conf_t *sscf; + ngx_str_t host; + const char *servername; + ngx_connection_t *c; + ngx_http_request_t *r; + ngx_http_connection_t *hc; + ngx_http_ssl_srv_conf_t *sscf; + ngx_http_core_loc_conf_t *clcf; + ngx_http_core_srv_conf_t *cscf; servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name); @@ -674,10 +680,22 @@ ngx_http_ssl_servername(ngx_ssl_conn_t * return SSL_TLSEXT_ERR_NOACK; } - if (ngx_http_find_virtual_server(r, host.data, host.len) != NGX_OK) { + hc = r->http_connection; + + if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host, + NULL, &cscf) + != NGX_OK) + { return SSL_TLSEXT_ERR_NOACK; } + r->srv_conf = cscf->ctx->srv_conf; + r->loc_conf = cscf->ctx->loc_conf; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + ngx_http_set_connection_log(c, clcf->error_log); + sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (sscf->ssl.ctx) { @@ -903,11 +921,9 @@ ngx_http_process_request_line(ngx_event_ if (r->http_version < NGX_HTTP_VERSION_10) { - if (ngx_http_find_virtual_server(r, r->headers_in.server.data, - r->headers_in.server.len) + if (ngx_http_set_virtual_server(r, &r->headers_in.server) == NGX_ERROR) { - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } @@ -1551,11 +1567,7 @@ ngx_http_process_multi_header_lines(ngx_ static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r) { - if (ngx_http_find_virtual_server(r, r->headers_in.server.data, - r->headers_in.server.len) - == NGX_ERROR) - { - ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + if (ngx_http_set_virtual_server(r, &r->headers_in.server) == NGX_ERROR) { return NGX_ERROR; } @@ -1793,61 +1805,28 @@ ngx_http_validate_host(ngx_str_t *host, static ngx_int_t -ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len) +ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host) { + ngx_int_t rc; + ngx_http_connection_t *hc; ngx_http_core_loc_conf_t *clcf; ngx_http_core_srv_conf_t *cscf; - ngx_http_virtual_names_t *virtual_names; - - virtual_names = r->http_connection->addr_conf->virtual_names; - - if (virtual_names == NULL) { - return NGX_DECLINED; - } - - cscf = ngx_hash_find_combined(&virtual_names->names, - ngx_hash_key(host, len), host, len); - - if (cscf) { - goto found; + + hc = r->http_connection; + + rc = ngx_http_find_virtual_server(r->connection, + hc->addr_conf->virtual_names, + host, r, &cscf); + + if (rc == NGX_ERROR) { + ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_ERROR; } -#if (NGX_PCRE) - - if (len && virtual_names->nregex) { - ngx_int_t n; - ngx_uint_t i; - ngx_str_t name; - ngx_http_server_name_t *sn; - - name.len = len; - name.data = host; - - sn = virtual_names->regex; - - for (i = 0; i < virtual_names->nregex; i++) { - - n = ngx_http_regex_exec(r, sn[i].regex, &name); - - if (n == NGX_OK) { - cscf = sn[i].server; - goto found; - } - - if (n == NGX_DECLINED) { - continue; - } - - return NGX_ERROR; - } + if (rc == NGX_DECLINED) { + return NGX_OK; } -#endif - - return NGX_DECLINED; - -found: - r->srv_conf = cscf->ctx->srv_conf; r->loc_conf = cscf->ctx->loc_conf; @@ -1859,6 +1838,87 @@ found: } +static ngx_int_t +ngx_http_find_virtual_server(ngx_connection_t *c, + ngx_http_virtual_names_t *virtual_names, ngx_str_t *host, + ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp) +{ + ngx_http_core_srv_conf_t *cscf; + + if (virtual_names == NULL) { + return NGX_DECLINED; + } + + cscf = ngx_hash_find_combined(&virtual_names->names, + ngx_hash_key(host->data, host->len), + host->data, host->len); + + if (cscf) { + *cscfp = cscf; + return NGX_OK; + } + +#if (NGX_PCRE) + + if (host->len && virtual_names->nregex) { + ngx_int_t n; + ngx_uint_t i; + ngx_http_server_name_t *sn; + + sn = virtual_names->regex; + +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + + if (r == NULL) { + for (i = 0; i < virtual_names->nregex; i++) { + + n = ngx_regex_exec(sn[i].regex->regex, host, NULL, 0); + + if (n == NGX_REGEX_NO_MATCHED) { + continue; + } + + if (n >= 0) { + *cscfp = sn[i].server; + return NGX_OK; + } + + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + ngx_regex_exec_n " failed: %i " + "on \"%V\" using \"%V\"", + n, host, &sn[i].regex->name); + + return NGX_ERROR; + } + + return NGX_DECLINED; + } + +#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */ + + for (i = 0; i < virtual_names->nregex; i++) { + + n = ngx_http_regex_exec(r, sn[i].regex, host); + + if (n == NGX_DECLINED) { + continue; + } + + if (n == NGX_OK) { + *cscfp = sn[i].server; + return NGX_OK; + } + + return NGX_ERROR; + } + } + +#endif /* NGX_PCRE */ + + return NGX_DECLINED; +} + + static void ngx_http_request_handler(ngx_event_t *ev) {