~ubuntu-branches/ubuntu/precise/nginx/precise

« back to all changes in this revision

Viewing changes to debian/modules/chunkin-nginx-module/src/ngx_http_chunkin_filter_module.c

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry, Kartik Mistry, Michael Lustfield
  • Date: 2011-11-18 23:44:00 UTC
  • mfrom: (4.2.39 sid)
  • Revision ID: package-import@ubuntu.com-20111118234400-atj8d0zog78vgdte
Tags: 1.1.8-1
[Kartik Mistry]
* New upstream release.
* debian/modules/chunkin-nginx-module:
  + Removed as of now, as it breaks with Perl 5.14 (Closes: #649061)

[Michael Lustfield]
* debian/control:
  + Added Map module to nginx-light modules list.
* debian/rules:
  + Removed --without-http_map_module form nginx-light.
* debian/nginx-common.install:
  + Changed ufw profile installation (LP: #825349).
    - debian/ufw.profile -> debian/ufw/nginx.
* debian/nginx-common.preinst:
  + Cleanup of moved nginx profile.
* debian/conf/nginx.conf:
  + Added a default map for $server_https (on|off).
* debian/conf/fastcgi_params:
  + Pass HTTPS so $_SERVER['HTTPS'] is set (LP: #857831).
* debian/conf/mime.types:
  + Added json type (LP: #883440).
* debian/conf/sites-available/default:
  + Added notes about PHP (Closes: #642995).
  + Changed location /doc from root to alias.
  + Changed location /doc to /doc/ for people that don't bother reading or
    learning anything about Nginx configuration files (LP: #840358).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) agentzh */
2
 
 
3
 
#define DDEBUG 0
4
 
#include "ddebug.h"
5
 
 
6
 
#include <ngx_config.h>
7
 
 
8
 
#include "ngx_http_chunkin_util.h"
9
 
#include "ngx_http_chunkin_filter_module.h"
10
 
#include "ngx_http_chunkin_request_body.h"
11
 
 
12
 
enum {
13
 
    DEFAULT_MAX_CHUNKS_PER_BUF = 512
14
 
};
15
 
 
16
 
static ngx_int_t ngx_http_chunkin_resume_handler(ngx_http_request_t *r);
17
 
 
18
 
static char* ngx_http_chunkin_resume(ngx_conf_t *cf, ngx_command_t *cmd,
19
 
        void *conf);
20
 
 
21
 
static void *ngx_http_chunkin_create_conf(ngx_conf_t *cf);
22
 
static char *ngx_http_chunkin_merge_conf(ngx_conf_t *cf, void *parent,
23
 
    void *child);
24
 
 
25
 
static ngx_int_t ngx_http_chunkin_handler(ngx_http_request_t *r);
26
 
 
27
 
static ngx_int_t ngx_http_chunkin_init(ngx_conf_t *cf);
28
 
 
29
 
static void ngx_http_chunkin_post_read(ngx_http_request_t *r);
30
 
 
31
 
 
32
 
static ngx_command_t  ngx_http_chunkin_commands[] = {
33
 
 
34
 
    { ngx_string("chunkin"),
35
 
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
36
 
      ngx_conf_set_flag_slot,
37
 
      NGX_HTTP_LOC_CONF_OFFSET,
38
 
      offsetof(ngx_http_chunkin_conf_t, enabled),
39
 
      NULL },
40
 
 
41
 
    { ngx_string("chunkin_max_chunks_per_buf"),
42
 
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
43
 
      ngx_conf_set_num_slot,
44
 
      NGX_HTTP_LOC_CONF_OFFSET,
45
 
      offsetof(ngx_http_chunkin_conf_t, max_chunks_per_buf),
46
 
      NULL },
47
 
 
48
 
    { ngx_string("chunkin_resume"),
49
 
      NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
50
 
      ngx_http_chunkin_resume,
51
 
      NGX_HTTP_LOC_CONF_OFFSET,
52
 
      0,
53
 
      NULL },
54
 
 
55
 
    { ngx_string("chunkin_keepalive"),
56
 
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
57
 
          |NGX_HTTP_LIF_CONF|NGX_CONF_FLAG,
58
 
      ngx_conf_set_flag_slot,
59
 
      NGX_HTTP_LOC_CONF_OFFSET,
60
 
      offsetof(ngx_http_chunkin_conf_t, keepalive),
61
 
      NULL },
62
 
 
63
 
      ngx_null_command
64
 
};
65
 
 
66
 
 
67
 
static ngx_http_module_t  ngx_http_chunkin_filter_module_ctx = {
68
 
    NULL,                                 /* preconfiguration */
69
 
    ngx_http_chunkin_init,         /* postconfiguration */
70
 
 
71
 
    NULL,                                  /* create main configuration */
72
 
    NULL,                                  /* init main configuration */
73
 
 
74
 
    NULL,                                  /* create server configuration */
75
 
    NULL,                                  /* merge server configuration */
76
 
 
77
 
    ngx_http_chunkin_create_conf,         /* create location configuration */
78
 
    ngx_http_chunkin_merge_conf           /* merge location configuration */
79
 
};
80
 
 
81
 
 
82
 
ngx_module_t  ngx_http_chunkin_filter_module = {
83
 
    NGX_MODULE_V1,
84
 
    &ngx_http_chunkin_filter_module_ctx,  /* module context */
85
 
    ngx_http_chunkin_commands,            /* module directives */
86
 
    NGX_HTTP_MODULE,                       /* module type */
87
 
    NULL,                                  /* init master */
88
 
    NULL,                                  /* init module */
89
 
    NULL,                                  /* init process */
90
 
    NULL,                                  /* init thread */
91
 
    NULL,                                  /* exit thread */
92
 
    NULL,                                  /* exit process */
93
 
    NULL,                                  /* exit master */
94
 
    NGX_MODULE_V1_PADDING
95
 
};
96
 
 
97
 
 
98
 
static void *
99
 
ngx_http_chunkin_create_conf(ngx_conf_t *cf)
100
 
{
101
 
    ngx_http_chunkin_conf_t  *conf;
102
 
 
103
 
    conf = ngx_palloc(cf->pool, sizeof(ngx_http_chunkin_conf_t));
104
 
    if (conf == NULL) {
105
 
        return NULL;
106
 
    }
107
 
 
108
 
    conf->enabled = NGX_CONF_UNSET;
109
 
    conf->keepalive = NGX_CONF_UNSET;
110
 
    conf->max_chunks_per_buf = NGX_CONF_UNSET_UINT;
111
 
 
112
 
    return conf;
113
 
}
114
 
 
115
 
 
116
 
static char *
117
 
ngx_http_chunkin_merge_conf(ngx_conf_t *cf, void *parent, void *child)
118
 
{
119
 
    ngx_http_chunkin_conf_t *prev = parent;
120
 
    ngx_http_chunkin_conf_t *conf = child;
121
 
 
122
 
    ngx_conf_merge_value(conf->enabled, prev->enabled, 0);
123
 
    ngx_conf_merge_value(conf->keepalive, prev->keepalive, 0);
124
 
    ngx_conf_merge_uint_value(conf->max_chunks_per_buf,
125
 
            prev->max_chunks_per_buf,
126
 
            DEFAULT_MAX_CHUNKS_PER_BUF);
127
 
 
128
 
    return NGX_CONF_OK;
129
 
}
130
 
 
131
 
 
132
 
static ngx_flag_t
133
 
ngx_http_chunkin_is_chunked_encoding(ngx_http_request_t *r)
134
 
{
135
 
    dd("is chunked encoding...");
136
 
 
137
 
    return r->headers_in.transfer_encoding &&
138
 
        r->headers_in.transfer_encoding->value.len >= 7 &&
139
 
        ngx_strcasestrn(r->headers_in.transfer_encoding->value.data,
140
 
                "chunked", 7 - 1);
141
 
}
142
 
 
143
 
 
144
 
static ngx_int_t
145
 
ngx_http_chunkin_init(ngx_conf_t *cf)
146
 
{
147
 
    ngx_http_handler_pt        *h;
148
 
    ngx_http_core_main_conf_t  *cmcf;
149
 
 
150
 
    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
151
 
 
152
 
    h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
153
 
    if (h == NULL) {
154
 
        return NGX_ERROR;
155
 
    }
156
 
 
157
 
    *h = ngx_http_chunkin_handler;
158
 
 
159
 
    return NGX_OK;
160
 
}
161
 
 
162
 
 
163
 
static ngx_int_t
164
 
ngx_http_chunkin_handler(ngx_http_request_t *r)
165
 
{
166
 
    ngx_http_chunkin_ctx_t      *ctx;
167
 
    ngx_http_chunkin_conf_t     *conf;
168
 
    ngx_int_t                   rc;
169
 
 
170
 
    dd("entered chunkin handler...");
171
 
 
172
 
    conf = ngx_http_get_module_loc_conf(r, ngx_http_chunkin_filter_module);
173
 
 
174
 
    if (!conf->enabled || r != r->main) {
175
 
        dd("conf not enabled: %d", (int) conf->enabled);
176
 
 
177
 
        return NGX_DECLINED;
178
 
    }
179
 
 
180
 
    ctx = ngx_http_get_module_ctx(r, ngx_http_chunkin_filter_module);
181
 
 
182
 
    if (ctx == NULL) {
183
 
        dd("ctx not found");
184
 
 
185
 
        return NGX_DECLINED;
186
 
    }
187
 
 
188
 
    if (ctx->done) {
189
 
        return NGX_DECLINED;
190
 
    }
191
 
 
192
 
    if (ctx->waiting_more_body) {
193
 
        return NGX_AGAIN;
194
 
    }
195
 
 
196
 
    dd("reading chunked input eagerly...");
197
 
 
198
 
    /* XXX this is a hack for now */
199
 
 
200
 
    if (conf->keepalive
201
 
            && r->headers_in.connection_type ==
202
 
                NGX_HTTP_CONNECTION_KEEP_ALIVE) {
203
 
        dd("re-enable r->keepalive...");
204
 
        r->keepalive = 1;
205
 
    } else {
206
 
        r->keepalive = 0;
207
 
    }
208
 
 
209
 
    dd_check_read_event_handler(r);
210
 
    dd_check_write_event_handler(r);
211
 
 
212
 
    /*
213
 
    rc = ngx_http_read_client_request_body(r,
214
 
            ngx_http_chunkin_post_read);
215
 
    */
216
 
 
217
 
    ngx_http_chunkin_clear_transfer_encoding(r);
218
 
 
219
 
    r->header_in->pos = r->header_end + sizeof(CRLF) - 1;
220
 
 
221
 
    if (r->header_in->pos > r->header_in->last) {
222
 
        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
223
 
                      "chunkin: r->header_in->pos overflown");
224
 
 
225
 
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
226
 
    }
227
 
 
228
 
    if (*(r->header_in->pos - 2) != CR || *(r->header_in->pos - 1) != LF) {
229
 
        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
230
 
                      "chunkin: r->header_in->pos not lead by CRLF");
231
 
 
232
 
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
233
 
    }
234
 
 
235
 
    dd("chunkin handler: header_in->pos: %d", (int)(r->header_in->pos - r->header_in->start));
236
 
 
237
 
    rc = ngx_http_chunkin_read_chunked_request_body(r,
238
 
            ngx_http_chunkin_post_read);
239
 
 
240
 
    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
241
 
        dd("read client request body returned special response %d", (int) rc);
242
 
        return rc;
243
 
    }
244
 
 
245
 
    dd("read client request body returned %d", (int) rc);
246
 
 
247
 
    if (rc == NGX_AGAIN) {
248
 
        ctx->waiting_more_body = 1;
249
 
 
250
 
        return NGX_AGAIN;
251
 
    }
252
 
 
253
 
    ctx->done = 1;
254
 
 
255
 
    return NGX_DECLINED;
256
 
}
257
 
 
258
 
 
259
 
static void
260
 
ngx_http_chunkin_post_read(ngx_http_request_t *r)
261
 
{
262
 
    ngx_http_chunkin_ctx_t          *ctx;
263
 
 
264
 
    dd("post read");
265
 
 
266
 
    dd_check_read_event_handler(r);
267
 
    dd_check_write_event_handler(r);
268
 
 
269
 
    r->read_event_handler = ngx_http_block_reading;
270
 
 
271
 
    ctx = ngx_http_get_module_ctx(r, ngx_http_chunkin_filter_module);
272
 
 
273
 
    ctx->done = 1;
274
 
 
275
 
    if (ctx->waiting_more_body) {
276
 
        ctx->waiting_more_body = 0;
277
 
        ngx_http_core_run_phases(r);
278
 
    }
279
 
}
280
 
 
281
 
 
282
 
static char* ngx_http_chunkin_resume(ngx_conf_t *cf, ngx_command_t *cmd,
283
 
        void *conf)
284
 
{
285
 
    ngx_http_core_loc_conf_t        *clcf;
286
 
 
287
 
    clcf = ngx_http_conf_get_module_loc_conf(cf,
288
 
                ngx_http_core_module);
289
 
 
290
 
    clcf->handler = ngx_http_chunkin_resume_handler;
291
 
 
292
 
    return NGX_CONF_OK;
293
 
}
294
 
 
295
 
 
296
 
static ngx_int_t
297
 
ngx_http_chunkin_resume_handler(ngx_http_request_t *r) {
298
 
    ngx_int_t                   rc;
299
 
    ngx_http_chunkin_conf_t     *conf;
300
 
    ngx_http_chunkin_ctx_t      *ctx;
301
 
 
302
 
    conf = ngx_http_get_module_loc_conf(r, ngx_http_chunkin_filter_module);
303
 
 
304
 
    dd("method: %.*s (%d)", (int) r->method_name.len, r->method_name.data, (int) r->method);
305
 
 
306
 
    if (!conf->enabled || r != r->main
307
 
            || (r->method != NGX_HTTP_PUT && r->method != NGX_HTTP_POST &&
308
 
                r->method != NGX_HTTP_DELETE))
309
 
    {
310
 
        dd("conf not enabled or in subrequest or not POST nor PUT requests");
311
 
 
312
 
        return NGX_HTTP_LENGTH_REQUIRED;
313
 
    }
314
 
 
315
 
    if (r->method == NGX_HTTP_POST &&
316
 
                ! ngx_http_chunkin_is_chunked_encoding(r->main))
317
 
    {
318
 
        dd("found POST request, but not chunked");
319
 
        return NGX_HTTP_LENGTH_REQUIRED;
320
 
    }
321
 
 
322
 
    dd("chunked request test passed");
323
 
 
324
 
    /* XXX just to fool the nginx core */
325
 
    r->headers_in.content_length_n = 1;
326
 
 
327
 
    ngx_http_chunkin_clear_transfer_encoding(r);
328
 
 
329
 
    ctx = ngx_http_get_module_ctx(r, ngx_http_chunkin_filter_module);
330
 
 
331
 
    if (ctx == NULL) {
332
 
        ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_chunkin_ctx_t));
333
 
        if (ctx == NULL) {
334
 
            return NGX_ERROR;
335
 
        }
336
 
 
337
 
        /* ctx->ignore_body is set to 0 */
338
 
    }
339
 
 
340
 
    r->discard_body = 0;
341
 
    r->error_page = 0;
342
 
    r->err_status = 0;
343
 
 
344
 
#if 0
345
 
    r->method = NGX_HTTP_PUT;
346
 
    r->headers_in.content_length = NULL;
347
 
    r->headers_in.content_length_n = -1;
348
 
#endif
349
 
 
350
 
    rc = ngx_http_chunkin_process_request_header(r);
351
 
    if (rc != NGX_OK) {
352
 
        return rc;
353
 
    }
354
 
 
355
 
#if 0
356
 
    r->plain_http = 1;
357
 
#endif
358
 
 
359
 
    rc = ngx_http_chunkin_process_request(r);
360
 
    if (rc != NGX_OK) {
361
 
        return rc;
362
 
    }
363
 
 
364
 
    return ngx_http_chunkin_internal_redirect(r, &r->main->uri, &r->main->args,
365
 
            ctx);
366
 
}
367