字号
1 相关配置
return模块配置指令如下:
详细用法参考nginx官方文档
2 源码解析
2.1 首先看看指令解析函数,这个函数的主要功能就是把return指令后面的文本以nginx变量的形式保存,绑定此阶段的处理函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| static char * ngx_stream_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_stream_return_srv_conf_t *rscf = conf;
ngx_str_t *value; ngx_stream_core_srv_conf_t *cscf; ngx_stream_compile_complex_value_t ccv;
if (rscf->text.value.data) { return "is duplicate"; }
value = cf->args->elts;
ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
ccv.cf = cf; ccv.value = &value[1]; ccv.complex_value = &rscf->text;
if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) { return NGX_CONF_ERROR; }
cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module);
cscf->handler = ngx_stream_return_handler;
return NGX_CONF_OK; }
|
2.2 在上一步设置好处理函数后,nginx运行到此阶段就会调用ngx_stream_return_handler函数,并给客户端响应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| static void ngx_stream_return_handler(ngx_stream_session_t *s) { ngx_str_t text; ngx_buf_t *b; ngx_connection_t *c; ngx_stream_return_ctx_t *ctx; ngx_stream_return_srv_conf_t *rscf;
c = s->connection;
c->log->action = "returning text";
rscf = ngx_stream_get_module_srv_conf(s, ngx_stream_return_module);
if (ngx_stream_complex_value(s, &rscf->text, &text) != NGX_OK) { ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); return; }
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "stream return text: \"%V\"", &text);
if (text.len == 0) { ngx_stream_finalize_session(s, NGX_STREAM_OK); return; }
ctx = ngx_pcalloc(c->pool, sizeof(ngx_stream_return_ctx_t)); if (ctx == NULL) { ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); return; }
ngx_stream_set_ctx(s, ctx, ngx_stream_return_module);
b = ngx_calloc_buf(c->pool); if (b == NULL) { ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); return; }
b->memory = 1; b->pos = text.data; b->last = text.data + text.len; b->last_buf = 1;
ctx->out = ngx_alloc_chain_link(c->pool); if (ctx->out == NULL) { ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); return; }
ctx->out->buf = b; ctx->out->next = NULL;
c->write->handler = ngx_stream_return_write_handler;
ngx_stream_return_write_handler(c->write); }
|
ngx_stream_return_handler函数首先解析出return指令后面的字符串值,然后为当前模块的ngx_stream_return_ctx_t申请内存,主要用来挂载发送数据的chain,再为发送数据的chain以及buf申请内存,设置写事件的handler,最后发送响应到客户端。
3 总结
return模块属于stream模块,在stream模块中处于第4阶段,所以需要绑定handler函数,将return指令后的变量或者纯文本响应给客户端。
记录 Nginx、Linux 与性能分析的学习笔记。