~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: Bazaar Package Importer
  • Author(s): Kartik Mistry
  • Date: 2011-04-16 13:47:58 UTC
  • mfrom: (4.2.31 sid)
  • Revision ID: james.westby@ubuntu.com-20110416134758-yqca2qp5crh2hw2f
Tags: 1.0.0-2
* debian/rules:
  + Removed --with-file-aio support. Fixed FTBFS on kFreeBSD-* arch
    (Closes: #621882)

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 
10
10
#define NGX_UNESCAPE_URI_COMPONENT  0
11
11
 
 
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
 
12
17
 
13
18
#define ngx_http_lua_method_name(m) { sizeof(m) - 1, (u_char *) m " " }
14
19
 
16
21
static ngx_str_t  ngx_http_lua_put_method = ngx_http_lua_method_name("PUT");
17
22
static ngx_str_t  ngx_http_lua_post_method = ngx_http_lua_method_name("POST");
18
23
static ngx_str_t  ngx_http_lua_head_method = ngx_http_lua_method_name("HEAD");
19
 
static ngx_str_t  ngx_http_lua_delete_method = ngx_http_lua_method_name("DELETE");
 
24
static ngx_str_t  ngx_http_lua_delete_method =
 
25
        ngx_http_lua_method_name("DELETE");
20
26
 
21
27
 
22
28
static ngx_str_t  ngx_http_lua_content_length_header_key =
28
34
static ngx_int_t ngx_http_lua_set_content_length_header(ngx_http_request_t *r,
29
35
        size_t len);
30
36
static ngx_int_t ngx_http_lua_adjust_subrequest(ngx_http_request_t *sr,
31
 
        ngx_uint_t method, ngx_http_request_body_t *body, ngx_flag_t share_all_vars);
32
 
static ngx_int_t ngx_http_lua_post_subrequest(ngx_http_request_t *r, void *data, ngx_int_t rc);
 
37
        ngx_uint_t method, ngx_http_request_body_t *body,
 
38
        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);
33
41
static int ngx_http_lua_ngx_echo(lua_State *L, ngx_flag_t newline);
34
 
static void ngx_http_lua_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type);
35
 
static uintptr_t ngx_http_lua_ngx_escape_sql_str(u_char *dst, u_char *src, size_t size);
36
 
static void log_wrapper(ngx_http_request_t *r, const char *ident, int level, lua_State *L);
 
42
static void ngx_http_lua_unescape_uri(u_char **dst, u_char **src, size_t size,
 
43
        ngx_uint_t type);
 
44
static uintptr_t ngx_http_lua_ngx_escape_sql_str(u_char *dst, u_char *src,
 
45
        size_t size);
 
46
static void log_wrapper(ngx_http_request_t *r, const char *ident, int level,
 
47
        lua_State *L);
37
48
static uintptr_t ngx_http_lua_escape_uri(u_char *dst, u_char *src,
38
49
        size_t size, ngx_uint_t type);
39
50
static ndk_set_var_value_pt ngx_http_lookup_ndk_set_var_directive(u_char *name,
44
55
jmp_buf ngx_http_lua_exception;
45
56
 
46
57
/**
47
 
 * Override default Lua panic handler, output VM crash reason to NginX error
 
58
 * Override default Lua panic handler, output VM crash reason to nginx error
48
59
 * log, and restore execution to the nearest jmp-mark.
49
60
 * 
50
61
 * @param L Lua state pointer
51
62
 * @retval Long jump to the nearest jmp-mark, never returns.
52
 
 * @note NginX request pointer should be stored in Lua thread's globals table
 
63
 * @note nginx request pointer should be stored in Lua thread's globals table
53
64
 * in order to make logging working.
54
65
 * */
55
66
int
64
75
 
65
76
    /*  log Lua VM crashing reason to error log */
66
77
    if (r && r->connection && r->connection->log) {
67
 
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "(lua-atpanic) Lua VM crashed, reason: %s", s);
 
78
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
 
79
                "(lua-atpanic) Lua VM crashed, reason: %s", s);
 
80
 
68
81
    } else {
69
82
        dd("(lua-atpanic) can't output Lua VM crashing reason to error log"
70
83
                " due to invalid logging context: %s", s);
129
142
 
130
143
 
131
144
/**
132
 
 * Wrapper of NginX log functionality. Take a log level param and varargs of
 
145
 * Wrapper of nginx log functionality. Take a log level param and varargs of
133
146
 * log message params.
134
147
 *
135
148
 * @param L Lua state pointer
160
173
 
161
174
 
162
175
/**
163
 
 * Override Lua print function, output message to NginX error logs. Equal to
 
176
 * Override Lua print function, output message to nginx error logs. Equal to
164
177
 * ngx.log(ngx.ERR, ...).
165
178
 *
166
179
 * @param L Lua state pointer
177
190
 
178
191
    if (r && r->connection && r->connection->log) {
179
192
        log_wrapper(r, "lua print: ", NGX_LOG_NOTICE, L);
 
193
 
180
194
    } else {
181
 
        dd("(lua-print) can't output print content to error log due to invalid logging context!");
 
195
        dd("(lua-print) can't output print content to error log due "
 
196
                "to invalid logging context!");
182
197
    }
183
198
 
184
199
    return 0;
214
229
int
215
230
ngx_http_lua_ngx_print(lua_State *L)
216
231
{
 
232
    dd("calling lua print");
217
233
    return ngx_http_lua_ngx_echo(L, 0);
218
234
}
219
235
 
221
237
int
222
238
ngx_http_lua_ngx_say(lua_State *L)
223
239
{
 
240
    dd("calling");
224
241
    return ngx_http_lua_ngx_echo(L, 1);
225
242
}
226
243
 
270
287
        size += sizeof("\n") - 1;
271
288
    }
272
289
 
 
290
    if (size == 0) {
 
291
        /* do nothing for empty strings */
 
292
        return 0;
 
293
    }
 
