4
#include "ngx_http_echo_echo.h"
5
#include "ngx_http_echo_util.h"
6
#include "ngx_http_echo_filter.h"
10
static ngx_buf_t ngx_http_echo_space_buf;
12
static ngx_buf_t ngx_http_echo_newline_buf;
15
ngx_http_echo_echo_init(ngx_conf_t *cf)
17
static u_char space_str[] = " ";
18
static u_char newline_str[] = "\n";
22
ngx_memzero(&ngx_http_echo_space_buf, sizeof(ngx_buf_t));
23
ngx_http_echo_space_buf.memory = 1;
24
ngx_http_echo_space_buf.start =
25
ngx_http_echo_space_buf.pos =
27
ngx_http_echo_space_buf.end =
28
ngx_http_echo_space_buf.last =
29
space_str + sizeof(space_str) - 1;
31
ngx_memzero(&ngx_http_echo_newline_buf, sizeof(ngx_buf_t));
32
ngx_http_echo_newline_buf.memory = 1;
33
ngx_http_echo_newline_buf.start =
34
ngx_http_echo_newline_buf.pos =
36
ngx_http_echo_newline_buf.end =
37
ngx_http_echo_newline_buf.last =
38
newline_str + sizeof(newline_str) - 1;
45
ngx_http_echo_exec_echo(ngx_http_request_t *r,
46
ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args,
47
ngx_flag_t in_filter, ngx_array_t *opts)
52
ngx_buf_t *newline_buf;
55
ngx_str_t *computed_arg;
56
ngx_str_t *computed_arg_elts;
59
ngx_chain_t *cl = NULL; /* the head of the chain link */
60
ngx_chain_t **ll = &cl; /* always point to the address of the last link */
65
if (computed_args == NULL) {
66
return NGX_HTTP_INTERNAL_SERVER_ERROR;
69
computed_arg_elts = computed_args->elts;
70
for (i = 0; i < computed_args->nelts; i++) {
71
computed_arg = &computed_arg_elts[i];
73
if (computed_arg->len == 0) {
77
buf = ngx_calloc_buf(r->pool);
79
return NGX_HTTP_INTERNAL_SERVER_ERROR;
82
buf->start = buf->pos = computed_arg->data;
83
buf->last = buf->end = computed_arg->data +
90
cl = ngx_alloc_chain_link(r->pool);
92
return NGX_HTTP_INTERNAL_SERVER_ERROR;
98
/* append a space first */
99
*ll = ngx_alloc_chain_link(r->pool);
102
return NGX_HTTP_INTERNAL_SERVER_ERROR;
105
space_buf = ngx_calloc_buf(r->pool);
107
if (space_buf == NULL) {
108
return NGX_HTTP_INTERNAL_SERVER_ERROR;
111
/* nginx clears buf flags at the end of each request handling,
112
* so we have to make a clone here. */
113
*space_buf = ngx_http_echo_space_buf;
115
(*ll)->buf = space_buf;
120
/* then append the buf only if it's non-empty */
122
*ll = ngx_alloc_chain_link(r->pool);
124
return NGX_HTTP_INTERNAL_SERVER_ERROR;
134
if (opts && opts->nelts > 0) {
136
if (opt[0].len == 1 && opt[0].data[0] == 'n') {
141
/* append the newline character */
143
if (cl && cl->buf == NULL) {
147
newline_buf = ngx_calloc_buf(r->pool);
149
if (newline_buf == NULL) {
150
return NGX_HTTP_INTERNAL_SERVER_ERROR;
153
*newline_buf = ngx_http_echo_newline_buf;
156
cl = ngx_alloc_chain_link(r->pool);
159
return NGX_HTTP_INTERNAL_SERVER_ERROR;
162
cl->buf = newline_buf;
164
/* ll = &cl->next; */
167
*ll = ngx_alloc_chain_link(r->pool);
170
return NGX_HTTP_INTERNAL_SERVER_ERROR;
173
(*ll)->buf = newline_buf;
175
/* ll = &(*ll)->next; */
180
if (cl == NULL || cl->buf == NULL) {
185
return ngx_http_echo_next_body_filter(r, cl);
188
return ngx_http_echo_send_chain_link(r, ctx, cl);
193
ngx_http_echo_exec_echo_flush(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx)
195
return ngx_http_send_special(r, NGX_HTTP_FLUSH);
200
ngx_http_echo_exec_echo_request_body(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx)
202
if (r->request_body && r->request_body->bufs) {
203
return ngx_http_echo_send_chain_link(r, ctx, r->request_body->bufs);
211
ngx_http_echo_exec_echo_duplicate(ngx_http_request_t *r,
212
ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args)
214
ngx_str_t *computed_arg;
215
ngx_str_t *computed_arg_elts;
227
computed_arg_elts = computed_args->elts;
229
computed_arg = &computed_arg_elts[0];
231
count = ngx_http_echo_atosz(computed_arg->data, computed_arg->len);
233
if (count == NGX_ERROR) {
234
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
235
"invalid size specified: \"%V\"", computed_arg);
237
return NGX_HTTP_INTERNAL_SERVER_ERROR;
240
str = &computed_arg_elts[1];
242
if (count == 0 || str->len == 0) {
243
rc = ngx_http_echo_send_header_if_needed(r, ctx);
244
if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
250
buf = ngx_create_temp_buf(r->pool, count * str->len);
252
return NGX_HTTP_INTERNAL_SERVER_ERROR;
256
for (i = 0; i < count; i++) {
257
p = ngx_copy(p, str->data, str->len);
261
cl = ngx_alloc_chain_link(r->pool);
263
return NGX_HTTP_INTERNAL_SERVER_ERROR;
268
return ngx_http_echo_send_chain_link(r, ctx, cl);