~britco/nginx/master

« back to all changes in this revision

Viewing changes to modules/nginx-echo/src/ngx_http_echo_filter.c

  • Committer: Bazaar Package Importer
  • Author(s): Kartik Mistry, Kartik Mistry, Michael Lustfield
  • Date: 2010-11-27 21:04:02 UTC
  • mfrom: (1.3.8 upstream)
  • mto: This revision was merged to the branch mainline in revision 36.
  • Revision ID: james.westby@ubuntu.com-20101127210402-14sgjpe6r3jup8a9
Tags: 0.8.53-1
[Kartik Mistry]
* debian/control:
  + Added Michael Lustfield as co-maintainer
* nginx.conf:
  + No need to use regex in gzip_disable for msie6, Thanks to António P. P.
    Almeida <appa@perusio.net> (Closes: #592147)
* conf/sites-available/default:
  + Fixed typo for "include fastcgi", Thanks to Mostafa Ghadamyari
    <nginx@gigfa.com> (Closes: #593142, #593143)
* debian/patches/fix_reloading_ipv6.diff:
  + Removed, merged upstream
* debian/init.d:
  + Added fix to control nginx by user in a simple way by setting DAEMON
    variable to an invalid name in /etc/default/nginx. Patch by Toni Mueller
    <support@oeko.net> (Closes: #594598)
* debian/NEWS.Debian:
  + Updated news for 0.8.x as stable branch

[Michael Lustfield]
* New upstream release (Closes: #602970)
  + 0.8.x branch is declared stable by upstream now
* Add a UFW profile set:
  + debian/nginx.ufw.profile: Added.
  + debian/control: nginx: Suggests ufw.
  + debian/dirs: Add 'etc/ufw/applications.d'
  + debian/rules: Add install rule for the nginx UFW profile.
* Moved debian/dirs to debian/nginx.dirs
* Added types_hash_max_size to nginx.conf
* Install simple default index.html file (Closes: #581416)
  + debian/dirs: Add 'usr/share/nginx/www'.
  + debian/nginx.install: Add 'html/* usr/share/nginx/www'.
* debian/patches/nginx-echo.diff:
  + Added Echo module
* Added files for nginx.docs
  - /usr/share/doc/nginx/
    + debian/help/docs/fcgiwrap
    + debian/help/docs/php
    + debian/help/docs/support-irc
    + debian/help/docs/upstream
* Added files for nginx.examples
  - /usr/share/doc/nginx/examples/
    + debian/help/docs/drupal
    + debian/help/docs/http
    + debian/help/docs/mail
    + debian/help/docs/mailman
    + debian/help/docs/nginx.conf
    + debian/help/docs/virtual_hosts
    + debian/help/docs/wordpress
* debian/conf/:
  + Removed excess spaces
  + Added tabs where appropriate
  + Added SCRIPT_FILENAME to fastcgi_params

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#define DDEBUG 0
 
2
 
 
3
#include "ddebug.h"
 
4
#include "ngx_http_echo_filter.h"
 
5
#include "ngx_http_echo_util.h"
 
6
#include "ngx_http_echo_echo.h"
 
7
 
 
8
#include <ngx_log.h>
 
9
 
 
10
ngx_flag_t ngx_http_echo_filter_used = 0;
 
11
 
 
12
ngx_http_output_header_filter_pt ngx_http_echo_next_header_filter;
 
13
 
 
14
ngx_http_output_body_filter_pt ngx_http_echo_next_body_filter;
 
15
 
 
16
static ngx_int_t ngx_http_echo_header_filter(ngx_http_request_t *r);
 
17
 
 
18
static ngx_int_t ngx_http_echo_body_filter(ngx_http_request_t *r, ngx_chain_t *in);
 
19
 
 
20
/* filter handlers */
 
21
static ngx_int_t ngx_http_echo_exec_filter_cmds(ngx_http_request_t *r,
 
22
        ngx_http_echo_ctx_t *ctx, ngx_array_t *cmds, ngx_uint_t *iterator);
 
23
 
 
24
 
 
25
ngx_int_t
 
26
ngx_http_echo_filter_init (ngx_conf_t *cf)
 
27
{
 
28
    if (ngx_http_echo_filter_used) {
 
29
        dd("top header filter: %ld", (unsigned long) ngx_http_top_header_filter);
 
30
        ngx_http_echo_next_header_filter = ngx_http_top_header_filter;
 
31
        ngx_http_top_header_filter  = ngx_http_echo_header_filter;
 
32
 
 
33
        dd("top body filter: %ld", (unsigned long) ngx_http_top_body_filter);
 
34
        ngx_http_echo_next_body_filter = ngx_http_top_body_filter;
 
35
        ngx_http_top_body_filter  = ngx_http_echo_body_filter;
 
36
    }
 
37
 
 
38
    return NGX_OK;
 
39
}
 
40
 
 
41
 
 
42
static ngx_int_t
 
43
ngx_http_echo_header_filter(ngx_http_request_t *r)
 
44
{
 
45
    ngx_http_echo_loc_conf_t    *conf;
 
46
    ngx_http_echo_ctx_t         *ctx;
 
47
    ngx_int_t                   rc;
 
48
 
 
49
    dd("We're in the header filter...");
 
50
 
 
51
    ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);
 
52
 
 
53
    /* XXX we should add option to insert contents for responses
 
54
     * of non-200 status code here... */
 
55
    /*
 
56
    if (r->headers_out.status != NGX_HTTP_OK) {
 
57
        if (ctx != NULL) {
 
58
            ctx->skip_filter = 1;
 
59
        }
 
60
        return ngx_http_echo_next_header_filter(r);
 
61
    }
 
62
    */
 
63
 
 
64
    conf = ngx_http_get_module_loc_conf(r, ngx_http_echo_module);
 
65
    if (conf->before_body_cmds == NULL && conf->after_body_cmds == NULL) {
 
66
        if (ctx != NULL) {
 
67
            ctx->skip_filter = 1;
 
68
        }
 
69
        return ngx_http_echo_next_header_filter(r);
 
70
    }
 
71
 
 
72
    if (ctx == NULL) {
 
73
        rc = ngx_http_echo_init_ctx(r, &ctx);
 
74
        if (rc != NGX_OK) {
 
75
            return NGX_ERROR;
 
76
        }
 
77
        ctx->headers_sent = 1;
 
78
        ngx_http_set_ctx(r, ctx, ngx_http_echo_module);
 
79
    }
 
80
 
 
81
    /* enable streaming here (use chunked encoding) */
 
82
    ngx_http_clear_content_length(r);
 
83
    ngx_http_clear_accept_ranges(r);
 
84
 
 
85
    return ngx_http_echo_next_header_filter(r);
 
86
}
 
87
 
 
88
 
 
89
static ngx_int_t
 
90
ngx_http_echo_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
 
91
{
 
92
    ngx_http_echo_ctx_t         *ctx;
 
93
    ngx_int_t                    rc;
 
94
    ngx_http_echo_loc_conf_t    *conf;
 
95
    ngx_flag_t                   last;
 
96
    ngx_chain_t                 *cl;
 
97
    ngx_buf_t                   *buf;
 
98
 
 
99
    if (in == NULL || r->header_only) {
 
100
        return ngx_http_echo_next_body_filter(r, in);
 
101
    }
 
102
 
 
103
    ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);
 
104
 
 
105
    if (ctx == NULL || ctx->skip_filter) {
 
106
        return ngx_http_echo_next_body_filter(r, in);
 
107
    }
 
108
 
 
109
    conf = ngx_http_get_module_loc_conf(r, ngx_http_echo_module);
 
110
 
 
111
    if (!ctx->before_body_sent) {
 
112
        ctx->before_body_sent = 1;
 
113
 
 
114
        if (conf->before_body_cmds != NULL) {
 
115
            rc = ngx_http_echo_exec_filter_cmds(r, ctx, conf->before_body_cmds,
 
116
                    &ctx->next_before_body_cmd);
 
117
            if (rc != NGX_OK) {
 
118
                return NGX_ERROR;
 
119
            }
 
120
        }
 
121
    }
 
122
 
 
123
    if (conf->after_body_cmds == NULL) {
 
124
        ctx->skip_filter = 1;
 
125
        return ngx_http_echo_next_body_filter(r, in);
 
126
    }
 
127
 
 
128
    last = 0;
 
129
 
 
130
    for (cl = in; cl; cl = cl->next) {
 
131
        if (cl->buf->last_buf) {
 
132
            cl->buf->last_buf = 0;
 
133
            cl->buf->sync = 1;
 
134
            last = 1;
 
135
        } else if (r != r->main && cl->buf->sync) {
 
136
            dd("Found sync buf");
 
137
            last = 1;
 
138
        }
 
139
    }
 
140
 
 
141
    rc = ngx_http_echo_next_body_filter(r, in);
 
142
 
 
143
    if (rc == NGX_ERROR || !last) {
 
144
        return rc;
 
145
    }
 
146
 
 
147
    dd("exec filter cmds for after body cmds");
 
148
    rc = ngx_http_echo_exec_filter_cmds(r, ctx, conf->after_body_cmds, &ctx->next_after_body_cmd);
 
149
    if (rc != NGX_OK) {
 
150
        dd("FAILED: exec filter cmds for after body cmds");
 
151
        return NGX_ERROR;
 
152
    }
 
153
 
 
154
    ctx->skip_filter = 1;
 
155
 
 
156
    dd("after body cmds executed...terminating...");
 
157
 
 
158
    /* XXX we can NOT use
 
159
     * ngx_http_send_special(r, NGX_HTTP_LAST) here
 
160
     * because we should bypass the upstream filters. */
 
161
    if (r != r->main) {
 
162
        return NGX_OK;
 
163
    }
 
164
 
 
165
    buf = ngx_calloc_buf(r->pool);
 
166
    buf->last_buf = 1;
 
167
 
 
168
    cl = ngx_alloc_chain_link(r->pool);
 
169
    if (cl == NULL) {
 
170
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
171
    }
 
172
 
 
173
    cl->next = NULL;
 
174
    cl->buf = buf;
 
175
 
 
176
    return ngx_http_echo_next_body_filter(r, cl);
 
177
}
 
178
 
 
179
 
 
180
static ngx_int_t
 
181
ngx_http_echo_exec_filter_cmds(ngx_http_request_t *r,
 
182
        ngx_http_echo_ctx_t *ctx, ngx_array_t *cmds,
 
183
        ngx_uint_t *iterator)
 
184
{
 
185
    ngx_int_t                    rc;
 
186
    ngx_array_t                 *computed_args = NULL;
 
187
    ngx_http_echo_cmd_t         *cmd;
 
188
    ngx_http_echo_cmd_t         *cmd_elts;
 
189
    ngx_array_t                 *opts = NULL;
 
190
 
 
191
    for (cmd_elts = cmds->elts; *iterator < cmds->nelts; (*iterator)++) {
 
192
        cmd = &cmd_elts[*iterator];
 
193
 
 
194
        /* evaluate arguments for the current cmd (if any) */
 
195
        if (cmd->args) {
 
196
            computed_args = ngx_array_create(r->pool, cmd->args->nelts,
 
197
                    sizeof(ngx_str_t));
 
198
 
 
199
            if (computed_args == NULL) {
 
200
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
201
            }
 
202
 
 
203
            opts = ngx_array_create(r->pool, 1, sizeof(ngx_str_t));
 
204
 
 
205
            if (opts == NULL) {
 
206
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
207
            }
 
208
 
 
209
            rc = ngx_http_echo_eval_cmd_args(r, cmd, computed_args, opts);
 
210
 
 
211
            if (rc != NGX_OK) {
 
212
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
 
213
                        "Failed to evaluate arguments for "
 
214
                        "the directive.");
 
215
                return rc;
 
216
            }
 
217
        }
 
218
 
 
219
        /* do command dispatch based on the opcode */
 
220
        switch (cmd->opcode) {
 
221
        case echo_opcode_echo_before_body:
 
222
        case echo_opcode_echo_after_body:
 
223
            dd("exec echo_before_body or echo_after_body...");
 
224
 
 
225
            rc = ngx_http_echo_exec_echo(r, ctx, computed_args,
 
226
                    1 /* in filter */, opts);
 
227
 
 
228
            if (rc != NGX_OK) {
 
229
                return rc;
 
230
            }
 
231
 
 
232
            break;
 
233
        default:
 
234
            break;
 
235
        }
 
236
    }
 
237
 
 
238
    return NGX_OK;
 
239
}
 
240