mirror of
https://github.com/nginx/nginx.git
synced 2024-12-19 05:33:52 -06:00
gRPC: variables support in the "grpc_pass" directive.
This commit is contained in:
parent
60f648f035
commit
0e3b3b5735
@ -27,6 +27,9 @@ typedef struct {
|
||||
ngx_str_t host;
|
||||
ngx_uint_t host_set;
|
||||
|
||||
ngx_array_t *grpc_lengths;
|
||||
ngx_array_t *grpc_values;
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
ngx_uint_t ssl;
|
||||
ngx_uint_t ssl_protocols;
|
||||
@ -119,6 +122,8 @@ typedef struct {
|
||||
unsigned status:1;
|
||||
|
||||
ngx_http_request_t *request;
|
||||
|
||||
ngx_str_t host;
|
||||
} ngx_http_grpc_ctx_t;
|
||||
|
||||
|
||||
@ -135,6 +140,8 @@ typedef struct {
|
||||
} ngx_http_grpc_frame_t;
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_grpc_eval(ngx_http_request_t *r,
|
||||
ngx_http_grpc_ctx_t *ctx, ngx_http_grpc_loc_conf_t *glcf);
|
||||
static ngx_int_t ngx_http_grpc_create_request(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_grpc_reinit_request(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_grpc_body_output_filter(void *data, ngx_chain_t *in);
|
||||
@ -524,10 +531,22 @@ ngx_http_grpc_handler(ngx_http_request_t *r)
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_grpc_ctx_t));
|
||||
if (ctx == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ctx->request = r;
|
||||
|
||||
ngx_http_set_ctx(r, ctx, ngx_http_grpc_module);
|
||||
|
||||
glcf = ngx_http_get_module_loc_conf(r, ngx_http_grpc_module);
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
if (glcf->grpc_lengths == NULL) {
|
||||
ctx->host = glcf->host;
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
u->ssl = (glcf->upstream.ssl != NULL);
|
||||
|
||||
@ -541,6 +560,12 @@ ngx_http_grpc_handler(ngx_http_request_t *r)
|
||||
ngx_str_set(&u->schema, "grpc://");
|
||||
#endif
|
||||
|
||||
} else {
|
||||
if (ngx_http_grpc_eval(r, ctx, glcf) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
u->output.tag = (ngx_buf_tag_t) &ngx_http_grpc_module;
|
||||
|
||||
u->conf = &glcf->upstream;
|
||||
@ -551,15 +576,6 @@ ngx_http_grpc_handler(ngx_http_request_t *r)
|
||||
u->abort_request = ngx_http_grpc_abort_request;
|
||||
u->finalize_request = ngx_http_grpc_finalize_request;
|
||||
|
||||
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_grpc_ctx_t));
|
||||
if (ctx == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ctx->request = r;
|
||||
|
||||
ngx_http_set_ctx(r, ctx, ngx_http_grpc_module);
|
||||
|
||||
u->input_filter_init = ngx_http_grpc_filter_init;
|
||||
u->input_filter = ngx_http_grpc_filter;
|
||||
u->input_filter_ctx = ctx;
|
||||
@ -576,6 +592,103 @@ ngx_http_grpc_handler(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_grpc_eval(ngx_http_request_t *r, ngx_http_grpc_ctx_t *ctx,
|
||||
ngx_http_grpc_loc_conf_t *glcf)
|
||||
{
|
||||
size_t add;
|
||||
ngx_url_t url;
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
ngx_memzero(&url, sizeof(ngx_url_t));
|
||||
|
||||
if (ngx_http_script_run(r, &url.url, glcf->grpc_lengths->elts, 0,
|
||||
glcf->grpc_values->elts)
|
||||
== NULL)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (url.url.len > 7
|
||||
&& ngx_strncasecmp(url.url.data, (u_char *) "grpc://", 7) == 0)
|
||||
{
|
||||
add = 7;
|
||||
|
||||
} else if (url.url.len > 8
|
||||
&& ngx_strncasecmp(url.url.data, (u_char *) "grpcs://", 8) == 0)
|
||||
{
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
add = 8;
|
||||
r->upstream->ssl = 1;
|
||||
#else
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"grpcs protocol requires SSL support");
|
||||
return NGX_ERROR;
|
||||
#endif
|
||||
|
||||
} else {
|
||||
add = 0;
|
||||
}
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
if (add) {
|
||||
u->schema.len = add;
|
||||
u->schema.data = url.url.data;
|
||||
|
||||
url.url.data += add;
|
||||
url.url.len -= add;
|
||||
|
||||
} else {
|
||||
ngx_str_set(&u->schema, "grpc://");
|
||||
}
|
||||
|
||||
url.no_resolve = 1;
|
||||
|
||||
if (ngx_parse_url(r->pool, &url) != NGX_OK) {
|
||||
if (url.err) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"%s in upstream \"%V\"", url.err, &url.url);
|
||||
}
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
|
||||
if (u->resolved == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (url.addrs) {
|
||||
u->resolved->sockaddr = url.addrs[0].sockaddr;
|
||||
u->resolved->socklen = url.addrs[0].socklen;
|
||||
u->resolved->name = url.addrs[0].name;
|
||||
u->resolved->naddrs = 1;
|
||||
}
|
||||
|
||||
u->resolved->host = url.host;
|
||||
u->resolved->port = url.port;
|
||||
u->resolved->no_port = url.no_port;
|
||||
|
||||
if (url.family != AF_UNIX) {
|
||||
|
||||
if (url.no_port) {
|
||||
ctx->host = url.host;
|
||||
|
||||
} else {
|
||||
ctx->host.len = url.host.len + 1 + url.port_text.len;
|
||||
ctx->host.data = url.host.data;
|
||||
}
|
||||
|
||||
} else {
|
||||
ngx_str_set(&ctx->host, "localhost");
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_grpc_create_request(ngx_http_request_t *r)
|
||||
{
|
||||
@ -587,6 +700,7 @@ ngx_http_grpc_create_request(ngx_http_request_t *r)
|
||||
ngx_chain_t *cl, *body;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *header;
|
||||
ngx_http_grpc_ctx_t *ctx;
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_http_grpc_frame_t *f;
|
||||
ngx_http_script_code_pt code;
|
||||
@ -598,6 +712,8 @@ ngx_http_grpc_create_request(ngx_http_request_t *r)
|
||||
|
||||
glcf = ngx_http_get_module_loc_conf(r, ngx_http_grpc_module);
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_grpc_module);
|
||||
|
||||
len = sizeof(ngx_http_grpc_connection_start) - 1
|
||||
+ sizeof(ngx_http_grpc_frame_t); /* headers frame */
|
||||
|
||||
@ -637,10 +753,10 @@ ngx_http_grpc_create_request(ngx_http_request_t *r)
|
||||
/* :authority header */
|
||||
|
||||
if (!glcf->host_set) {
|
||||
len += 1 + NGX_HTTP_V2_INT_OCTETS + glcf->host.len;
|
||||
len += 1 + NGX_HTTP_V2_INT_OCTETS + ctx->host.len;
|
||||
|
||||
if (tmp_len < glcf->host.len) {
|
||||
tmp_len = glcf->host.len;
|
||||
if (tmp_len < ctx->host.len) {
|
||||
tmp_len = ctx->host.len;
|
||||
}
|
||||
}
|
||||
|
||||
@ -785,7 +901,7 @@ ngx_http_grpc_create_request(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
if (glcf->ssl) {
|
||||
if (u->ssl) {
|
||||
*b->last++ = ngx_http_v2_indexed(NGX_HTTP_V2_SCHEME_HTTPS_INDEX);
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
@ -846,11 +962,11 @@ ngx_http_grpc_create_request(ngx_http_request_t *r)
|
||||
|
||||
if (!glcf->host_set) {
|
||||
*b->last++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_AUTHORITY_INDEX);
|
||||
b->last = ngx_http_v2_write_value(b->last, glcf->host.data,
|
||||
glcf->host.len, tmp);
|
||||
b->last = ngx_http_v2_write_value(b->last, ctx->host.data,
|
||||
ctx->host.len, tmp);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"grpc header: \":authority: %V\"", &glcf->host);
|
||||
"grpc header: \":authority: %V\"", &ctx->host);
|
||||
}
|
||||
|
||||
ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
|
||||
@ -4319,15 +4435,23 @@ ngx_http_grpc_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
|
||||
|
||||
if (clcf->noname && conf->upstream.upstream == NULL) {
|
||||
if (clcf->noname
|
||||
&& conf->upstream.upstream == NULL && conf->grpc_lengths == NULL)
|
||||
{
|
||||
conf->upstream.upstream = prev->upstream.upstream;
|
||||
conf->host = prev->host;
|
||||
|
||||
conf->grpc_lengths = prev->grpc_lengths;
|
||||
conf->grpc_values = prev->grpc_values;
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
conf->upstream.ssl = prev->upstream.ssl;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (clcf->lmt_excpt && clcf->handler == NULL && conf->upstream.upstream) {
|
||||
if (clcf->lmt_excpt && clcf->handler == NULL
|
||||
&& (conf->upstream.upstream || conf->grpc_lengths))
|
||||
{
|
||||
clcf->handler = ngx_http_grpc_handler;
|
||||
}
|
||||
|
||||
@ -4540,15 +4664,51 @@ ngx_http_grpc_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
size_t add;
|
||||
ngx_str_t *value, *url;
|
||||
ngx_url_t u;
|
||||
ngx_uint_t n;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_script_compile_t sc;
|
||||
|
||||
if (glcf->upstream.upstream) {
|
||||
if (glcf->upstream.upstream || glcf->grpc_lengths) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
|
||||
|
||||
clcf->handler = ngx_http_grpc_handler;
|
||||
|
||||
if (clcf->name.len && clcf->name.data[clcf->name.len - 1] == '/') {
|
||||
clcf->auto_redirect = 1;
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
url = &value[1];
|
||||
|
||||
n = ngx_http_script_variables_count(url);
|
||||
|
||||
if (n) {
|
||||
|
||||
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
|
||||
|
||||
sc.cf = cf;
|
||||
sc.source = url;
|
||||
sc.lengths = &glcf->grpc_lengths;
|
||||
sc.values = &glcf->grpc_values;
|
||||
sc.variables = n;
|
||||
sc.complete_lengths = 1;
|
||||
sc.complete_values = 1;
|
||||
|
||||
if (ngx_http_script_compile(&sc) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
glcf->ssl = 1;
|
||||
#endif
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (ngx_strncasecmp(url->data, (u_char *) "grpc://", 7) == 0) {
|
||||
add = 7;
|
||||
|
||||
@ -4593,14 +4753,6 @@ ngx_http_grpc_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
ngx_str_set(&glcf->host, "localhost");
|
||||
}
|
||||
|
||||
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
|
||||
|
||||
clcf->handler = ngx_http_grpc_handler;
|
||||
|
||||
if (clcf->name.len && clcf->name.data[clcf->name.len - 1] == '/') {
|
||||
clcf->auto_redirect = 1;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user