~britco/nginx/master

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry, Kartik Mistry
  • Date: 2011-09-26 10:17:04 UTC
  • mfrom: (4.2.38 sid)
  • Revision ID: package-import@ubuntu.com-20110926101704-x8pxngiujrmkxnn3
Tags: 1.1.4-2
[Kartik Mistry]
* debian/modules:
  + Updated nginx-upload-progress module, Thanks to upstream for fixing issue
    that FTBFS nginx on kFreeBSD-* archs.
  + Updated nginx-lua module to latest upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) agentzh */
 
2
 
 
3
#define DDEBUG 0
 
4
 
 
5
#include "ddebug.h"
 
6
 
 
7
#include "ngx_http_chunkin_util.h"
 
8
 
 
9
static ngx_str_t ngx_http_chunkin_content_length_header_key =
 
10
    ngx_string("Content-Length");
 
11
 
 
12
 
 
13
void
 
14
ngx_http_chunkin_clear_transfer_encoding(ngx_http_request_t *r)
 
15
{
 
16
    if (r->headers_in.transfer_encoding) {
 
17
        r->headers_in.transfer_encoding->value.len = 0;
 
18
        r->headers_in.transfer_encoding->value.data = (u_char *) "";
 
19
        r->headers_in.transfer_encoding->hash = 0;
 
20
        r->headers_in.transfer_encoding = NULL;
 
21
    }
 
22
}
 
23
 
 
24
 
 
25
ngx_int_t
 
26
ngx_http_chunkin_set_content_length_header(ngx_http_request_t *r, size_t len) {
 
27
    ngx_table_elt_t             *h;
 
28
    ngx_list_part_t             *part;
 
29
    ngx_uint_t                  i;
 
30
 
 
31
    r->headers_in.content_length_n = len;
 
32
 
 
33
    part = &r->headers_in.headers.part;
 
34
    h = part->elts;
 
35
 
 
36
    for (i = 0; /* void */; i++) {
 
37
 
 
38
        if (i >= part->nelts) {
 
39
            if (part->next == NULL) {
 
40
                break;
 
41
            }
 
42
 
 
43
            part = part->next;
 
44
            h = part->elts;
 
45
            i = 0;
 
46
        }
 
47
 
 
48
        /*
 
49
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
50
                "header value [%V]", &h[i].value);
 
51
        dd("header value (raw): [%s]", h[i].value.data);
 
52
        */
 
53
 
 
54
        if (h[i].key.len == ngx_http_chunkin_content_length_header_key.len
 
55
                && ngx_strncasecmp(h[i].key.data,
 
56
                    ngx_http_chunkin_content_length_header_key.data,
 
57
                    h[i].key.len) == 0)
 
58
        {
 
59
            dd("Found existing content-length header.");
 
60
 
 
61
            h[i].value.data = ngx_palloc(r->pool, NGX_OFF_T_LEN);
 
62
 
 
63
            if (h[i].value.data == NULL) {
 
64
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
65
            }
 
66
 
 
67
            h[i].value.len = ngx_sprintf(h[i].value.data, "%O",
 
68
                    r->headers_in.content_length_n) - h[i].value.data;
 
69
 
 
70
            return NGX_OK;
 
71
        }
 
72
    }
 
73
 
 
74
    h = ngx_list_push(&r->headers_in.headers);
 
75
 
 
76
    if (h == NULL) {
 
77
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
78
    }
 
79
 
 
80
    h->hash = r->header_hash;
 
81
 
 
82
    h->key = ngx_http_chunkin_content_length_header_key;
 
83
 
 
84
    h->value.data = ngx_palloc(r->pool, NGX_OFF_T_LEN);
 
85
 
 
86
    if (h->value.data == NULL) {
 
87
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
88
    }
 
89
 
 
90
    h->value.len = ngx_sprintf(h->value.data, "%O",
 
91
            r->headers_in.content_length_n) - h->value.data;
 
92
 
 
93
    h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
 
94
    if (h->lowcase_key == NULL) {
 
95
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
96
    }
 
97
 
 
98
    ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
 
99
 
 
100
    r->headers_in.content_length = h;
 
101
 
 
102
    return NGX_OK;
 
103
}
 
