~ubuntu-branches/ubuntu/quantal/nginx/quantal-updates

« back to all changes in this revision

Viewing changes to debian/modules/nginx-lua/src/ngx_http_lua_hook.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:
2
2
 
3
3
#define DDEBUG 0
4
4
 
 
5
#include <nginx.h>
5
6
#include "ngx_http_lua_hook.h"
6
7
#include "ngx_http_lua_util.h"
7
8
#include "ngx_http_lua_contentby.h"
8
 
#include "ngx_http_lua_headers.h"
 
9
#include "ngx_http_lua_headers_out.h"
 
10
#include "ngx_http_lua_headers_in.h"
9
11
 
10
12
#define NGX_UNESCAPE_URI_COMPONENT  0
11
13
 
12
 
#ifndef ngx_str_set
13
 
#define ngx_str_set(str, text)                                               \
14
 
    (str)->len = sizeof(text) - 1; (str)->data = (u_char *) text
15
 
#endif
16
 
 
17
 
 
18
14
#define ngx_http_lua_method_name(m) { sizeof(m) - 1, (u_char *) m " " }
19
15
 
 
16
jmp_buf ngx_http_lua_exception;
 
17
 
20
18
static ngx_str_t  ngx_http_lua_get_method = ngx_http_lua_method_name("GET");
21
19
static ngx_str_t  ngx_http_lua_put_method = ngx_http_lua_method_name("PUT");
22
20
static ngx_str_t  ngx_http_lua_post_method = ngx_http_lua_method_name("POST");
32
30
static void ngx_http_lua_process_args_option(ngx_http_request_t *r,
33
31
        lua_State *L, int table, ngx_str_t *args);
34
32
static ngx_int_t ngx_http_lua_set_content_length_header(ngx_http_request_t *r,
35
 
        size_t len);
 
33
        off_t len);
36
34
static ngx_int_t ngx_http_lua_adjust_subrequest(ngx_http_request_t *sr,
37
35
        ngx_uint_t method, ngx_http_request_body_t *body,
38
36
        ngx_flag_t share_all_vars);
39
 
static ngx_int_t ngx_http_lua_post_subrequest(ngx_http_request_t *r,
40
 
        void *data, ngx_int_t rc);
41
37
static int ngx_http_lua_ngx_echo(lua_State *L, ngx_flag_t newline);
42
38
static void ngx_http_lua_unescape_uri(u_char **dst, u_char **src, size_t size,
43
39
        ngx_uint_t type);
47
43
        lua_State *L);
48
44
static uintptr_t ngx_http_lua_escape_uri(u_char *dst, u_char *src,
49
45
        size_t size, ngx_uint_t type);
 
46
static int ngx_http_lua_ngx_req_header_set_helper(lua_State *L);
 
47
 
 
48
 
 
49
#if defined(NDK) && NDK
50
50
static ndk_set_var_value_pt ngx_http_lookup_ndk_set_var_directive(u_char *name,
51
51
        size_t name_len);
 
52
#endif
52
53
 
53
54
 
54
55
/*  longjmp mark for restoring nginx execution after Lua VM crashing */
85
86
 
86
87
    /*  restore nginx execution */
87
88
    NGX_LUA_EXCEPTION_THROW(1);
 
89
 
 
90
    /* cannot reach here, just to suppress a potential gcc warning */
 
91
    return 0;
88
92
}
89
93
 
90
94
 
350
354
 
351
355
    rc = (ngx_int_t) luaL_checkinteger(L, 1);
352
356
 