294
 
273
295
    b = ngx_create_temp_buf(r->pool, size);
274
296
    if (b == NULL) {
275
297
        return luaL_error(L, "out of memory");
277
299
 
278
300
    for (i = 1; i <= nargs; i++) {
279
301
        p = lua_tolstring(L, i, &len);
280
 
        b->last = ngx_copy(b->last, p, len);
 
302
        b->last = ngx_copy(b->last, (u_char *) p, len);
281
303
    }
282
304
 
283
305
    if (newline) {
298
320
        return luaL_error(L, "failed to send data through the output filters");
299
321
    }
300
322
 
301
 
    lua_settop(L, 0);
302
 
 
303
323
    return 0;
304
324
}
305
325
 
329
349
    }
330
350
 
331
351
    rc = (ngx_int_t) luaL_checkinteger(L, 1);
 
352
 
332
353
    if (rc >= 200 && ctx->headers_sent) {
333
 
        return luaL_error(L, "attempt to call ngx.exit after sending out the headers");
 
354
        return luaL_error(L, "attempt to call ngx.exit after sending "
 
355
                "out the headers");
334
356
    }
335
357
 
336
358
    ctx->exit_code = rc;
366
388
        return luaL_error(L, "no request ctx found");
367
389
    }
368
390
 
369
 
    if (ctx->eof == 0) {
 
391
    if (ctx->eof) {
370
392
        return luaL_error(L, "already seen eof");
371
393
    }
372
394
 
379
401
 
380
402
    cl = ngx_alloc_chain_link(r->pool);
381
403
    if (cl == NULL) {
382
 
        return luaL_error(L, "memory allocation error");
 
404
        return luaL_error(L, "out of memory");
383
405
    }
384
406
 
385
407
    cl->next = NULL;
401
423
int
402
424
ngx_http_lua_ngx_eof(lua_State *L)
403
425
{
404
 
    ngx_http_request_t *r;
405
 
    ngx_http_lua_ctx_t *ctx;
 
426
    ngx_http_request_t      *r;
 
427
    ngx_http_lua_ctx_t      *ctx;
 
428
    ngx_int_t                rc;
406
429
 
407
430
    lua_getglobal(L, GLOBALS_SYMBOL_REQUEST);
408
431
    r = lua_touserdata(L, -1);
417
440
    }
418
441
 
419
442
    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
420
 
    if (ctx != NULL && ctx->eof == 0) {
421
 
        ctx->eof = 1;    /*  set eof flag to prevent further output */
422
 
        ngx_http_lua_send_chain_link(r, ctx, NULL/*indicate last_buf*/);
 
443
 
 
444
    rc = ngx_http_lua_send_chain_link(r, ctx, NULL/*indicate last_buf*/);
 
445
 
 
446
    if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
 
447
        return luaL_error(L, "failed to send eof buf");
423
448
    }
424
449
 
425
450
    return 0;
426
451
}
427
452
 
428
453
 
 
454
/* ngx.location.capture is just a thin wrapper around
 
455
 * ngx.location.capture_multi */
429
456
int
430
457
ngx_http_lua_ngx_location_capture(lua_State *L)
431
458
{
 
459
    int                 n;
 
460
 
 
461
    n = lua_gettop(L);
 
462
 
 
463
    if (n != 1 && n != 2) {
 
464
        return luaL_error(L, "expecting one or two arguments");
 
465
    }
 
466
 
 
467
    lua_createtable(L, n, 0); /* uri opts? table  */
 
468
    lua_insert(L, 1); /* table uri opts? */
 
469
    if (n == 1) { /* table uri */
 
470
        lua_rawseti(L, 1, 1); /* table */
 
471
 
 
472
    } else { /* table uri opts */
 
473
        lua_rawseti(L, 1, 2); /* table uri */
 
474
        lua_rawseti(L, 1, 1); /* table */
 
475
    }
 
476
 
 
477
    lua_createtable(L, 1, 0); /* table table' */
 
478
    lua_insert(L, 1);   /* table' table */
 
479
    lua_rawseti(L, 1, 1); /* table' */
 
480
 
 
481
    return ngx_http_lua_ngx_location_capture_multi(L);
 
482
}
 
483
 
 
484
 
 
485
int
 
486
ngx_http_lua_ngx_location_capture_multi(lua_State *L)
 
487
{
432
488
    ngx_http_request_t              *r;
433
489
    ngx_http_request_t              *sr; /* subrequest object */
434
490
    ngx_http_post_subrequest_t      *psr;
435
491
    ngx_http_lua_ctx_t              *sr_ctx;
 
492
    ngx_http_lua_ctx_t              *ctx;
436
493
    ngx_str_t                        uri;
437
494
    ngx_str_t                        args;
438
 
    ngx_str_t                        extra_args = ngx_null_string;
439
 
    ngx_uint_t                       flags = 0;
 
495
    ngx_str_t                        extra_args;
 
496
    ngx_uint_t                       flags;
440
497
    u_char                          *p;
441
498
    u_char                          *q;
442
499
    size_t                           len;
 
500
    size_t                           nargs;
443
501
    int                              rc;
444
502
    int                              n;
445
503
    ngx_uint_t                       method;
446
 
    ngx_http_request_body_t         *body = NULL;
 
504
    ngx_http_request_body_t         *body;
447
505
    int                              type;
448
506
    ngx_buf_t                       *b;
449
 
    ngx_flag_t                       share_all_vars = 0;
 
507
    ngx_flag_t                       share_all_vars;
 
508
    ngx_uint_t                       nsubreqs;
 
509
    ngx_uint_t                       index;
 
510
    size_t                           sr_statuses_len;
 
511
    size_t                           sr_headers_len;
 
512
    size_t                           sr_bodies_len;
 
513
 
 
514
    n = lua_gettop(L);
 
515
    if (n != 1) {
 
516
        return luaL_error(L, "only one argument is expected, but got %d", n);
 
517
    }
 
518
 
 
519
    luaL_checktype(L, 1, LUA_TTABLE);
 
520
 
 
521
    nsubreqs = lua_objlen(L, 1);
 
522
    if (nsubreqs == 0) {
 
523
        return luaL_error(L, "at least one subrequest should be specified");
 
524
    }
450
525
 
451
526
    lua_getglobal(L, GLOBALS_SYMBOL_REQUEST);
452
527
    r = lua_touserdata(L, -1);
456
531
        return luaL_error(L, "no request object found");
457
532
    }