104
 
 
105
 
 
106
ngx_chain_t *
 
107
ngx_http_chunkin_get_buf(ngx_pool_t *pool, ngx_http_chunkin_ctx_t *ctx)
 
108
{
 
109
    ngx_chain_t     *cl;
 
110
    ngx_chain_t     **ll;
 
111
    ngx_uint_t      i;
 
112
 
 
113
    cl = ctx->free_bufs;
 
114
 
 
115
    if (cl == NULL) {
 
116
        ll = &ctx->free_bufs;
 
117
        for (i = 0; i < 4; i++) {
 
118
            cl = ngx_alloc_chain_link(pool);
 
119
            if (cl == NULL) {
 
120
                return NULL;
 
121
            }
 
122
 
 
123
            cl->buf = ngx_calloc_buf(pool);
 
124
            if (cl->buf == NULL) {
 
125
                return NULL;
 
126
            }
 
127
 
 
128
            cl->next = NULL;
 
129
            *ll = cl;
 
130
            ll = &cl->next;
 
131
        }
 
132
        cl = ctx->free_bufs;
 
133
    }
 
134
 
 
135
    if (cl) {
 
136
        ctx->free_bufs = cl->next;
 
137
 
 
138
        cl->buf->shadow = NULL;
 
139
        cl->next = NULL;
 
140
 
 
141
        dd("returned free buf");
 
142
        return cl;
 
143
    }
 
144
 
 
145
    dd("allocate new buf");
 
146
 
 
147
    cl = ngx_alloc_chain_link(pool);
 
148
    if (cl == NULL) {
 
149
        return NULL;
 
150
    }
 
151
 
 
152
    cl->buf = ngx_calloc_buf(pool);
 
153
    if (cl->buf == NULL) {
 
154
        return NULL;
 
155
    }
 
156
 
 
157
    cl->next = NULL;
 
158
 
 
159
    /* cl->buf->tag = (ngx_buf_tag_t) &ngx_http_chunkin_filter_module; */
 
160
 
 
161
    return cl;
 
162
}
 
163
 
 
164
 
 
165
/* modified from the ngx_http_internal_redirect function
 
166
 * in ngx_http_core_module.c of nginx 0.8.29.
 
167
 * copyrighted by Igor Sysoev. */
 
168
ngx_int_t
 
169
ngx_http_chunkin_restart_request(ngx_http_request_t *r,
 
170
        ngx_http_chunkin_ctx_t *ctx)
 
171
{
 
172
    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
173
                   "chunkin: restart request: \"%V?%V\"",
 
174
                   &r->uri, &r->args);
 
175
 
 
176
    ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
 
177
 
 
178
    ngx_http_set_ctx(r, ctx, ngx_http_chunkin_filter_module);
 
179
 
 
180
    r->internal = 0;
 
181
    /* r->phase_handler = 0; */
 
182
 
 
183
    ngx_http_handler(r);
 
184
 
 
185
#if defined(nginx_version) && nginx_version >= 8011
 
186
 
 
187
    dd("DISCARD BODY: %d", (int)r->discard_body);
 
188
 
 
189
    if ( ! ctx->r_discard_body ) {
 
190
        r->main->count++;
 
191
    }
 
192
 
 
193
#endif
 
194
 
 
195
    return NGX_DONE;
 
196
}
 
197
 
 
198
 
 
199
/* mostly a clone of the ngx_http_process_request_header function
 
200
 * in ngx_http_request.c of nginx 0.8.29.
 
201
 * copyrighted by Igor Sysoev. */
 
202
ngx_int_t
 
203
ngx_http_chunkin_process_request_header(ngx_http_request_t *r)
 
