Klaus Demo nginx / a7c6f8c
Stream: return module. Roman Arutyunyan 4 years ago
3 changed file(s) with 218 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
10271027 . auto/module
10281028 fi
10291029
1030 if [ $STREAM_RETURN = YES ]; then
1031 ngx_module_name=ngx_stream_return_module
1032 ngx_module_deps=
1033 ngx_module_srcs=src/stream/ngx_stream_return_module.c
1034
1035 . auto/module
1036 fi
1037
10301038 if [ $STREAM_UPSTREAM_HASH = YES ]; then
10311039 ngx_module_name=ngx_stream_upstream_hash_module
10321040 ngx_module_deps=
117117 STREAM_LIMIT_CONN=YES
118118 STREAM_ACCESS=YES
119119 STREAM_MAP=YES
120 STREAM_RETURN=YES
120121 STREAM_UPSTREAM_HASH=YES
121122 STREAM_UPSTREAM_LEAST_CONN=YES
122123 STREAM_UPSTREAM_ZONE=YES
295296 STREAM_LIMIT_CONN=NO ;;
296297 --without-stream_access_module) STREAM_ACCESS=NO ;;
297298 --without-stream_map_module) STREAM_MAP=NO ;;
299 --without-stream_return_module) STREAM_RETURN=NO ;;
298300 --without-stream_upstream_hash_module)
299301 STREAM_UPSTREAM_HASH=NO ;;
300302 --without-stream_upstream_least_conn_module)
494496 --without-stream_limit_conn_module disable ngx_stream_limit_conn_module
495497 --without-stream_access_module disable ngx_stream_access_module
496498 --without-stream_map_module disable ngx_stream_map_module
499 --without-stream_return_module disable ngx_stream_return_module
497500 --without-stream_upstream_hash_module
498501 disable ngx_stream_upstream_hash_module
499502 --without-stream_upstream_least_conn_module
0
1 /*
2 * Copyright (C) Roman Arutyunyan
3 * Copyright (C) Nginx, Inc.
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_stream.h>
10
11
12 typedef struct {
13 ngx_stream_complex_value_t text;
14 } ngx_stream_return_srv_conf_t;
15
16
17 typedef struct {
18 ngx_buf_t buf;
19 } ngx_stream_return_ctx_t;
20
21
22 static void ngx_stream_return_handler(ngx_stream_session_t *s);
23 static void ngx_stream_return_write_handler(ngx_event_t *ev);
24
25 static void *ngx_stream_return_create_srv_conf(ngx_conf_t *cf);
26 static char *ngx_stream_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
27
28
29 static ngx_command_t ngx_stream_return_commands[] = {
30
31 { ngx_string("return"),
32 NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
33 ngx_stream_return,
34 NGX_STREAM_SRV_CONF_OFFSET,
35 0,
36 NULL },
37
38 ngx_null_command
39 };
40
41
42 static ngx_stream_module_t ngx_stream_return_module_ctx = {
43 NULL, /* preconfiguration */
44 NULL, /* postconfiguration */
45
46 NULL, /* create main configuration */
47 NULL, /* init main configuration */
48
49 ngx_stream_return_create_srv_conf, /* create server configuration */
50 NULL, /* merge server configuration */
51 };
52
53
54 ngx_module_t ngx_stream_return_module = {
55 NGX_MODULE_V1,
56 &ngx_stream_return_module_ctx, /* module context */
57 ngx_stream_return_commands, /* module directives */
58 NGX_STREAM_MODULE, /* module type */
59 NULL, /* init master */
60 NULL, /* init module */
61 NULL, /* init process */
62 NULL, /* init thread */
63 NULL, /* exit thread */
64 NULL, /* exit process */
65 NULL, /* exit master */
66 NGX_MODULE_V1_PADDING
67 };
68
69
70 static void
71 ngx_stream_return_handler(ngx_stream_session_t *s)
72 {
73 ngx_str_t text;
74 ngx_connection_t *c;
75 ngx_stream_return_ctx_t *ctx;
76 ngx_stream_return_srv_conf_t *rscf;
77
78 c = s->connection;
79
80 c->log->action = "returning text";
81
82 rscf = ngx_stream_get_module_srv_conf(s, ngx_stream_return_module);
83
84 if (ngx_stream_complex_value(s, &rscf->text, &text) != NGX_OK) {
85 ngx_stream_close_connection(c);
86 return;
87 }
88
89 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
90 "stream return text: \"%V\"", &text);
91
92 if (text.len == 0) {
93 ngx_stream_close_connection(c);
94 return;
95 }
96
97 ctx = ngx_pcalloc(c->pool, sizeof(ngx_stream_return_ctx_t));
98 if (ctx == NULL) {
99 ngx_stream_close_connection(c);
100 return;
101 }
102
103 ngx_stream_set_ctx(s, ctx, ngx_stream_return_module);
104
105 ctx->buf.pos = text.data;
106 ctx->buf.last = text.data + text.len;
107
108 c->write->handler = ngx_stream_return_write_handler;
109
110 ngx_stream_return_write_handler(c->write);
111 }
112
113
114 static void
115 ngx_stream_return_write_handler(ngx_event_t *ev)
116 {
117 ssize_t n;
118 ngx_buf_t *b;
119 ngx_connection_t *c;
120 ngx_stream_session_t *s;
121 ngx_stream_return_ctx_t *ctx;
122
123 c = ev->data;
124 s = c->data;
125
126 if (ev->timedout) {
127 ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out");
128 ngx_stream_close_connection(c);
129 return;
130 }
131
132 if (ev->ready) {
133 ctx = ngx_stream_get_module_ctx(s, ngx_stream_return_module);
134
135 b = &ctx->buf;
136
137 n = c->send(c, b->pos, b->last - b->pos);
138 if (n == NGX_ERROR) {
139 ngx_stream_close_connection(c);
140 return;
141 }
142
143 if (n > 0) {
144 b->pos += n;
145
146 if (b->pos == b->last) {
147 ngx_stream_close_connection(c);
148 return;
149 }
150 }
151 }
152
153 if (ngx_handle_write_event(ev, 0) != NGX_OK) {
154 ngx_stream_close_connection(c);
155 return;
156 }
157
158 ngx_add_timer(ev, 5000);
159 }
160
161
162 static void *
163 ngx_stream_return_create_srv_conf(ngx_conf_t *cf)
164 {
165 ngx_stream_return_srv_conf_t *conf;
166
167 conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_return_srv_conf_t));
168 if (conf == NULL) {
169 return NULL;
170 }
171
172 return conf;
173 }
174
175
176 static char *
177 ngx_stream_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
178 {
179 ngx_stream_return_srv_conf_t *rscf = conf;
180
181 ngx_str_t *value;
182 ngx_stream_core_srv_conf_t *cscf;
183 ngx_stream_compile_complex_value_t ccv;
184
185 if (rscf->text.value.data) {
186 return "is duplicate";
187 }
188
189 value = cf->args->elts;
190
191 ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
192
193 ccv.cf = cf;
194 ccv.value = &value[1];
195 ccv.complex_value = &rscf->text;
196
197 if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
198 return NGX_CONF_ERROR;
199 }
200
201 cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module);
202
203 cscf->handler = ngx_stream_return_handler;
204
205 return NGX_CONF_OK;
206 }