458
533
 
 
534
    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
 
535
    if (ctx == NULL) {
 
536
        return luaL_error(L, "no ctx found");
 
537
    }
 
538
 
 
539
    sr_statuses_len = nsubreqs * sizeof(ngx_int_t);
 
540
    sr_headers_len  = nsubreqs * sizeof(ngx_http_headers_out_t *);
 
541
    sr_bodies_len   = nsubreqs * sizeof(ngx_str_t);
 
542
 
 
543
    p = ngx_pcalloc(r->pool, sr_statuses_len + sr_headers_len +
 
544
            sr_bodies_len);
 
545
 
 
546
    if (p == NULL) {
 
547
        return luaL_error(L, "out of memory");
 
548
    }
 
549
 
 
550
    ctx->sr_statuses = (void *) p;
 
551
    p += sr_statuses_len;
 
552
 
 
553
    ctx->sr_headers = (void *) p;
 
554
    p += sr_headers_len;
 
555
 
 
556
    ctx->sr_bodies = (void *) p;
 
557
 
 
558
    ctx->nsubreqs = nsubreqs;
 
559
 
459
560
    n = lua_gettop(L);
460
 
 
461
 
    if (n != 1 && n != 2) {
462
 
        return luaL_error(L, "expecting one or two arguments");
463
 
    }