204
{
 
205
    dd("entered process_request_header");
 
206
 
 
207
    if (r->headers_in.host == NULL && r->http_version > NGX_HTTP_VERSION_10) {
 
208
        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
 
209
                   "client sent HTTP/1.1 request without \"Host\" header");
 
210
        return NGX_HTTP_BAD_REQUEST;
 
211
    }
 
212
 
 
213
    if (r->headers_in.content_length) {
 
214
        r->headers_in.content_length_n =
 
215
                            ngx_atoof(r->headers_in.content_length->value.data,
 
216
                                      r->headers_in.content_length->value.len);
 
217
 
 
218
        if (r->headers_in.content_length_n == NGX_ERROR) {
 
219
            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
 
220
                          "client sent invalid \"Content-Length\" header");
 
221
            return NGX_HTTP_LENGTH_REQUIRED;
 
222
        }
 
223
    }
 
224
 
 
225
    dd("method: %d (%d)", (int)r->method, (int)NGX_HTTP_PUT);
 
226
    dd("content_length_n: %d (%d)", (int)r->headers_in.content_length_n, -1);
 
227
 
 
228
    if (r->method & NGX_HTTP_PUT && r->headers_in.content_length_n == -1) {
 
229
        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
 
230
                  "client sent %V method without \"Content-Length\" header",
 
231
                  &r->method_name);
 
232
        return NGX_HTTP_LENGTH_REQUIRED;
 
233
    }
 
234
 
 
235
    if (r->method & NGX_HTTP_TRACE) {
 
236
        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
 
237
                      "client sent TRACE method");
 
238
        return NGX_HTTP_NOT_ALLOWED;
 
239
    }
 
240
 
 
241
    if (r->headers_in.transfer_encoding
 
242
        && ngx_strcasestrn(r->headers_in.transfer_encoding->value.data,
 
243
                           "chunked", 7 - 1))
 
244
    {
 
245
        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
 
246
                      "client sent \"Transfer-Encoding: chunked\" header");
 
247
        return NGX_HTTP_LENGTH_REQUIRED;
 
248
    }
 
249
 
 
250
    if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
 
251
        if (r->headers_in.keep_alive) {
 
252
            r->headers_in.keep_alive_n =
 
253
                            ngx_atotm(r->headers_in.keep_alive->value.data,
 
254
                                      r->headers_in.keep_alive->value.len);
 
255
        }
 
256
    }
 
257
 
 
258
    return NGX_OK;
 
259
}
 
260
 
 
261
 
 
262
/* mostly a clone of the ngx_http_process_request function
 
263
 * in ngx_http_request.c of nginx 0.8.29.
 
264
 * copyrighted by Igor Sysoev. */
 
265
ngx_int_t
 
266
ngx_http_chunkin_process_request(ngx_http_request_t *r)
 
