Mercurial > hg > nginx
changeset 1219:86c5c9288acc
SNI support
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 29 May 2007 15:21:09 +0000 |
parents | e081e9c2291c |
children | 91ae88fb2500 |
files | src/http/modules/ngx_http_ssl_module.c src/http/ngx_http.h src/http/ngx_http_request.c |
diffstat | 3 files changed, 84 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/src/http/modules/ngx_http_ssl_module.c Tue May 29 12:15:04 2007 +0000 +++ b/src/http/modules/ngx_http_ssl_module.c Tue May 29 15:21:09 2007 +0000 @@ -345,6 +345,19 @@ return NGX_CONF_ERROR; } +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + + if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx, + ngx_http_ssl_servername) + == 0) + { + ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, + "SSL_CTX_set_tlsext_servername_callback() failed"); + return NGX_CONF_ERROR; + } + +#endif + cln = ngx_pool_cleanup_add(cf->pool, 0); if (cln == NULL) { return NGX_CONF_ERROR;
--- a/src/http/ngx_http.h Tue May 29 12:15:04 2007 +0000 +++ b/src/http/ngx_http.h Tue May 29 15:21:09 2007 +0000 @@ -59,6 +59,10 @@ void ngx_http_init_connection(ngx_connection_t *c); +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME +int ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg); +#endif + ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b); ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r); ngx_int_t ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
--- a/src/http/ngx_http_request.c Tue May 29 12:15:04 2007 +0000 +++ b/src/http/ngx_http_request.c Tue May 29 15:21:09 2007 +0000 @@ -25,8 +25,8 @@ ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r); -static void ngx_http_find_virtual_server(ngx_http_request_t *r, - ngx_http_virtual_names_t *vn, ngx_uint_t hash); +static void ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, + size_t len, ngx_uint_t hash); static void ngx_http_request_handler(ngx_event_t *ev); static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r); @@ -544,6 +544,54 @@ return; } +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + +int +ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) +{ + u_char *p; + ngx_uint_t hash; + const char *servername; + ngx_connection_t *c; + ngx_http_request_t *r; + ngx_http_ssl_srv_conf_t *sscf; + + servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name); + + if (servername == NULL) { + return SSL_TLSEXT_ERR_NOACK; + } + + c = ngx_ssl_get_connection(ssl_conn); + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, + "SSL server name: \"%s\"", servername); + + r = c->data; + + if (r->virtual_names == NULL) { + return SSL_TLSEXT_ERR_NOACK; + } + + /* it seems browsers send low case server name */ + + hash = 0; + + for (p = (u_char *) servername; *p; p++) { + hash = ngx_hash(hash, *p); + } + + ngx_http_find_virtual_server(r, (u_char *) servername, + p - (u_char *) servername, hash); + + sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); + + SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx); + + return SSL_TLSEXT_ERR_OK; +} + +#endif #endif @@ -1203,7 +1251,7 @@ ngx_http_process_request_header(ngx_http_request_t *r) { size_t len; - u_char *ua, *user_agent, ch; + u_char *host, *ua, *user_agent, ch; ngx_uint_t hash; #if (NGX_HTTP_SSL) long rc; @@ -1234,7 +1282,18 @@ r->headers_in.host_name_len = len; if (r->virtual_names) { - ngx_http_find_virtual_server(r, r->virtual_names, hash); + + host = r->host_start; + + if (host == NULL) { + host = r->headers_in.host->value.data; + len = r->headers_in.host_name_len; + + } else { + len = r->host_end - host; + } + + ngx_http_find_virtual_server(r, host, len, hash); } } else { @@ -1394,23 +1453,14 @@ static void -ngx_http_find_virtual_server(ngx_http_request_t *r, - ngx_http_virtual_names_t *vn, ngx_uint_t hash) +ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len, + ngx_uint_t hash) { - size_t len; - u_char *host; + ngx_http_virtual_names_t *vn; ngx_http_core_loc_conf_t *clcf; ngx_http_core_srv_conf_t *cscf; - host = r->host_start; - - if (host == NULL) { - host = r->headers_in.host->value.data; - len = r->headers_in.host_name_len; - - } else { - len = r->host_end - host; - } + vn = r->virtual_names; if (vn->hash.buckets) { cscf = ngx_hash_find(&vn->hash, hash, host, len);