464
 
 
465
 
    if (n == 2) {
466
 
        /* check out the options table */
467
 
 
468
 
        if (lua_type(L, 2) != LUA_TTABLE) {
469
 
            return luaL_error(L, "expecting table as the 2nd argument");
470
 
        }
471
 
 
472
 
        /* check the args option */
473
 
 
474
 
        lua_getfield(L, 2, "args");
475
 
 
476
 
        type = lua_type(L, -1);
477
 
 
478
 
        switch (type) {
479
 
        case LUA_TTABLE:
480
 
            ngx_http_lua_process_args_option(r, L, -1, &extra_args);
481
 
            break;
482
 
 
483
 
        case LUA_TNIL:
484
 
            /* do nothing */
485
 
            break;
486
 
 
487
 
        case LUA_TNUMBER:
488
 
        case LUA_TSTRING:
489
 
            extra_args.data = (u_char *) lua_tolstring(L, -1, &len);
490
 
            extra_args.len = len;
491
 
 
492
 
            break;
493
 
 
494
 
        default:
495
 
            return luaL_error(L, "Bad args option value");
496
 
        }
497
 
 
498
 
        lua_pop(L, 1);
499
 
 
500
 
        /* check the share_all_vars option */
501
 
 
502
 
        lua_getfield(L, 2, "share_all_vars");
503
 
 
504
 
        type = lua_type(L, -1);
505
 
        if (type == LUA_TNIL) {
506
 
            /* do nothing */
 
561
    dd("top before loop: %d", n);
 
562
 
 
563
    ctx->done = 0;
 
564
    ctx->waiting = 0;
 
565
 
 
566
    for (index = 0; index < nsubreqs; index++) {
 
567
        ctx->waiting++;
 
568
 
 
569
        lua_rawgeti(L, 1, index + 1);
 
570
        if (lua_isnil(L, -1)) {
 
571
            return luaL_error(L, "only array-like tables are allowed");
 
572
        }
 
573
 
 
574
        if (lua_type(L, -1) != LUA_TTABLE) {
 
575
            return luaL_error(L, "the query argument %d is not a table, "
 
576
                    "but a %s",
 
577
                    index, lua_typename(L, lua_type(L, -1)));
 
578
        }
 
579
 
 
580
        dd("lua top so far: %d", lua_gettop(L));
 
581
 
 
582
        nargs = lua_objlen(L, -1);
 
583
 
 
584
        if (nargs != 1 && nargs != 2) {
 
585
            return luaL_error(L, "query argument %d expecting one or "
 
586
                    "two arguments", index);
 
587
        }
 
588
 
 
589
        lua_rawgeti(L, 2, 1); /* queries query uri */
 
590
 
 
591
        dd("first arg in first query: %s", lua_typename(L, lua_type(L, -1)));
 
592
 
 
593
        body = NULL;
 
594
 
 
595
        extra_args.data = NULL;
 
596
        extra_args.len = 0;
 
597
 
 
598
        share_all_vars = 0;
 
599
 
 
600
        if (nargs == 2) {
 
601
            /* check out the options table */
 
602
 
 
603
            lua_rawgeti(L, 2, 2);
 
604
 
 
605
            if (lua_type(L, 4) != LUA_TTABLE) {
 
606
                return luaL_error(L, "expecting table as the 2nd argument for "
 
607
                        "subrequest %d", index);
 
608
            }
 
609
 
 
610
            /* check the args option */
 
611
 
 
612
            lua_getfield(L, 4, "args");
 
613
 
 
614
            type = lua_type(L, -1);
 
615
 
 
616
            switch (type) {
 
617
            case LUA_TTABLE:
 
618
                ngx_http_lua_process_args_option(r, L, -1, &extra_args);
 
619
                break;
 
620
 
 
621
            case LUA_TNIL:
 
622
                /* do nothing */
 
623
                break;
 
624
 
 
625
            case LUA_TNUMBER:
 
626
            case LUA_TSTRING:
 
627
                extra_args.data = (u_char *) lua_tolstring(L, -1, &len);
 
628
                extra_args.len = len;
 
629
 
 
630
                break;
 
631
 
 
632
            default:
 
633
                return luaL_error(L, "Bad args option value");
 
634
            }
 
635
 
 
636
            lua_pop(L, 1);
 
637
 
 
638
            /* check the share_all_vars option */
 
639
 
 
640
            lua_getfield(L, 4, "share_all_vars");
 
641
 
 
642
            type = lua_type(L, -1);
 
643
            if (type == LUA_TNIL) {
 
644
                /* do nothing */
 
645
            } else {
 
646
                if (type != LUA_TBOOLEAN) {
 
647
                    return luaL_error(L, "Bad share_all_vars option value");
 
648
                }
 
649
 
 
650
                share_all_vars = lua_toboolean(L, -1);
 
651
            }
 
652
 
 
653
            lua_pop(L, 1);
 
654
 
 
655
            /* check the method option */
 
656
 
 
657
            lua_getfield(L, 4, "method");
 
658
 
 
659
            type = lua_type(L, -1);
 
660
            if (type == LUA_TNIL) {
 
661
                method = NGX_HTTP_GET;
 
662
            } else {
 
663
                if (type != LUA_TNUMBER) {
 
664
                    return luaL_error(L, "Bad http request method");
 
665
                }
 
666
 
 
667
                method = (ngx_uint_t) lua_tonumber(L, -1);
 
668
            }
 
669
 
 
670
            lua_pop(L, 1);
 
671
 
 
672
            /* check the body option */
 
673
 
 
674
            lua_getfield(L, 4, "body");
 
675
 
 
676
            if (type != LUA_TNIL) {
 
677
                if (type != LUA_TSTRING && type != LUA_TNUMBER) {
 
678
                    return luaL_error(L, "Bad http request body");
 
679
                }
 
680
 
 
681
                body = ngx_pcalloc(r->pool,
 
682
                        sizeof(ngx_http_request_body_t));
 
683
 
 
684
                if (body == NULL) {
 
685
                    return luaL_error(L, "out of memory");
 
686
                }
 
687
 
 
688
                q = (u_char *) lua_tolstring(L, -1, &len);
 
689
 
 
690
                dd("request body: [%.*s]", (int) len, q);
 
691
 
 
692
                if (len) {
 
693
                    b = ngx_create_temp_buf(r->pool, len);
 
694
                    if (b == NULL) {
 
695
                        return luaL_error(L, "out of memory");
 
696
                    }
 
697
 
 
698
                    b->last = ngx_copy(b->last, q, len);
 
699
 
 
700
                    body->bufs = ngx_alloc_chain_link(r->pool);
 
701
                    if (body->bufs == NULL) {
 
702
                        return luaL_error(L, "out of memory");
 
703
                    }
 
704
 
 
705
                    body->bufs->buf = b;
 
706
                    body->bufs->next = NULL;
 
707
 
 
708
                    body->buf = b;
 
709
                }
 
710
            }
 
711
 
 
712
            lua_pop(L, 2); /* pop body and opts table */
507
713
        } else {
508
 
            if (type != LUA_TBOOLEAN) {
509
 
                return luaL_error(L, "Bad share_all_vars option value");
510
 
            }
511
 
 
512
 
            share_all_vars = lua_toboolean(L, -1);
513
 
        }
514
 
 
515
 
        lua_pop(L, 1);
516
 
 
517
 
        /* check the method option */
518
 
 
519
 
        lua_getfield(L, 2, "method");
520
 
 
521
 
        type = lua_type(L, -1);
522
 
        if (type == LUA_TNIL) {
523
714
            method = NGX_HTTP_GET;
524
 
        } else {
525
 
            if (type != LUA_TNUMBER) {
526
 
                return luaL_error(L, "Bad http request method");
527
 
            }
528
 
 
529
 
            method = (ngx_uint_t) lua_tonumber(L, -1);
530
 
        }
531
 
 
532
 
        lua_pop(L, 1);
533
 
 
534
 
        /* check the body option */
535
 
 
536
 
        lua_getfield(L, 2, "body");
537
 
 
538
 
        if (type != LUA_TNIL) {
539
 
            if (type != LUA_TSTRING && type != LUA_TNUMBER) {
540
 
                return luaL_error(L, "Bad http request body");
541
 
            }
542
 
 
543
 
            q = (u_char *) lua_tolstring(L, -1, &len);
544
 
            if (len != 0) {
545
 
                body = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
546
 
 
547
 
                b = ngx_create_temp_buf(r->pool, len);
548
 
                if (b == NULL) {
549
 
                    return luaL_error(L, "out of memory");
550
 
                }
551
 
 
552
 
                b->last = ngx_copy(b->last, q, len);
553
 
 
554
 
                body->bufs = ngx_alloc_chain_link(r->pool);
555
 
                if (body->bufs == NULL) {
556
 
                    return luaL_error(L, "out of memory");
557
 
                }
558
 
 
559
 
                body->bufs->buf = b;
560
 
                body->bufs->next = NULL;
561
 
 
562
 
                body->buf = b;
563
 
            }
564
 
        }
565
 
 
566
 
        lua_pop(L, 1);
567
 
 
568
 
    } else {
569
 
        method = NGX_HTTP_GET;
570
 
    }
571
 
 
572
 
    p = (u_char *) luaL_checklstring(L, 1, &len);
573
 
 
574
 
    uri.data = ngx_palloc(r->pool, len);
575
 
    if (uri.data == NULL) {
576
 
        return luaL_error(L, "memory allocation error");
577
 
    }
578
 
 
579
 
    ngx_memcpy(uri.data, p, len);
580
 
 
581
 
    uri.len = len;
582
 
 
583
 
    args.data = NULL;
584
 
    args.len = 0;
585
 
 
586
 
    rc = ngx_http_parse_unsafe_uri(r, &uri, &args, &flags);
587
 
    if (rc != NGX_OK) {
588
 
        dd("rc = %d", (int) rc);
589
 
 
590
 
        return luaL_error(L, "unsafe uri in argument #1: %s", p);
591
 
    }
592
 
 
593
 
    if (args.len == 0) {
594
 
        args = extra_args;
595
 
    } else if (extra_args.len) {
596
 
        /* concatenate the two parts of args together */
597
 
        len = args.len + (sizeof("&") - 1) + extra_args.len;
598
 
 
599
 
        p = ngx_palloc(r->pool, len);
600
 
        if (p == NULL) {
 
715
        }
 
716
 
 
717
        n = lua_gettop(L);
 
718
        dd("top size so far: %d", n);
 
719
 
 
720
        p = (u_char *) luaL_checklstring(L, 3, &len);
 
721
 
 
722
        uri.data = ngx_palloc(r->pool, len);
 
723
        if (uri.data == NULL) {
 
724
            return luaL_error(L, "memory allocation error");
 
725
        }
 
726
 
 
727
        ngx_memcpy(uri.data, p, len);
 
728
 
 
729
        uri.len = len;
 
730
 
 
731
        args.data = NULL;
 
732
        args.len = 0;
 
733
 
 
734
        flags = 0;
 
735
 
 
736
        rc = ngx_http_parse_unsafe_uri(r, &uri, &args, &flags);
 
737
        if (rc != NGX_OK) {
 
738
            dd("rc = %d", (int) rc);
 
739
 
 
740
            return luaL_error(L, "unsafe uri in argument #1: %s", p);
 
741
        }
 
742
 
 
743
        if (args.len == 0) {
 
744
            args = extra_args;
 
745
 
 
746
        } else if (extra_args.len) {
 
747
            /* concatenate the two parts of args together */
 
748
            len = args.len + (sizeof("&") - 1) + extra_args.len;
 
749
 
 
750
            p = ngx_palloc(r->pool, len);
 
751
            if (p == NULL) {
 
752
                return luaL_error(L, "out of memory");
 
753
            }
 
754
 
 
755
            q = ngx_copy(p, args.data, args.len);
 
756
            *q++ = '&';
 
757
            q = ngx_copy(q, extra_args.data, extra_args.len);
 
758
 
 
759
            args.data = p;
 
760
            args.len = len;
 
761
        }
 
762
 
 
763
        psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
 
764
        if (psr == NULL) {
 
765
            return luaL_error(L, "memory allocation error");
 
766
        }
 
767
 
 
768
        sr_ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_lua_ctx_t));
 
769
        if (sr_ctx == NULL) {
601
770
            return luaL_error(L, "out of memory");
602
771
        }
603
772
 
604
 
        q = ngx_copy(p, args.data, args.len);
605
 
        *q++ = '&';
606
 
        q = ngx_copy(q, extra_args.data, extra_args.len);
607
 
 
608
 
        args.data = p;
609
 
        args.len = len;
610
 
    }