267
{
 
268
    ngx_connection_t  *c;
 
269
 
 
270
    c = r->connection;
 
271
 
 
272
    if (r->plain_http) {
 
273
        ngx_log_error(NGX_LOG_INFO, c->log, 0,
 
274
                      "client sent plain HTTP request to HTTPS port");
 
275
        /* ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS); */
 
276
        return NGX_HTTP_TO_HTTPS;
 
277
    }
 
278
 
 
279
#if (NGX_HTTP_SSL)
 
280
 
 
281
    if (c->ssl) {
 
282
        long                      rc;
 
283
        X509                     *cert;
 
284
        ngx_http_ssl_srv_conf_t  *sscf;
 
285
 
 
286
        sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
 
287
 
 
288
        if (sscf->verify) {
 
289
            rc = SSL_get_verify_result(c->ssl->connection);
 
290
 
 
291
            if (rc != X509_V_OK) {
 
292
                ngx_log_error(NGX_LOG_INFO, c->log, 0,
 
293
                              "client SSL certificate verify error: (%l:%s)",
 
294
                              rc, X509_verify_cert_error_string(rc));
 
295
 
 
296
                ngx_ssl_remove_cached_session(sscf->ssl.ctx,
 
297
                                       (SSL_get0_session(c->ssl->connection)));
 
298
 
 
299
                /* ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR); */
 
300
                return NGX_HTTPS_CERT_ERROR;
 
301
            }
 
302
 
 
303
            if (sscf->verify == 1) {
 
304
                cert = SSL_get_peer_certificate(c->ssl->connection);
 
305
 
 
306
                if (cert == NULL) {
 
307
                    ngx_log_error(NGX_LOG_INFO, c->log, 0,
 
308
                                  "client sent no required SSL certificate");
 
309
 
 
310
                    ngx_ssl_remove_cached_session(sscf->ssl.ctx,
 
311
                                       (SSL_get0_session(c->ssl->connection)));
 
312
 
 
313
                    /* ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT); */
 
314
                    return NGX_HTTPS_NO_CERT;
 
315
                }
 
316
 
 
317
                X509_free(cert);
 
318
            }
 
319
        }
 
320
    }
 
321
 
 
322
#endif
 
323
 
 
324
    if (c->read->timer_set) {
 
325
        ngx_del_timer(c->read);
 
326
    }
 
327
 
 
328
#if (NGX_STAT_STUB)
 
329
    (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
 
330
    r->stat_reading = 0;
 
331
    (void) ngx_atomic_fetch_add(ngx_stat_writing, 1);
 
332
    r->stat_writing = 1;
 
333
#endif
 
334
 
 
335
    return NGX_OK;
 
336
}
 
337
 
 
338
 
 
339
ngx_int_t
 
340
ngx_http_chunkin_internal_redirect(ngx_http_request_t *r,
 
341
    ngx_str_t *uri, ngx_str_t *args, ngx_http_chunkin_ctx_t *ctx)
 
342
{
 
343
    ngx_http_core_srv_conf_t  *cscf;
 
344
 
 
345
    r->uri_changes--;
 
346
 
 
347
    if (r->uri_changes == 0) {
 
348
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
 
349
                      "rewrite or internal redirection cycle "
 
350
                      "while internal redirect to \"%V\"", uri);
 
351
 
 
352
#if defined(nginx_version) && nginx_version >= 8011
 
353
 
 
354
        r->main->count++;
 
355
 
 
356
#endif
 
357
 
 
358
        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
 
359
        return NGX_DONE;
 
360
    }
 
361
 
 
362
    r->uri = *uri;
 
363
 
 
364
    if (args) {
 
365
        r->args = *args;
 
366
 
 
367
    } else {
 
368
        r->args.len = 0;
 
369
        r->args.data = NULL;
 
370
    }
 
371
 
 
372
    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
373
                   "internal redirect: \"%V?%V\"", uri, &r->args);
 
374
 
 
375
    ngx_http_set_exten(r);
 
376
 
 
377
    /* clear the modules contexts */
 
378
    ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
 
379
 
 
380
    ngx_http_set_ctx(r, ctx, ngx_http_chunkin_filter_module);
 
381
 
 
382
    cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
 
383
    r->loc_conf = cscf->ctx->loc_conf;
 
384
 
 
385
    ngx_http_update_location_config(r);
 
386
 
 
387
#if (NGX_HTTP_CACHE)
 
388
    r->cache = NULL;
 
389
#endif
 
390
 
 
391
    r->internal = 0;
 
392
 
 
393
#if defined(nginx_version) && nginx_version >= 8011
 
394
 
 
395
    dd("DISCARD BODY: %d", (int)r->discard_body);
 
396
 
 
397
    if ( ! ctx->r_discard_body ) {
 
398
        r->main->count++;
 
399
    }
 
400
 
 
401
#endif
 
402
 
 
403
    ngx_http_handler(r);
 
404
 
 
405
    return NGX_DONE;
 
406
}
 
407