Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

0001 
0002 /*
0003  * Copyright (C) Roman Arutyunyan
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_stream.h>
0011 
0012 
0013 typedef struct {
0014     ngx_stream_complex_value_t   text;
0015 } ngx_stream_return_srv_conf_t;
0016 
0017 
0018 typedef struct {
0019     ngx_chain_t                 *out;
0020 } ngx_stream_return_ctx_t;
0021 
0022 
0023 static void ngx_stream_return_handler(ngx_stream_session_t *s);
0024 static void ngx_stream_return_write_handler(ngx_event_t *ev);
0025 
0026 static void *ngx_stream_return_create_srv_conf(ngx_conf_t *cf);
0027 static char *ngx_stream_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
0028 
0029 
0030 static ngx_command_t  ngx_stream_return_commands[] = {
0031 
0032     { ngx_string("return"),
0033       NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0034       ngx_stream_return,
0035       NGX_STREAM_SRV_CONF_OFFSET,
0036       0,
0037       NULL },
0038 
0039       ngx_null_command
0040 };
0041 
0042 
0043 static ngx_stream_module_t  ngx_stream_return_module_ctx = {
0044     NULL,                                  /* preconfiguration */
0045     NULL,                                  /* postconfiguration */
0046 
0047     NULL,                                  /* create main configuration */
0048     NULL,                                  /* init main configuration */
0049 
0050     ngx_stream_return_create_srv_conf,     /* create server configuration */
0051     NULL                                   /* merge server configuration */
0052 };
0053 
0054 
0055 ngx_module_t  ngx_stream_return_module = {
0056     NGX_MODULE_V1,
0057     &ngx_stream_return_module_ctx,         /* module context */
0058     ngx_stream_return_commands,            /* module directives */
0059     NGX_STREAM_MODULE,                     /* module type */
0060     NULL,                                  /* init master */
0061     NULL,                                  /* init module */
0062     NULL,                                  /* init process */
0063     NULL,                                  /* init thread */
0064     NULL,                                  /* exit thread */
0065     NULL,                                  /* exit process */
0066     NULL,                                  /* exit master */
0067     NGX_MODULE_V1_PADDING
0068 };
0069 
0070 
0071 static void
0072 ngx_stream_return_handler(ngx_stream_session_t *s)
0073 {
0074     ngx_str_t                      text;
0075     ngx_buf_t                     *b;
0076     ngx_connection_t              *c;
0077     ngx_stream_return_ctx_t       *ctx;
0078     ngx_stream_return_srv_conf_t  *rscf;
0079 
0080     c = s->connection;
0081 
0082     c->log->action = "returning text";
0083 
0084     rscf = ngx_stream_get_module_srv_conf(s, ngx_stream_return_module);
0085 
0086     if (ngx_stream_complex_value(s, &rscf->text, &text) != NGX_OK) {
0087         ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0088         return;
0089     }
0090 
0091     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
0092                    "stream return text: \"%V\"", &text);
0093 
0094     if (text.len == 0) {
0095         ngx_stream_finalize_session(s, NGX_STREAM_OK);
0096         return;
0097     }
0098 
0099     ctx = ngx_pcalloc(c->pool, sizeof(ngx_stream_return_ctx_t));
0100     if (ctx == NULL) {
0101         ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0102         return;
0103     }
0104 
0105     ngx_stream_set_ctx(s, ctx, ngx_stream_return_module);
0106 
0107     b = ngx_calloc_buf(c->pool);
0108     if (b == NULL) {
0109         ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0110         return;
0111     }
0112 
0113     b->memory = 1;
0114     b->pos = text.data;
0115     b->last = text.data + text.len;
0116     b->last_buf = 1;
0117 
0118     ctx->out = ngx_alloc_chain_link(c->pool);
0119     if (ctx->out == NULL) {
0120         ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0121         return;
0122     }
0123 
0124     ctx->out->buf = b;
0125     ctx->out->next = NULL;
0126 
0127     c->write->handler = ngx_stream_return_write_handler;
0128 
0129     ngx_stream_return_write_handler(c->write);
0130 }
0131 
0132 
0133 static void
0134 ngx_stream_return_write_handler(ngx_event_t *ev)
0135 {
0136     ngx_connection_t         *c;
0137     ngx_stream_session_t     *s;
0138     ngx_stream_return_ctx_t  *ctx;
0139 
0140     c = ev->data;
0141     s = c->data;
0142 
0143     if (ev->timedout) {
0144         ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out");
0145         ngx_stream_finalize_session(s, NGX_STREAM_OK);
0146         return;
0147     }
0148 
0149     ctx = ngx_stream_get_module_ctx(s, ngx_stream_return_module);
0150 
0151     if (ngx_stream_top_filter(s, ctx->out, 1) == NGX_ERROR) {
0152         ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0153         return;
0154     }
0155 
0156     ctx->out = NULL;
0157 
0158     if (!c->buffered) {
0159         ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
0160                        "stream return done sending");
0161         ngx_stream_finalize_session(s, NGX_STREAM_OK);
0162         return;
0163     }
0164 
0165     if (ngx_handle_write_event(ev, 0) != NGX_OK) {
0166         ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0167         return;
0168     }
0169 
0170     ngx_add_timer(ev, 5000);
0171 }
0172 
0173 
0174 static void *
0175 ngx_stream_return_create_srv_conf(ngx_conf_t *cf)
0176 {
0177     ngx_stream_return_srv_conf_t  *conf;
0178 
0179     conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_return_srv_conf_t));
0180     if (conf == NULL) {
0181         return NULL;
0182     }
0183 
0184     return conf;
0185 }
0186 
0187 
0188 static char *
0189 ngx_stream_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0190 {
0191     ngx_stream_return_srv_conf_t *rscf = conf;
0192 
0193     ngx_str_t                           *value;
0194     ngx_stream_core_srv_conf_t          *cscf;
0195     ngx_stream_compile_complex_value_t   ccv;
0196 
0197     if (rscf->text.value.data) {
0198         return "is duplicate";
0199     }
0200 
0201     value = cf->args->elts;
0202 
0203     ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
0204 
0205     ccv.cf = cf;
0206     ccv.value = &value[1];
0207     ccv.complex_value = &rscf->text;
0208 
0209     if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
0210         return NGX_CONF_ERROR;
0211     }
0212 
0213     cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module);
0214 
0215     cscf->handler = ngx_stream_return_handler;
0216 
0217     return NGX_CONF_OK;
0218 }