611
 
 
612
 
    psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
613
 
    if (psr == NULL) {
614
 
        return luaL_error(L, "memory allocation error");
615
 
    }
616
 
 
617
 
    sr_ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_lua_ctx_t));
618
 
    if (sr_ctx == NULL) {
619
 
        return luaL_error(L, "memory allocation error");
620
 
    }
621
 
 
622
 
    sr_ctx->capture = 1;
623
 
 
624
 
    psr->handler = ngx_http_lua_post_subrequest;
625
 
    psr->data = sr_ctx;
626
 
 
627
 
    rc = ngx_http_subrequest(r, &uri, &args, &sr, psr, 0);
628
 
 
629
 
    if (rc != NGX_OK) {
630
 
        return luaL_error(L, "failed to issue subrequest: %d", (int) rc);
631
 
    }
632
 
 
633
 
    ngx_http_set_ctx(sr, sr_ctx, ngx_http_lua_module);
634
 
 
635
 
    rc = ngx_http_lua_adjust_subrequest(sr, method, body, share_all_vars);
636
 
 
637
 
    if (rc != NGX_OK) {
638
 
        return luaL_error(L, "failed to adjust the subrequest: %d", (int) rc);
 
773
        /* set by ngx_pcalloc:
 
774
         *      sr_ctx->run_post_subrequest = 0
 
775
         *      sr_ctx->free = NULL
 
776
         */
 
777
 
 
778
        sr_ctx->cc_ref = LUA_NOREF;
 
779
 
 
780
        sr_ctx->capture = 1;
 
781
 
 
782
        sr_ctx->index = index;
 
783
 
 
784
        psr->handler = ngx_http_lua_post_subrequest;
 
785
        psr->data = sr_ctx;
 
786
 
 
787
        rc = ngx_http_subrequest(r, &uri, &args, &sr, psr, 0);
 
788
 
 
789
        if (rc != NGX_OK) {
 
790
            return luaL_error(L, "failed to issue subrequest: %d", (int) rc);
 
791
        }
 
792
 
 
793
        ngx_http_set_ctx(sr, sr_ctx, ngx_http_lua_module);
 
794
 
 
795
        rc = ngx_http_lua_adjust_subrequest(sr, method, body, share_all_vars);
 
796
 
 
797
        if (rc != NGX_OK) {
 
798
            return luaL_error(L, "failed to adjust the subrequest: %d",
 
799
                    (int) rc);
 
800
        }
 
801
 
 
802
        lua_pop(L, 2); /* pop the subrequest argument and uri */
639
803
    }