353
 
    if (rc >= 200 && ctx->headers_sent) {
 
357
    if (rc >= NGX_HTTP_SPECIAL_RESPONSE && ctx->headers_sent) {
354
358
        return luaL_error(L, "attempt to call ngx.exit after sending "
355
359
                "out the headers");
356
360
    }
640
644
            lua_getfield(L, 4, "share_all_vars");
641
645
 
642
646
            type = lua_type(L, -1);
 
647
 
643
648
            if (type == LUA_TNIL) {
644
649
                /* do nothing */
 
650
 
645
651
            } else {
646
652
                if (type != LUA_TBOOLEAN) {
647
653
                    return luaL_error(L, "Bad share_all_vars option value");
657
663
            lua_getfield(L, 4, "method");
658
664
 
659
665
            type = lua_type(L, -1);
 
666
 
660
667
            if (type == LUA_TNIL) {
661
668
                method = NGX_HTTP_GET;
 
669
 
662
670
            } else {
663
671
                if (type != LUA_TNUMBER) {
664
672
                    return luaL_error(L, "Bad http request method");
673
681
 
674
682
            lua_getfield(L, 4, "body");
675
683
 
 
684
            type = lua_type(L, -1);
 
685
 
676
686
            if (type != LUA_TNIL) {
677
687
                if (type != LUA_TSTRING && type != LUA_TNUMBER) {
678
688
                    return luaL_error(L, "Bad http request body");
887
897
}
888
898
 
889
899
 
890
 
static ngx_int_t
 
900
ngx_int_t
891
901
ngx_http_lua_post_subrequest(ngx_http_request_t *r, void *data, ngx_int_t rc)
892
902
{
893
903
    ngx_http_request_t            *pr;
1933
1943
 
1934
1944
 
1935
1945
int
1936
 
ngx_http_lua_header_get(lua_State *L)
 
1946
ngx_http_lua_ngx_req_get_headers(lua_State *L) {
 
1947
    ngx_list_part_t              *part;
 
1948
    ngx_table_elt_t              *header;
 
1949
    ngx_http_request_t           *r;
 
1950
    ngx_uint_t                    i;
 
1951
 
 
1952
    if (lua_gettop(L) != 0) {
 
1953
        return luaL_error(L, "expecting 0 arguments but seen %d",
 
1954
                lua_gettop(L));
 
1955
    }
 
1956
 
 
1957
    lua_getglobal(L, GLOBALS_SYMBOL_REQUEST);
 
1958
    r = lua_touserdata(L, -1);
 
1959
    lua_pop(L, 1);
 
1960
 
 
1961
    if (r == NULL) {
 
1962
        return luaL_error(L, "no request object found");
 
1963
    }
 
1964
 
 
1965
    lua_createtable(L, 0, 4);
 
1966
 
 
1967
    part = &r->headers_in.headers.part;
 
1968
    header = part->elts;
 
1969
 
 
1970
    for (i = 0; /* void */; i++) {
 
1971
 
 
1972
        if (i >= part->nelts) {
 
1973
            if (part->next == NULL) {
 
1974
                break;
 
1975
            }
 
1976
 
 
1977
            part = part->next;
 
1978
            header = part->elts;
 
1979
            i = 0;
 
1980
        }
 
1981
 
 
1982
        lua_pushlstring(L, (char *) header[i].key.data, header[i].key.len);
 
1983
            /* stack: table key */
 
1984
 
 
1985
        lua_pushvalue(L, -1); /* stack: table key key */
 
1986
 
 
1987
        /* check if header already exists */
 
1988
        lua_rawget(L, -3); /* stack: table key value */
 
1989
 
 
1990
        if (lua_isnil(L, -1)) {
 
1991
            dd("req.header key %.*s not exist", (int) header[i].key.len,
 
1992
                    header[i].key.data);
 
1993
 
 
1994
            lua_pop(L, 1); /* stack: table key */
 
1995
 
 
1996
            lua_pushlstring(L, (char *) header[i].value.data,
 
1997
                    header[i].value.len); /* stack: table key value */
 
1998
 
 
1999
            lua_rawset(L, -3); /* stack: table */
 
2000
 
 
2001
        } else {
 
2002
            dd("req.header key %.*s exists", (int) header[i].key.len,
 
2003
                    header[i].key.data);
 
2004
 
 
2005
            if (! lua_istable(L, -1)) { /* already inserted one value */
 
2006
                dd("req.header key %.*s already has one value",
 
2007
                        (int) header[i].key.len, header[i].key.data);
 
2008
                lua_createtable(L, 4, 0);
 
2009
                    /* stack: table key value table */
 
2010
 
 
2011
                lua_insert(L, -2); /* stack: table key table value */
 
2012
                lua_rawseti(L, -2, 1); /* stack: table key table */
 
2013
 
 
2014
                lua_pushlstring(L, (char *) header[i].value.data,
 
2015
                        header[i].value.len);
 
2016
                    /* stack: table key table value */
 
2017
 
 
2018
                lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
 
2019
                    /* stack: table key table */
 
2020
 
 
2021
                lua_rawset(L, -3); /* stack: table */
 
2022
 
 
2023
            } else {
 
2024
                dd("req.header key %.*s already has multi values",
 
2025
                        (int) header[i].key.len, header[i].key.data);
 
2026
 
 
2027
                lua_pushlstring(L, (char *) header[i].value.data,
 
2028
                        header[i].value.len);
 
2029
                    /* stack: table key table value */
 
2030
 
 
2031
                lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
 
2032
                    /* stack: table key table */
 
2033
 
 
2034
                lua_pop(L, 2); /* stack: table */
 
2035
            }
 
2036
        }
 
2037
 
 
2038
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
2039
                       "http lua req header: \"%V: %V\"",
 
2040
                       &header[i].key, &header[i].value);
 
2041
    }
 
2042
 
 
2043
    return 1;
 
2044
}
 
2045
 
 
2046
 
 
2047
int
 
2048
ngx_http_lua_ngx_header_get(lua_State *L)
1937
2049
{
1938
2050
    return luaL_error(L, "header get not implemented yet");
1939
2051
}
1940
2052
 
1941
2053
 
1942
2054
int
1943
 
ngx_http_lua_header_set(lua_State *L)
 
2055
ngx_http_lua_ngx_header_set(lua_State *L)
1944
2056
{
1945
2057
    ngx_http_request_t          *r;
1946
2058
    u_char                      *p;
2021
2133
                ngx_memcpy(value.data, p, len);
2022
2134
                value.len = len;
2023
2135
 
2024
 
                rc = ngx_http_lua_set_header(r, key, value,
 
2136
                rc = ngx_http_lua_set_output_header(r, key, value,
2025
2137
                        i == 1 /* override */);
2026
2138
 
2027
2139
                if (rc != NGX_OK) {
2048
2160
    dd("key: %.*s, value: %.*s",
2049
2161
            (int) key.len, key.data, (int) value.len, value.data);
2050
2162
 
2051
 
    rc = ngx_http_lua_set_header(r, key, value, 1 /* override */);
 
2163
    rc = ngx_http_lua_set_output_header(r, key, value, 1 /* override */);
 
2164
 
 
2165
    if (rc != NGX_OK) {
 
2166
        return luaL_error(L, "failed to set header %s (error: %d)",
 
2167
                key.data, (int) rc);
 
2168
    }
 
2169
 
 
2170
    return 0;
 
2171
}
 
2172
 
 
2173
 
 
2174
int
 
2175
ngx_http_lua_ngx_req_header_clear(lua_State *L)
 
2176
{
 
2177
    if (lua_gettop(L) != 1) {
 
2178
        return luaL_error(L, "expecting one arguments, but seen %d",
 
2179
                lua_gettop(L));
 
2180
    }
 
2181
 
 
2182
    lua_pushnil(L);
 
2183
 
 
2184
    return ngx_http_lua_ngx_req_header_set_helper(L);
 
2185
}
 
2186
 
 
2187
 
 
2188
int
 
2189
ngx_http_lua_ngx_req_header_set(lua_State *L)
 
2190
{
 
2191
    if (lua_gettop(L) != 2) {
 
2192
        return luaL_error(L, "expecting two arguments, but seen %d",
 
2193
                lua_gettop(L));
 
2194
    }
 
2195
 
 
2196
    return ngx_http_lua_ngx_req_header_set_helper(L);
 
2197
}
 
2198
 
 
2199
 
 
2200
static int
 
2201
ngx_http_lua_ngx_req_header_set_helper(lua_State *L)
 
2202
{
 
2203
    ngx_http_request_t          *r;
 
2204
    u_char                      *p;
 
2205
    ngx_str_t                    key;
 
2206
    ngx_str_t                    value;
 
2207
    ngx_uint_t                   i;
 
2208
    size_t                       len;
 
2209
    ngx_int_t                    rc;
 
2210
    ngx_uint_t                   n;
 
2211
 
 
2212
    lua_getglobal(L, GLOBALS_SYMBOL_REQUEST);
 
2213
    r = lua_touserdata(L, -1);
 
2214
    lua_pop(L, 1);
 
2215
 
 
2216
    if (r == NULL) {
 
2217
        return luaL_error(L, "no request object found");
 
2218
    }
 
2219
 
 
2220
    p = (u_char *) luaL_checklstring(L, 1, &len);
 
2221
 
 
2222
    dd("key: %.*s, len %d", (int) len, p, (int) len);
 
2223
 
 
2224
    /* replace "_" with "-" */
 
2225
    for (i = 0; i < len; i++) {
 
2226
        if (p[i] == '_') {
 
2227
            p[i] = '-';
 
2228
        }
 
2229
    }
 
2230
 
 
2231
    key.data = ngx_palloc(r->pool, len + 1);
 
2232
    if (key.data == NULL) {
 
2233
        return luaL_error(L, "out of memory");
 
2234
    }
 
2235
 
 
2236
    ngx_memcpy(key.data, p, len);
 
2237
 
 
2238
    key.data[len] = '\0';
 
2239
 
 
2240
    key.len = len;
 
2241
 
 
2242
    if (lua_type(L, 2) == LUA_TNIL) {
 
2243
        value.data = NULL;
 
2244
        value.len = 0;
 
2245
 
 
2246
    } else if (lua_type(L, 2) == LUA_TTABLE) {
 
2247
        n = luaL_getn(L, 2);
 
2248
        if (n == 0) {
 
2249
            value.data = NULL;
 
2250
            value.len = 0;
 
2251
 
 
2252
        } else {
 
2253
            for (i = 1; i <= n; i++) {
 
2254
                dd("header value table index %d", (int) i);
 
2255
 
 
2256
                lua_rawgeti(L, 2, i);
 
2257
                p = (u_char *) luaL_checklstring(L, -1, &len);
 
2258
 
 
2259
                value.data = ngx_palloc(r->pool, len);
 
2260
                if (value.data == NULL) {
 
2261
                    return luaL_error(L, "out of memory");
 
2262
                }
 
2263
 
 
2264
                ngx_memcpy(value.data, p, len);
 
2265
                value.len = len;
 
2266
 
 
2267
                rc = ngx_http_lua_set_input_header(r, key, value,
 
2268
                        i == 1 /* override */);
 
2269
 
 
2270
                if (rc != NGX_OK) {
 
2271
                    return luaL_error(L,
 
2272
                            "failed to set header %s (error: %d)",
 
2273
                            key.data, (int) rc);
 
2274
                }
 
2275
            }
 
2276
 
 
2277
            return 0;
 
2278
        }
 
2279
 
 
2280
    } else {
 
2281
        p = (u_char *) luaL_checklstring(L, 2, &len);
 
2282
        value.data = ngx_palloc(r->pool, len);
 
2283
        if (value.data == NULL) {
 
2284
            return luaL_error(L, "out of memory");
 
2285
        }
 
2286
 
 
2287
        ngx_memcpy(value.data, p, len);
 
2288
        value.len = len;
 
2289
    }
 
2290
 
 
2291
    dd("key: %.*s, value: %.*s",
 
2292
            (int) key.len, key.data, (int) value.len, value.data);
 
2293
 
 
2294
    rc = ngx_http_lua_set_input_header(r, key, value, 1 /* override */);
2052
2295
 
2053
2296
    if (rc != NGX_OK) {
2054
2297
        return luaL_error(L, "failed to set header %s (error: %d)",
2155
2398
}
2156
2399
 
2157
2400
 
 
2401
#if defined(NDK) && NDK
2158
2402
int
2159
2403
ngx_http_lua_ndk_set_var_get(lua_State *L)
2160
2404
{
2285
2529
 
2286
2530
    return 1;
2287
2531
}
 
2532
#endif /* defined(NDK) && NDK */
2288
2533
 
2289
2534
 
2290
2535
static ngx_int_t
2291
 
ngx_http_lua_set_content_length_header(ngx_http_request_t *r, size_t len)
 
2536
ngx_http_lua_set_content_length_header(ngx_http_request_t *r, off_t len)
2292
2537
{
2293
 
    ngx_table_elt_t            *h;
 
2538
    ngx_table_elt_t                 *h, *header;
 
2539
    u_char                          *p;
 
2540
    ngx_list_part_t                 *part;
 
2541
    ngx_http_request_t              *pr;
 
2542
    ngx_uint_t                       i;
2294
2543
 
2295
2544
    r->headers_in.content_length_n = len;
2296
 
    r->headers_in.content_length = ngx_pcalloc(r->pool,
2297
 
            sizeof(ngx_table_elt_t));
2298
 
 
2299
 
    r->headers_in.content_length->value.data =
2300
 
        ngx_palloc(r->pool, NGX_OFF_T_LEN);
2301
 
 
2302
 
    if (r->headers_in.content_length->value.data == NULL) {
2303
 
        return NGX_ERROR;
2304
 
    }
2305
 
 
2306
 
    r->headers_in.content_length->value.len = ngx_sprintf(
2307
 
            r->headers_in.content_length->value.data, "%O",
2308
 
            r->headers_in.content_length_n) -
2309
 
            r->headers_in.content_length->value.data;
2310
2545
 
2311
2546
    if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
2312
2547
                sizeof(ngx_table_elt_t)) != NGX_OK) {
2318
2553
        return NGX_ERROR;
2319
2554
    }
2320
2555
 
2321
 
    h->hash = r->header_hash;
2322
 
 
2323
2556
    h->key = ngx_http_lua_content_length_header_key;
2324
 
    h->value = r->headers_in.content_length->value;
2325
 
 
2326
2557
    h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
2327
2558
    if (h->lowcase_key == NULL) {
2328
2559
        return NGX_ERROR;
2330
2561
 
2331
2562
    ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
2332
2563
 
 
2564
    r->headers_in.content_length = h;
 
2565
 
 
2566
    p = ngx_palloc(r->pool, NGX_OFF_T_LEN);
 
2567
    if (p == NULL) {
 
2568
        return NGX_ERROR;
 
2569
    }
 
2570
 
 
2571
    h->value.data = p;
 
2572
 
 
2573
    h->value.len = ngx_sprintf(h->value.data, "%O", len) - h->value.data;
 
2574
 
 
2575
    h->hash = 1;
 
2576
 
2333
2577
    dd("r content length: %.*s",
2334
2578
            (int)r->headers_in.content_length->value.len,
2335
2579
            r->headers_in.content_length->value.data);
2336
2580
 
 
2581
    pr = r->parent;
 
2582
 
 
2583
    if (pr == NULL) {
 
2584
        return NGX_OK;
 
2585
    }
 
2586
 
 
2587
    /* forward the parent request's all other request headers */
 
2588
 
 
2589
    part = &pr->headers_in.headers.part;
 
2590
    header = part->elts;
 
2591
 
 
2592
    for (i = 0; /* void */; i++) {
 
2593
 
 
2594
        if (i >= part->nelts) {
 
2595
            if (part->next == NULL) {
 
2596
                break;
 
2597
            }
 
2598
 
 
2599
            part = part->next;
 
2600
            header = part->elts;
 
2601
            i = 0;
 
2602
        }
 
2603
 
 
2604
        h = ngx_list_push(&r->headers_in.headers);
 
2605
        if (h == NULL) {
 
2606
            return NGX_ERROR;
 
2607
        }
 
2608
 
 
2609
        *h = header[i];
 
2610
    }
 
2611
 
 
2612
    /* XXX maybe we should set those built-in header slot in
 
2613
     * ngx_http_headers_in_t too? */
 
2614
 
2337
2615
    return NGX_OK;
2338
2616
}
2339
2617
 
2341
2619
int
2342
2620
ngx_http_lua_ngx_cookie_time(lua_State *L)
2343
2621
{
2344
 
    ngx_http_request_t                  *r;
2345
2622
    time_t                               t;
2346
2623
    u_char                              *p;
2347
2624
 
2353
2630
 
2354
2631
    t = (time_t) luaL_checknumber(L, 1);
2355
2632
 
2356
 
    lua_getglobal(L, GLOBALS_SYMBOL_REQUEST);
2357
 
    r = lua_touserdata(L, -1);
2358
 
    lua_pop(L, 1);
2359
 
 
2360
 
    if (r == NULL) {
2361
 
        return luaL_error(L, "no request object found");
2362
 
    }
2363
 
 
2364
2633
    p = buf;
2365
2634
    p = ngx_http_cookie_time(p, t);
2366
2635
 
2371
2640
 
2372
2641
 
2373
2642
int
 
2643
ngx_http_lua_ngx_http_time(lua_State *L)
 
2644
{
 
2645
    time_t                               t;
 
2646
    u_char                              *p;
 
2647
 
 
2648
    u_char   buf[sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1];
 
2649
 
 
2650
    if (lua_gettop(L) != 1) {
 
2651
        return luaL_error(L, "expecting one argument");
 
2652
    }
 
2653
 
 
2654
    t = (time_t) luaL_checknumber(L, 1);
 
2655
 
 
2656
    p = buf;
 
2657
    p = ngx_http_time(p, t);
 
2658
 
 
2659
    lua_pushlstring(L, (char *) buf, p - buf);
 
2660
 
 
2661
    return 1;
 
2662
}
 
2663
 
 
2664
 
 
2665
int
 
2666
ngx_http_lua_ngx_parse_http_time(lua_State *L)
 
2667
{
 
2668
    u_char                              *p;
 
2669
    size_t                               len;
 
2670
    time_t                               time;
 
2671
 
 
2672
    if (lua_gettop(L) != 1) {
 
2673
        return luaL_error(L, "expecting one argument");
 
2674
    }
 
2675
 
 
2676
    p = (u_char *) luaL_checklstring(L, 1, &len);
 
2677
 
 
2678
    time = ngx_http_parse_time(p, len);
 
2679
    if (time == NGX_ERROR) {
 
2680
        lua_pushnil(L);
 
2681
        return 1;
 
2682
    }
 
2683
 
 
2684
    lua_pushnumber(L, (lua_Number) time);
 
2685
 
 
2686
    return 1;
 
2687
}
 
2688
 
 
2689
 
 
2690
int
2374
2691
ngx_http_lua_ngx_redirect(lua_State *L)
2375
2692
{
2376
2693
    ngx_http_lua_ctx_t          *ctx;