Mercurial > hg > nginx
comparison src/http/v2/ngx_http_v2.c @ 9119:08ef02ad5c54
HTTP/2: "http2" directive.
The directive enables HTTP/2 in the current server. The previous way to
enable HTTP/2 via "listen ... http2" is now deprecated. The new approach
allows to share HTTP/2 and HTTP/0.9-1.1 on the same port.
For SSL connections, HTTP/2 is now selected by ALPN callback based on whether
the protocol is enabled in the virtual server chosen by SNI. This however only
works since OpenSSL 1.0.2h, where ALPN callback is invoked after SNI callback.
For older versions of OpenSSL, HTTP/2 is enabled based on the default virtual
server configuration.
For plain TCP connections, HTTP/2 is now auto-detected by HTTP/2 preface, if
HTTP/2 is enabled in the default virtual server. If preface is not matched,
HTTP/0.9-1.1 is assumed.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Tue, 16 May 2023 16:30:08 +0400 |
parents | 9db24374123b |
children | 262c01782566 |
comparison
equal
deleted
inserted
replaced
9118:b4a57278bf24 | 9119:08ef02ad5c54 |
---|---|
61 static void ngx_http_v2_write_handler(ngx_event_t *wev); | 61 static void ngx_http_v2_write_handler(ngx_event_t *wev); |
62 static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c); | 62 static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c); |
63 static void ngx_http_v2_lingering_close(ngx_connection_t *c); | 63 static void ngx_http_v2_lingering_close(ngx_connection_t *c); |
64 static void ngx_http_v2_lingering_close_handler(ngx_event_t *rev); | 64 static void ngx_http_v2_lingering_close_handler(ngx_event_t *rev); |
65 | 65 |
66 static u_char *ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c, | |
67 u_char *pos, u_char *end); | |
68 static u_char *ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c, | 66 static u_char *ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c, |
69 u_char *pos, u_char *end); | 67 u_char *pos, u_char *end); |
70 static u_char *ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c, | 68 static u_char *ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c, |
71 u_char *pos, u_char *end); | 69 u_char *pos, u_char *end); |
72 static u_char *ngx_http_v2_state_head(ngx_http_v2_connection_t *h2c, | 70 static u_char *ngx_http_v2_state_head(ngx_http_v2_connection_t *h2c, |
230 | 228 |
231 | 229 |
232 void | 230 void |
233 ngx_http_v2_init(ngx_event_t *rev) | 231 ngx_http_v2_init(ngx_event_t *rev) |
234 { | 232 { |
233 u_char *p, *end; | |
235 ngx_connection_t *c; | 234 ngx_connection_t *c; |
236 ngx_pool_cleanup_t *cln; | 235 ngx_pool_cleanup_t *cln; |
237 ngx_http_connection_t *hc; | 236 ngx_http_connection_t *hc; |
238 ngx_http_v2_srv_conf_t *h2scf; | 237 ngx_http_v2_srv_conf_t *h2scf; |
239 ngx_http_v2_main_conf_t *h2mcf; | 238 ngx_http_v2_main_conf_t *h2mcf; |
312 { | 311 { |
313 ngx_http_close_connection(c); | 312 ngx_http_close_connection(c); |
314 return; | 313 return; |
315 } | 314 } |
316 | 315 |
317 h2c->state.handler = hc->proxy_protocol ? ngx_http_v2_state_proxy_protocol | 316 h2c->state.handler = ngx_http_v2_state_preface; |
318 : ngx_http_v2_state_preface; | |
319 | 317 |
320 ngx_queue_init(&h2c->waiting); | 318 ngx_queue_init(&h2c->waiting); |
321 ngx_queue_init(&h2c->dependencies); | 319 ngx_queue_init(&h2c->dependencies); |
322 ngx_queue_init(&h2c->closed); | 320 ngx_queue_init(&h2c->closed); |
323 | 321 |
332 ngx_add_timer(rev, cscf->client_header_timeout); | 330 ngx_add_timer(rev, cscf->client_header_timeout); |
333 } | 331 } |
334 | 332 |
335 c->idle = 1; | 333 c->idle = 1; |
336 ngx_reusable_connection(c, 0); | 334 ngx_reusable_connection(c, 0); |
335 | |
336 if (c->buffer) { | |
337 p = c->buffer->pos; | |
338 end = c->buffer->last; | |
339 | |
340 do { | |
341 p = h2c->state.handler(h2c, p, end); | |
342 | |
343 if (p == NULL) { | |
344 return; | |
345 } | |
346 | |
347 } while (p != end); | |
348 | |
349 h2c->total_bytes += p - c->buffer->pos; | |
350 c->buffer->pos = p; | |
351 } | |
337 | 352 |
338 ngx_http_v2_read_handler(rev); | 353 ngx_http_v2_read_handler(rev); |
339 } | 354 } |
340 | 355 |
341 | 356 |
845 ngx_add_timer(rev, timer); | 860 ngx_add_timer(rev, timer); |
846 } | 861 } |
847 | 862 |
848 | 863 |
849 static u_char * | 864 static u_char * |
850 ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c, u_char *pos, | |
851 u_char *end) | |
852 { | |
853 ngx_log_t *log; | |
854 | |
855 log = h2c->connection->log; | |
856 log->action = "reading PROXY protocol"; | |
857 | |
858 pos = ngx_proxy_protocol_read(h2c->connection, pos, end); | |
859 | |
860 log->action = "processing HTTP/2 connection"; | |
861 | |
862 if (pos == NULL) { | |
863 return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR); | |
864 } | |
865 | |
866 return ngx_http_v2_state_preface(h2c, pos, end); | |
867 } | |
868 | |
869 | |
870 static u_char * | |
871 ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c, u_char *pos, | 865 ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c, u_char *pos, |
872 u_char *end) | 866 u_char *end) |
873 { | 867 { |
874 static const u_char preface[] = "PRI * HTTP/2.0\r\n"; | 868 static const u_char preface[] = NGX_HTTP_V2_PREFACE_START; |
875 | 869 |
876 if ((size_t) (end - pos) < sizeof(preface) - 1) { | 870 if ((size_t) (end - pos) < sizeof(preface) - 1) { |
877 return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_preface); | 871 return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_preface); |
878 } | 872 } |
879 | 873 |
890 | 884 |
891 static u_char * | 885 static u_char * |
892 ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c, u_char *pos, | 886 ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c, u_char *pos, |
893 u_char *end) | 887 u_char *end) |
894 { | 888 { |
895 static const u_char preface[] = "\r\nSM\r\n\r\n"; | 889 static const u_char preface[] = NGX_HTTP_V2_PREFACE_END; |
896 | 890 |
897 if ((size_t) (end - pos) < sizeof(preface) - 1) { | 891 if ((size_t) (end - pos) < sizeof(preface) - 1) { |
898 return ngx_http_v2_state_save(h2c, pos, end, | 892 return ngx_http_v2_state_save(h2c, pos, end, |
899 ngx_http_v2_state_preface_end); | 893 ngx_http_v2_state_preface_end); |
900 } | 894 } |
3941 | 3935 |
3942 static void | 3936 static void |
3943 ngx_http_v2_run_request(ngx_http_request_t *r) | 3937 ngx_http_v2_run_request(ngx_http_request_t *r) |
3944 { | 3938 { |
3945 ngx_connection_t *fc; | 3939 ngx_connection_t *fc; |
3940 ngx_http_v2_srv_conf_t *h2scf; | |
3946 ngx_http_v2_connection_t *h2c; | 3941 ngx_http_v2_connection_t *h2c; |
3947 | 3942 |
3948 fc = r->connection; | 3943 fc = r->connection; |
3944 | |
3945 h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module); | |
3946 | |
3947 if (!h2scf->enable && !r->http_connection->addr_conf->http2) { | |
3948 ngx_log_error(NGX_LOG_INFO, fc->log, 0, | |
3949 "client attempted to request the server name " | |
3950 "for which the negotiated protocol is disabled"); | |
3951 | |
3952 ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST); | |
3953 goto failed; | |
3954 } | |
3949 | 3955 |
3950 if (ngx_http_v2_construct_request_line(r) != NGX_OK) { | 3956 if (ngx_http_v2_construct_request_line(r) != NGX_OK) { |
3951 goto failed; | 3957 goto failed; |
3952 } | 3958 } |
3953 | 3959 |