640
804
 
641
805
    lua_pushinteger(L, location_capture);
667
831
        sr->request_body = body;
668
832
 
669
833
        rc = ngx_http_lua_set_content_length_header(sr,
670
 
                ngx_buf_size(body->buf));
 
834
                body->buf ? ngx_buf_size(body->buf) : 0);
671
835
 
672
836
        if (rc != NGX_OK) {
673
837
            return NGX_ERROR;
714
878
        cmcf = ngx_http_get_module_main_conf(sr, ngx_http_core_module);
715
879
 
716
880
        sr->variables = ngx_pcalloc(sr->pool, cmcf->variables.nelts
717
 
                                            * sizeof(ngx_http_variable_value_t));
 
881
                                * sizeof(ngx_http_variable_value_t));
718
882
 
719
883
        if (sr->variables == NULL) {
720
884
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
731
895
    ngx_http_request_t            *pr;
732
896
    ngx_http_lua_ctx_t            *pr_ctx;
733
897
    ngx_http_lua_ctx_t            *ctx = data;
 
898
    size_t                         len;
 
899
    ngx_str_t                     *body_str;
 
900
    u_char                        *p;
 
901
    ngx_chain_t                   *cl;
 
902
 
 
903
    dd("uri %.*s, rc:%d, waiting: %d, done:%d", (int) r->uri.len, r->uri.data,
 
904
            (int) rc, (int) ctx->waiting, (int) ctx->done);
 
905
 
 
906
    if (ctx->run_post_subrequest) {
 
907
        return rc;
 
908
    }
 
909
 
 
910
    ctx->run_post_subrequest = 1;
 
911
 
 
912
#if 0
 
913
    ngx_http_lua_dump_postponed(r);
 
914
#endif
734
915
 
735
916
    pr = r->parent;
736
917
 
739
920
        return NGX_ERROR;
740
921
    }
741
922
 
742
 
    pr_ctx->waiting = 0;
743
 
    pr_ctx->done = 1;
744
 
 
745
 
    pr->write_event_handler = ngx_http_lua_wev_handler;
 
923
    pr_ctx->waiting--;
 
924
 
 
925
    if (pr_ctx->waiting == 0) {
 
926
        pr_ctx->done = 1;
 
927
    }
 
928
 
 
929
    if (pr_ctx->entered_content_phase) {
 
930
        dd("setting wev handler");
 
931
        pr->write_event_handler = ngx_http_lua_content_wev_handler;
 
932
    }
 
933
 
 
934
    dd("status rc = %d", (int) rc);
 
935
    dd("status headers_out.status = %d", (int) r->headers_out.status);
 
936
    dd("uri: %.*s", (int) r->uri.len, r->uri.data);
746
937
 
747
938
    /*  capture subrequest response status */
748
939
    if (rc == NGX_ERROR) {
749
 
        pr_ctx->sr_status = NGX_HTTP_INTERNAL_SERVER_ERROR;
 
940
        pr_ctx->sr_statuses[ctx->index] = NGX_HTTP_INTERNAL_SERVER_ERROR;
 
941
 
750
942
    } else if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
751
 
        pr_ctx->sr_status = rc;
 
943
        dd("HERE");
 
944
        pr_ctx->sr_statuses[ctx->index] = rc;
 
945
 
752
946
    } else {
753
 
        pr_ctx->sr_status = r->headers_out.status;
754
 
    }
755
 
 
756
 
    /*  copy subrequest response body */
757
 
    pr_ctx->sr_body = ctx->body;
 
947
        dd("THERE");
 
948
        pr_ctx->sr_statuses[ctx->index] = r->headers_out.status;
 
949
    }
 
950
 
 
951
    if (pr_ctx->sr_statuses[ctx->index] == 0) {
 
952
        pr_ctx->sr_statuses[ctx->index] = NGX_HTTP_OK;
 
953
    }
 
954
 
 
955
    dd("pr_ctx status: %d", (int) pr_ctx->sr_statuses[ctx->index]);
758
956
 
759
957
    /* copy subrequest response headers */
760
 
    pr_ctx->sr_headers = &r->headers_out;
761
 
 
762
 
    /* ensure that the parent request is (or will be)
763
 
     *  posted out the head of the r->posted_requests chain */
764
 
 
765
 
    if (r->main->posted_requests
766
 
            && r->main->posted_requests->request != pr)
 
958
 
 
959
    pr_ctx->sr_headers[ctx->index] = &r->headers_out;
 
960
 
 
961
    /* copy subrequest response body */
 
962
 
 
963
    body_str = &pr_ctx->sr_bodies[ctx->index];
 
