Mercurial > hg > nginx
comparison src/http/modules/ngx_http_grpc_module.c @ 7234:c693daca57f7
gRPC: special handling of the TE request header.
According to the gRPC protocol specification, the "TE" header is used
to detect incompatible proxies, and at least grpc-c server rejects
requests without "TE: trailers".
To preserve the logic, we have to pass "TE: trailers" to the backend if
and only if the original request contains "trailers" in the "TE" header.
Note that no other TE values are allowed in HTTP/2, so we have to remove
anything else.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sat, 17 Mar 2018 23:04:25 +0300 |
parents | 2713b2dbf5bb |
children | c2a0a838c40f |
comparison
equal
deleted
inserted
replaced
7233:2713b2dbf5bb | 7234:c693daca57f7 |
---|---|
174 | 174 |
175 static void ngx_http_grpc_abort_request(ngx_http_request_t *r); | 175 static void ngx_http_grpc_abort_request(ngx_http_request_t *r); |
176 static void ngx_http_grpc_finalize_request(ngx_http_request_t *r, | 176 static void ngx_http_grpc_finalize_request(ngx_http_request_t *r, |
177 ngx_int_t rc); | 177 ngx_int_t rc); |
178 | 178 |
179 static ngx_int_t ngx_http_grpc_internal_trailers_variable( | |
180 ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); | |
181 | |
182 static ngx_int_t ngx_http_grpc_add_variables(ngx_conf_t *cf); | |
179 static void *ngx_http_grpc_create_loc_conf(ngx_conf_t *cf); | 183 static void *ngx_http_grpc_create_loc_conf(ngx_conf_t *cf); |
180 static char *ngx_http_grpc_merge_loc_conf(ngx_conf_t *cf, | 184 static char *ngx_http_grpc_merge_loc_conf(ngx_conf_t *cf, |
181 void *parent, void *child); | 185 void *parent, void *child); |
182 static ngx_int_t ngx_http_grpc_init_headers(ngx_conf_t *cf, | 186 static ngx_int_t ngx_http_grpc_init_headers(ngx_conf_t *cf, |
183 ngx_http_grpc_loc_conf_t *conf, ngx_http_grpc_headers_t *headers, | 187 ngx_http_grpc_loc_conf_t *conf, ngx_http_grpc_headers_t *headers, |
417 ngx_null_command | 421 ngx_null_command |
418 }; | 422 }; |
419 | 423 |
420 | 424 |
421 static ngx_http_module_t ngx_http_grpc_module_ctx = { | 425 static ngx_http_module_t ngx_http_grpc_module_ctx = { |
422 NULL, /* preconfiguration */ | 426 ngx_http_grpc_add_variables, /* preconfiguration */ |
423 NULL, /* postconfiguration */ | 427 NULL, /* postconfiguration */ |
424 | 428 |
425 NULL, /* create main configuration */ | 429 NULL, /* create main configuration */ |
426 NULL, /* init main configuration */ | 430 NULL, /* init main configuration */ |
427 | 431 |
461 "\x7f\xff\x00\x00"; | 465 "\x7f\xff\x00\x00"; |
462 | 466 |
463 | 467 |
464 static ngx_keyval_t ngx_http_grpc_headers[] = { | 468 static ngx_keyval_t ngx_http_grpc_headers[] = { |
465 { ngx_string("Content-Length"), ngx_string("$content_length") }, | 469 { ngx_string("Content-Length"), ngx_string("$content_length") }, |
470 { ngx_string("TE"), ngx_string("$grpc_internal_trailers") }, | |
466 { ngx_string("Host"), ngx_string("") }, | 471 { ngx_string("Host"), ngx_string("") }, |
467 { ngx_string("Connection"), ngx_string("") }, | 472 { ngx_string("Connection"), ngx_string("") }, |
468 { ngx_string("Transfer-Encoding"), ngx_string("") }, | 473 { ngx_string("Transfer-Encoding"), ngx_string("") }, |
469 { ngx_string("TE"), ngx_string("") }, | |
470 { ngx_string("Keep-Alive"), ngx_string("") }, | 474 { ngx_string("Keep-Alive"), ngx_string("") }, |
471 { ngx_string("Expect"), ngx_string("") }, | 475 { ngx_string("Expect"), ngx_string("") }, |
472 { ngx_string("Upgrade"), ngx_string("") }, | 476 { ngx_string("Upgrade"), ngx_string("") }, |
473 { ngx_null_string, ngx_null_string } | 477 { ngx_null_string, ngx_null_string } |
474 }; | 478 }; |
481 ngx_string("X-Accel-Redirect"), | 485 ngx_string("X-Accel-Redirect"), |
482 ngx_string("X-Accel-Limit-Rate"), | 486 ngx_string("X-Accel-Limit-Rate"), |
483 ngx_string("X-Accel-Buffering"), | 487 ngx_string("X-Accel-Buffering"), |
484 ngx_string("X-Accel-Charset"), | 488 ngx_string("X-Accel-Charset"), |
485 ngx_null_string | 489 ngx_null_string |
490 }; | |
491 | |
492 | |
493 static ngx_http_variable_t ngx_http_grpc_vars[] = { | |
494 | |
495 { ngx_string("grpc_internal_trailers"), NULL, | |
496 ngx_http_grpc_internal_trailers_variable, 0, | |
497 NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, | |
498 | |
499 ngx_http_null_variable | |
486 }; | 500 }; |
487 | 501 |
488 | 502 |
489 static ngx_int_t | 503 static ngx_int_t |
490 ngx_http_grpc_handler(ngx_http_request_t *r) | 504 ngx_http_grpc_handler(ngx_http_request_t *r) |
3994 "finalize grpc request"); | 4008 "finalize grpc request"); |
3995 return; | 4009 return; |
3996 } | 4010 } |
3997 | 4011 |
3998 | 4012 |
4013 static ngx_int_t | |
4014 ngx_http_grpc_internal_trailers_variable(ngx_http_request_t *r, | |
4015 ngx_http_variable_value_t *v, uintptr_t data) | |
4016 { | |
4017 ngx_table_elt_t *te; | |
4018 | |
4019 te = r->headers_in.te; | |
4020 | |
4021 if (te == NULL) { | |
4022 v->not_found = 1; | |
4023 return NGX_OK; | |
4024 } | |
4025 | |
4026 if (ngx_strlcasestrn(te->value.data, te->value.data + te->value.len, | |
4027 (u_char *) "trailers", 8 - 1) | |
4028 == NULL) | |
4029 { | |
4030 v->not_found = 1; | |
4031 return NGX_OK; | |
4032 } | |
4033 | |
4034 v->valid = 1; | |
4035 v->no_cacheable = 0; | |
4036 v->not_found = 0; | |
4037 | |
4038 v->data = (u_char *) "trailers"; | |
4039 v->len = sizeof("trailers") - 1; | |
4040 | |
4041 return NGX_OK; | |
4042 } | |
4043 | |
4044 | |
4045 static ngx_int_t | |
4046 ngx_http_grpc_add_variables(ngx_conf_t *cf) | |
4047 { | |
4048 ngx_http_variable_t *var, *v; | |
4049 | |
4050 for (v = ngx_http_grpc_vars; v->name.len; v++) { | |
4051 var = ngx_http_add_variable(cf, &v->name, v->flags); | |
4052 if (var == NULL) { | |
4053 return NGX_ERROR; | |
4054 } | |
4055 | |
4056 var->get_handler = v->get_handler; | |
4057 var->data = v->data; | |
4058 } | |
4059 | |
4060 return NGX_OK; | |
4061 } | |
4062 | |
4063 | |
3999 static void * | 4064 static void * |
4000 ngx_http_grpc_create_loc_conf(ngx_conf_t *cf) | 4065 ngx_http_grpc_create_loc_conf(ngx_conf_t *cf) |
4001 { | 4066 { |
4002 ngx_http_grpc_loc_conf_t *conf; | 4067 ngx_http_grpc_loc_conf_t *conf; |
4003 | 4068 |