964
 
 
965
    if (ctx->body && ctx->body->next == NULL) {
 
966
        /* optimize for the single buf body */
 
967
 
 
968
        cl = ctx->body;
 
969
 
 
970
        len = cl->buf->last - cl->buf->pos;
 
971
 
 
972
        body_str->len = len;
 
973
 
 
974
        if (len == 0) {
 
975
            body_str->data = NULL;
 
976
 
 
977
        } else {
 
978
            body_str->data = cl->buf->pos;
 
979
        }
 
980
 
 
981
    } else {
 
982
        len = 0;
 
983
        for (cl = ctx->body; cl; cl = cl->next) {
 
984
            /*  ignore all non-memory buffers */
 
985
            len += cl->buf->last - cl->buf->pos;
 
986
        }
 
987
 
 
988
        body_str->len = len;
 
989
 
 
990
        if (len == 0) {
 
991
            body_str->data = NULL;
 
992
 
 
993
        } else {
 
994
            p = ngx_palloc(r->pool, len);
 
995
            if (p == NULL) {
 
996
                return NGX_ERROR;
 
997
            }
 
998
 
 
999
            body_str->data = p;
 
1000
 
 
1001
            /* copy from and then free the data buffers */
 
1002
 
 
1003
            for (cl = ctx->body; cl; cl = cl->next) {
 
1004
                p = ngx_copy(p, cl->buf->pos,
 
1005
                        cl->buf->last - cl->buf->pos);
 
1006
 
 
1007
                dd("free bod chain link buf ASAP");
 
1008
                ngx_pfree(r->pool, cl->buf->start);
 
1009
            }
 
1010
        }
 
1011
    }
 
1012
 
 
1013
    if (ctx->body) {
 
1014
        /* free the ctx->body chain such that it can be reused by
 
1015
         * other subrequests */
 
1016
 
 
1017
        if (pr_ctx->free == NULL) {
 
1018
            pr_ctx->free = ctx->body;
 
1019
 
 
1020
        } else {
 
1021
            for (cl = pr_ctx->free; cl->next; cl = cl->next) { /* void */ }
 
1022
 
 
1023
            cl->next = ctx->body;
 
1024
        }
 
1025
    }
 
1026
 
 
1027
    /* work-around issues in nginx's event module */
 
1028
 
 
1029
    if (r != r->connection->data && r->postponed &&
 
1030
            (r->main->posted_requests == NULL ||
 
1031
            r->main->posted_requests->request != pr))
767
1032
    {
768
 
        rc = ngx_http_lua_post_request_at_head(pr, NULL);
769
 
        if (rc != NGX_OK) {
770
 
            return NGX_ERROR;
771
 
        }
 
1033
#if defined(nginx_version) && nginx_version >= 8012
 
1034
        ngx_http_post_request(pr, NULL);
 
1035
#else
 
1036
        ngx_http_post_request(pr);
 
1037
#endif
772
1038
    }
773
1039
 
774
1040
    return rc;
1148
1414
ngx_http_lua_ngx_md5(lua_State *L)
1149
1415
{
1150
1416
    ngx_http_request_t      *r;
1151
 
    u_char                  *p = NULL;
1152
1417
    u_char                  *src;
1153
 
    size_t                   len, slen;
 
1418
    size_t                   slen;
 
1419
 
 
1420
    ngx_md5_t                md5;
 
1421
    u_char                   md5_buf[MD5_DIGEST_LENGTH];
 
1422
    u_char                   hex_buf[2 * sizeof(md5_buf)];
1154
1423
 
1155
1424
    lua_getglobal(L, GLOBALS_SYMBOL_REQUEST);
1156
1425
    r = lua_touserdata(L, -1);
1157
1426
    lua_pop(L, 1);
1158
1427
 
1159
 
    len = MD5_DIGEST_LENGTH * 2;
1160
 
 
1161
1428
    if (r == NULL) {
1162
1429
        return luaL_error(L, "no request object found");
1163
1430
    }
1169
1436
    if (strcmp(luaL_typename(L, 1), (char *) "nil") == 0) {
1170
1437
        src     = (u_char *) "";
1171
1438
        slen    = 0;
 
1439
 
1172
1440
    } else {
1173
1441
        src = (u_char *) luaL_checklstring(L, 1, &slen);
1174
1442
    }
1175
1443
 
1176
 
    p = ngx_palloc(r->pool, len);
1177
 
    if (p == NULL) {
1178
 
        return NGX_ERROR;
1179
 
    }
1180
 
 
1181
 
    ndk_md5_hash(p, (char *) src, slen);
1182
 
 
1183
 
    lua_pushlstring(L, (char *) p, len);
 
1444
    ngx_md5_init(&md5);
 
1445
    ngx_md5_update(&md5, src, slen);
 
1446
    ngx_md5_final(md5_buf, &md5);
 
1447
 
 
1448
    ngx_hex_dump(hex_buf, md5_buf, sizeof(md5_buf));
 
1449
 
 
1450
    lua_pushlstring(L, (char *) hex_buf, sizeof(hex_buf));
1184
1451
 
1185
1452
    return 1;
1186
1453
}
1190
1457
ngx_http_lua_ngx_md5_bin(lua_State *L)
1191
1458
{
1192
1459
    ngx_http_request_t      *r;
1193
 
    u_char                  *p = NULL;
1194
1460
    u_char                  *src;
1195
 
    size_t                   len, slen;
 
1461
    size_t                   slen;
 
1462
 
1196
1463
    ngx_md5_t                md5;
 
1464
    u_char                   md5_buf[MD5_DIGEST_LENGTH];
1197
1465
 
1198
1466
    lua_getglobal(L, GLOBALS_SYMBOL_REQUEST);
1199
1467
    r = lua_touserdata(L, -1);
1200
1468
    lua_pop(L, 1);
1201
1469
 
1202
 
    len = MD5_DIGEST_LENGTH;
1203
 
 
1204
1470
    if (r == NULL) {
1205
1471
        return luaL_error(L, "no request object found");
1206
1472
    }
1212
1478
    if (strcmp(luaL_typename(L, 1), (char *) "nil") == 0) {
1213
1479
        src     = (u_char *) "";
1214
1480
        slen    = 0;
 
1481
 
1215
1482
    } else {
1216
1483
        src = (u_char *) luaL_checklstring(L, 1, &slen);
1217
1484
    }
1218
1485
 
1219
1486
    dd("slen: %d", (int) slen);
1220
1487
 
1221
 
    p = ngx_palloc(r->pool, len);
1222
 
    if (p == NULL) {
1223
 
        return NGX_ERROR;
1224
 
    }
1225
 
 
1226
1488
    ngx_md5_init(&md5);
1227
 
    ngx_md5_update(&md5, (char *) src, slen);
1228
 
    ngx_md5_final(p, &md5);
1229
 
 
1230
 
    dd("len: %d", (int) len);
1231
 
 
1232
 
    lua_pushlstring(L, (char *) p, len);
1233
 
 
1234
 
    ngx_pfree(r->pool, p);
 
1489
    ngx_md5_update(&md5, src, slen);
 
1490
    ngx_md5_final(md5_buf, &md5);
 
1491
 
 
1492
    lua_pushlstring(L, (char *) md5_buf, sizeof(md5_buf));
1235
1493
 
1236
1494
    return 1;
1237
1495
}
1741
1999
                dd("header value table index %d", (int) i);
1742
2000
 
1743
2001
                lua_rawgeti(L, 3, i);
1744
 
                p = (u_char*) luaL_checklstring(L, -1, &len);
 
2002
                p = (u_char *) luaL_checklstring(L, -1, &len);
1745
2003
 
1746
2004
                value.data = ngx_palloc(r->pool, len);
1747
2005
                if (value.data == NULL) {
1765
2023
        }
1766
2024
 
1767
2025
    } else {
1768
 
        p = (u_char*) luaL_checklstring(L, 3, &len);
 
2026
        p = (u_char *) luaL_checklstring(L, 3, &len);
1769
2027
        value.data = ngx_palloc(r->pool, len);
1770
2028
        if (value.data == NULL) {
1771
2029
            return luaL_error(L, "out of memory");
1909
2167
    lua_pushvalue(L, -1); /* table key key key */
1910
2168
 
1911
2169
    lua_pushlightuserdata(L, func); /* table key key key func */
1912
 
    lua_pushcclosure(L, ngx_http_lua_run_set_var_directive, 2); /* table key key closure */
 
2170
 
 
2171
    lua_pushcclosure(L, ngx_http_lua_run_set_var_directive, 2);
 
2172
        /* table key key closure */
1913
2173
 
1914
2174
    lua_rawset(L, 1); /* table key */
1915
2175
 
1962
2222
                continue;
1963
2223
            }
1964
2224
 
1965
 
            return filter->func;
 
2225
            return (ndk_set_var_value_pt)(filter->func);
1966
2226
        }
1967
2227
    }
1968
2228
 
2000
2260
 
2001
2261
    dd("calling set_var func for %s", p);
2002
2262
 
2003
 
    func = lua_touserdata(L, lua_upvalueindex(2));
 
2263
    func = (ndk_set_var_value_pt)lua_touserdata(L, lua_upvalueindex(2));
2004
2264
 
2005
2265
    rc = func(r, &res, &arg);
2006
2266
 
2144
2404
    }
2145
2405
 
2146
2406
    if (ctx->headers_sent) {
2147
 
        return luaL_error(L, "attempt to call ngx.redirect after sending out the headers");
 
2407
        return luaL_error(L, "attempt to call ngx.redirect after sending out "
 
2408
                "the headers");
2148
2409
    }
2149
2410
 
2150
2411
    uri = ngx_palloc(r->pool, len);
2199
2460
 
2200
2461
        key = (u_char *) lua_tolstring(L, -2, &key_len);
2201
2462
 
2202
 
        total_escape += 2 * ngx_http_lua_escape_uri(NULL, key, key_len, NGX_ESCAPE_URI);
 
2463
        total_escape += 2 * ngx_http_lua_escape_uri(NULL, key, key_len,
 
2464
                NGX_ESCAPE_URI);
2203
2465
 
2204
2466
        value = (u_char *) lua_tolstring(L, -1, &value_len);
2205
2467
 
2206
 
        total_escape += 2 * ngx_http_lua_escape_uri(NULL, value, value_len, NGX_ESCAPE_URI);
 
2468
        total_escape += 2 * ngx_http_lua_escape_uri(NULL, value, value_len,
 
2469
                NGX_ESCAPE_URI);
2207
2470
 
2208
2471
        len += key_len + value_len + (sizeof("=") - 1);
2209
2472
 
2235
2498
        key = (u_char *) lua_tolstring(L, -2, &key_len);
2236
2499
 
2237
2500
        if (total_escape) {
2238
 
            p = (u_char *) ngx_http_lua_escape_uri(p, key, key_len, NGX_ESCAPE_URI);
 
2501
            p = (u_char *) ngx_http_lua_escape_uri(p, key, key_len,
 
2502
                    NGX_ESCAPE_URI);
2239
2503
 
2240
2504
        } else {
2241
2505
            dd("shortcut: no escape required");
2248
2512
        value = (u_char *) lua_tolstring(L, -1, &value_len);
2249
2513
 
2250
2514
        if (total_escape) {
2251
 
            p = (u_char *) ngx_http_lua_escape_uri(p, value, value_len, NGX_ESCAPE_URI);
 
2515
            p = (u_char *) ngx_http_lua_escape_uri(p, value, value_len,
 
2516
                    NGX_ESCAPE_URI);
 
2517
 
2252
2518
        } else {
2253
2519
            p = ngx_copy(p, value, value_len);
2254
2520
        }