Return to nginx.xs CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / nginx / src / http / modules / perl |
1.1 misho 1: 2: /* 3: * Copyright (C) Igor Sysoev 4: * Copyright (C) Nginx, Inc. 5: */ 6: 7: 8: #define PERL_NO_GET_CONTEXT 9: 10: #include <ngx_config.h> 11: #include <ngx_core.h> 12: #include <ngx_http.h> 13: #include <ngx_http_perl_module.h> 14: 15: #include "XSUB.h" 16: 17: 18: #define ngx_http_perl_set_request(r) \ 19: r = INT2PTR(ngx_http_request_t *, SvIV((SV *) SvRV(ST(0)))) 20: 21: 22: #define ngx_http_perl_set_targ(p, len) \ 23: \ 24: SvUPGRADE(TARG, SVt_PV); \ 25: SvPOK_on(TARG); \ 26: sv_setpvn(TARG, (char *) p, len) 27: 28: 29: static ngx_int_t 30: ngx_http_perl_sv2str(pTHX_ ngx_http_request_t *r, ngx_str_t *s, SV *sv) 31: { 32: u_char *p; 33: STRLEN len; 34: 35: if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { 36: sv = SvRV(sv); 37: } 38: 39: p = (u_char *) SvPV(sv, len); 40: 41: s->len = len; 42: 43: if (SvREADONLY(sv) && SvPOK(sv)) { 44: s->data = p; 45: 46: ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 47: "perl sv2str: %08XD \"%V\"", sv->sv_flags, s); 48: 49: return NGX_OK; 50: } 51: 52: s->data = ngx_pnalloc(r->pool, len); 53: if (s->data == NULL) { 54: return NGX_ERROR; 55: } 56: 57: ngx_memcpy(s->data, p, len); 58: 59: ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 60: "perl sv2str: %08XD \"%V\"", sv->sv_flags, s); 61: 62: return NGX_OK; 63: } 64: 65: 66: static ngx_int_t 67: ngx_http_perl_output(ngx_http_request_t *r, ngx_buf_t *b) 68: { 69: ngx_chain_t out; 70: #if (NGX_HTTP_SSI) 71: ngx_chain_t *cl; 72: ngx_http_perl_ctx_t *ctx; 73: 74: ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); 75: 76: if (ctx->ssi) { 77: cl = ngx_alloc_chain_link(r->pool); 78: if (cl == NULL) { 79: return NGX_ERROR; 80: } 81: 82: cl->buf = b; 83: cl->next = NULL; 84: *ctx->ssi->last_out = cl; 85: ctx->ssi->last_out = &cl->next; 86: 87: return NGX_OK; 88: } 89: #endif 90: 91: out.buf = b; 92: out.next = NULL; 93: 94: return ngx_http_output_filter(r, &out); 95: } 96: 97: 98: MODULE = nginx PACKAGE = nginx 99: 100: 101: void 102: status(r, code) 103: CODE: 104: 105: ngx_http_request_t *r; 106: 107: ngx_http_perl_set_request(r); 108: 109: r->headers_out.status = SvIV(ST(1)); 110: 111: ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 112: "perl status: %d", r->headers_out.status); 113: 114: XSRETURN_UNDEF; 115: 116: 117: void 118: send_http_header(r, ...) 119: CODE: 120: 121: ngx_http_request_t *r; 122: SV *sv; 123: 124: ngx_http_perl_set_request(r); 125: 126: if (r->headers_out.status == 0) { 127: r->headers_out.status = NGX_HTTP_OK; 128: } 129: 130: if (items != 1) { 131: sv = ST(1); 132: 133: if (ngx_http_perl_sv2str(aTHX_ r, &r->headers_out.content_type, sv) 134: != NGX_OK) 135: { 136: XSRETURN_EMPTY; 137: } 138: 139: r->headers_out.content_type_len = r->headers_out.content_type.len; 140: 141: } else { 142: if (ngx_http_set_content_type(r) != NGX_OK) { 143: XSRETURN_EMPTY; 144: } 145: } 146: 147: (void) ngx_http_send_header(r); 148: 149: 150: void 151: header_only(r) 152: CODE: 153: 154: dXSTARG; 155: ngx_http_request_t *r; 156: 157: ngx_http_perl_set_request(r); 158: 159: sv_upgrade(TARG, SVt_IV); 160: sv_setiv(TARG, r->header_only); 161: 162: ST(0) = TARG; 163: 164: 165: void 166: uri(r) 167: CODE: 168: 169: dXSTARG; 170: ngx_http_request_t *r; 171: 172: ngx_http_perl_set_request(r); 173: ngx_http_perl_set_targ(r->uri.data, r->uri.len); 174: 175: ST(0) = TARG; 176: 177: 178: void 179: args(r) 180: CODE: 181: 182: dXSTARG; 183: ngx_http_request_t *r; 184: 185: ngx_http_perl_set_request(r); 186: ngx_http_perl_set_targ(r->args.data, r->args.len); 187: 188: ST(0) = TARG; 189: 190: 191: void 192: request_method(r) 193: CODE: 194: 195: dXSTARG; 196: ngx_http_request_t *r; 197: 198: ngx_http_perl_set_request(r); 199: ngx_http_perl_set_targ(r->method_name.data, r->method_name.len); 200: 201: ST(0) = TARG; 202: 203: 204: void 205: remote_addr(r) 206: CODE: 207: 208: dXSTARG; 209: ngx_http_request_t *r; 210: 211: ngx_http_perl_set_request(r); 212: ngx_http_perl_set_targ(r->connection->addr_text.data, 213: r->connection->addr_text.len); 214: 215: ST(0) = TARG; 216: 217: 218: void 219: header_in(r, key) 220: CODE: 221: 222: dXSTARG; 223: ngx_http_request_t *r; 224: SV *key; 225: u_char *p, *lowcase_key, *value, sep; 226: STRLEN len; 227: ssize_t size; 228: ngx_uint_t i, n, hash; 229: ngx_array_t *a; 230: ngx_list_part_t *part; 231: ngx_table_elt_t *h, **ph; 232: ngx_http_header_t *hh; 233: ngx_http_core_main_conf_t *cmcf; 234: 235: ngx_http_perl_set_request(r); 236: 237: key = ST(1); 238: 239: if (SvROK(key) && SvTYPE(SvRV(key)) == SVt_PV) { 240: key = SvRV(key); 241: } 242: 243: p = (u_char *) SvPV(key, len); 244: 245: /* look up hashed headers */ 246: 247: lowcase_key = ngx_pnalloc(r->pool, len); 248: if (lowcase_key == NULL) { 249: XSRETURN_UNDEF; 250: } 251: 252: hash = ngx_hash_strlow(lowcase_key, p, len); 253: 254: cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); 255: 256: hh = ngx_hash_find(&cmcf->headers_in_hash, hash, lowcase_key, len); 257: 258: if (hh) { 259: 260: if (hh->offset == offsetof(ngx_http_headers_in_t, cookies)) { 261: sep = ';'; 262: goto multi; 263: } 264: 265: #if (NGX_HTTP_X_FORWARDED_FOR) 266: if (hh->offset == offsetof(ngx_http_headers_in_t, x_forwarded_for)) { 267: sep = ','; 268: goto multi; 269: } 270: #endif 271: 272: if (hh->offset) { 273: 274: ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset); 275: 276: if (*ph) { 277: ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); 278: 279: goto done; 280: } 281: 282: XSRETURN_UNDEF; 283: } 284: 285: multi: 286: 287: /* Cookie, X-Forwarded-For */ 288: 289: a = (ngx_array_t *) ((char *) &r->headers_in + hh->offset); 290: 291: n = a->nelts; 292: 293: if (n == 0) { 294: XSRETURN_UNDEF; 295: } 296: 297: ph = a->elts; 298: 299: if (n == 1) { 300: ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); 301: 302: goto done; 303: } 304: 305: size = - (ssize_t) (sizeof("; ") - 1); 306: 307: for (i = 0; i < n; i++) { 308: size += ph[i]->value.len + sizeof("; ") - 1; 309: } 310: 311: value = ngx_pnalloc(r->pool, size); 312: if (value == NULL) { 313: XSRETURN_UNDEF; 314: } 315: 316: p = value; 317: 318: for (i = 0; /* void */ ; i++) { 319: p = ngx_copy(p, ph[i]->value.data, ph[i]->value.len); 320: 321: if (i == n - 1) { 322: break; 323: } 324: 325: *p++ = sep; *p++ = ' '; 326: } 327: 328: ngx_http_perl_set_targ(value, size); 329: 330: goto done; 331: } 332: 333: /* iterate over all headers */ 334: 335: part = &r->headers_in.headers.part; 336: h = part->elts; 337: 338: for (i = 0; /* void */ ; i++) { 339: 340: if (i >= part->nelts) { 341: if (part->next == NULL) { 342: break; 343: } 344: 345: part = part->next; 346: h = part->elts; 347: i = 0; 348: } 349: 350: if (len != h[i].key.len 351: || ngx_strcasecmp(p, h[i].key.data) != 0) 352: { 353: continue; 354: } 355: 356: ngx_http_perl_set_targ(h[i].value.data, h[i].value.len); 357: 358: goto done; 359: } 360: 361: XSRETURN_UNDEF; 362: 363: done: 364: 365: ST(0) = TARG; 366: 367: 368: void 369: has_request_body(r, next) 370: CODE: 371: 372: dXSTARG; 373: ngx_http_request_t *r; 374: ngx_http_perl_ctx_t *ctx; 375: 376: ngx_http_perl_set_request(r); 377: 378: if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) { 379: XSRETURN_UNDEF; 380: } 381: 382: ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); 383: ctx->next = SvRV(ST(1)); 384: 385: r->request_body_in_single_buf = 1; 386: r->request_body_in_persistent_file = 1; 387: r->request_body_in_clean_file = 1; 388: 389: if (r->request_body_in_file_only) { 390: r->request_body_file_log_level = 0; 391: } 392: 393: ngx_http_read_client_request_body(r, ngx_http_perl_handle_request); 394: 395: sv_upgrade(TARG, SVt_IV); 396: sv_setiv(TARG, 1); 397: 398: ST(0) = TARG; 399: 400: 401: void 402: request_body(r) 403: CODE: 404: 405: dXSTARG; 406: ngx_http_request_t *r; 407: u_char *p, *data; 408: size_t len; 409: ngx_buf_t *buf; 410: ngx_chain_t *cl; 411: 412: ngx_http_perl_set_request(r); 413: 414: if (r->request_body == NULL 415: || r->request_body->temp_file 416: || r->request_body->bufs == NULL) 417: { 418: XSRETURN_UNDEF; 419: } 420: 421: cl = r->request_body->bufs; 422: buf = cl->buf; 423: 424: if (cl->next == NULL) { 425: len = buf->last - buf->pos; 426: data = buf->pos; 427: goto done; 428: } 429: 430: len = buf->last - buf->pos; 431: cl = cl->next; 432: 433: for ( /* void */ ; cl; cl = cl->next) { 434: buf = cl->buf; 435: len += buf->last - buf->pos; 436: } 437: 438: p = ngx_pnalloc(r->pool, len); 439: if (p == NULL) { 440: XSRETURN_UNDEF; 441: } 442: 443: data = p; 444: cl = r->request_body->bufs; 445: 446: for ( /* void */ ; cl; cl = cl->next) { 447: buf = cl->buf; 448: p = ngx_cpymem(p, buf->pos, buf->last - buf->pos); 449: } 450: 451: done: 452: 453: if (len == 0) { 454: XSRETURN_UNDEF; 455: } 456: 457: ngx_http_perl_set_targ(data, len); 458: 459: ST(0) = TARG; 460: 461: 462: void 463: request_body_file(r) 464: CODE: 465: 466: dXSTARG; 467: ngx_http_request_t *r; 468: 469: ngx_http_perl_set_request(r); 470: 471: if (r->request_body == NULL || r->request_body->temp_file == NULL) { 472: XSRETURN_UNDEF; 473: } 474: 475: ngx_http_perl_set_targ(r->request_body->temp_file->file.name.data, 476: r->request_body->temp_file->file.name.len); 477: 478: ST(0) = TARG; 479: 480: 481: void 482: discard_request_body(r) 483: CODE: 484: 485: ngx_http_request_t *r; 486: 487: ngx_http_perl_set_request(r); 488: 489: ngx_http_discard_request_body(r); 490: 491: 492: void 493: header_out(r, key, value) 494: CODE: 495: 496: ngx_http_request_t *r; 497: SV *key; 498: SV *value; 499: ngx_table_elt_t *header; 500: 501: ngx_http_perl_set_request(r); 502: 503: key = ST(1); 504: value = ST(2); 505: 506: header = ngx_list_push(&r->headers_out.headers); 507: if (header == NULL) { 508: XSRETURN_EMPTY; 509: } 510: 511: header->hash = 1; 512: 513: if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) { 514: XSRETURN_EMPTY; 515: } 516: 517: if (ngx_http_perl_sv2str(aTHX_ r, &header->value, value) != NGX_OK) { 518: XSRETURN_EMPTY; 519: } 520: 521: if (header->key.len == sizeof("Content-Length") - 1 522: && ngx_strncasecmp(header->key.data, (u_char *) "Content-Length", 523: sizeof("Content-Length") - 1) == 0) 524: { 525: r->headers_out.content_length_n = (off_t) SvIV(value); 526: r->headers_out.content_length = header; 527: } 528: 529: if (header->key.len == sizeof("Content-Encoding") - 1 530: && ngx_strncasecmp(header->key.data, (u_char *) "Content-Encoding", 531: sizeof("Content-Encoding") - 1) == 0) 532: { 533: r->headers_out.content_encoding = header; 534: } 535: 536: 537: void 538: filename(r) 539: CODE: 540: 541: dXSTARG; 542: size_t root; 543: ngx_http_request_t *r; 544: ngx_http_perl_ctx_t *ctx; 545: 546: ngx_http_perl_set_request(r); 547: 548: ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); 549: if (ctx->filename.data) { 550: goto done; 551: } 552: 553: if (ngx_http_map_uri_to_path(r, &ctx->filename, &root, 0) == NULL) { 554: XSRETURN_UNDEF; 555: } 556: 557: ctx->filename.len--; 558: sv_setpv(PL_statname, (char *) ctx->filename.data); 559: 560: done: 561: 562: ngx_http_perl_set_targ(ctx->filename.data, ctx->filename.len); 563: 564: ST(0) = TARG; 565: 566: 567: void 568: print(r, ...) 569: CODE: 570: 571: ngx_http_request_t *r; 572: SV *sv; 573: int i; 574: u_char *p; 575: size_t size; 576: STRLEN len; 577: ngx_buf_t *b; 578: 579: ngx_http_perl_set_request(r); 580: 581: if (items == 2) { 582: 583: /* 584: * do zero copy for prolate single read-only SV: 585: * $r->print("some text\n"); 586: */ 587: 588: sv = ST(1); 589: 590: if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { 591: sv = SvRV(sv); 592: } 593: 594: if (SvREADONLY(sv) && SvPOK(sv)) { 595: 596: p = (u_char *) SvPV(sv, len); 597: 598: if (len == 0) { 599: XSRETURN_EMPTY; 600: } 601: 602: b = ngx_calloc_buf(r->pool); 603: if (b == NULL) { 604: XSRETURN_EMPTY; 605: } 606: 607: b->memory = 1; 608: b->pos = p; 609: b->last = p + len; 610: b->start = p; 611: b->end = b->last; 612: 613: ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 614: "$r->print: read-only SV: %z", len); 615: 616: goto out; 617: } 618: } 619: 620: size = 0; 621: 622: for (i = 1; i < items; i++) { 623: 624: sv = ST(i); 625: 626: if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { 627: sv = SvRV(sv); 628: } 629: 630: (void) SvPV(sv, len); 631: 632: ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 633: "$r->print: copy SV: %z", len); 634: 635: size += len; 636: } 637: 638: if (size == 0) { 639: XSRETURN_EMPTY; 640: } 641: 642: b = ngx_create_temp_buf(r->pool, size); 643: if (b == NULL) { 644: XSRETURN_EMPTY; 645: } 646: 647: for (i = 1; i < items; i++) { 648: sv = ST(i); 649: 650: if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { 651: sv = SvRV(sv); 652: } 653: 654: p = (u_char *) SvPV(sv, len); 655: b->last = ngx_cpymem(b->last, p, len); 656: } 657: 658: out: 659: 660: (void) ngx_http_perl_output(r, b); 661: 662: 663: void 664: sendfile(r, filename, offset = -1, bytes = 0) 665: CODE: 666: 667: ngx_http_request_t *r; 668: char *filename; 669: off_t offset; 670: size_t bytes; 671: ngx_str_t path; 672: ngx_buf_t *b; 673: ngx_open_file_info_t of; 674: ngx_http_core_loc_conf_t *clcf; 675: 676: ngx_http_perl_set_request(r); 677: 678: filename = SvPV_nolen(ST(1)); 679: 680: if (filename == NULL) { 681: croak("sendfile(): NULL filename"); 682: } 683: 684: offset = items < 3 ? -1 : SvIV(ST(2)); 685: bytes = items < 4 ? 0 : SvIV(ST(3)); 686: 687: b = ngx_calloc_buf(r->pool); 688: if (b == NULL) { 689: XSRETURN_EMPTY; 690: } 691: 692: b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)); 693: if (b->file == NULL) { 694: XSRETURN_EMPTY; 695: } 696: 697: path.len = ngx_strlen(filename); 698: 699: path.data = ngx_pnalloc(r->pool, path.len + 1); 700: if (path.data == NULL) { 701: XSRETURN_EMPTY; 702: } 703: 704: (void) ngx_cpystrn(path.data, (u_char *) filename, path.len + 1); 705: 706: clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 707: 708: ngx_memzero(&of, sizeof(ngx_open_file_info_t)); 709: 710: of.read_ahead = clcf->read_ahead; 711: of.directio = clcf->directio; 712: of.valid = clcf->open_file_cache_valid; 713: of.min_uses = clcf->open_file_cache_min_uses; 714: of.errors = clcf->open_file_cache_errors; 715: of.events = clcf->open_file_cache_events; 716: 717: if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) { 718: XSRETURN_EMPTY; 719: } 720: 721: if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) 722: != NGX_OK) 723: { 724: if (of.err == 0) { 725: XSRETURN_EMPTY; 726: } 727: 728: ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, 729: "%s \"%s\" failed", of.failed, filename); 730: XSRETURN_EMPTY; 731: } 732: 733: if (offset == -1) { 734: offset = 0; 735: } 736: 737: if (bytes == 0) { 738: bytes = of.size - offset; 739: } 740: 741: b->in_file = 1; 742: 743: b->file_pos = offset; 744: b->file_last = offset + bytes; 745: 746: b->file->fd = of.fd; 747: b->file->log = r->connection->log; 748: b->file->directio = of.is_directio; 749: 750: (void) ngx_http_perl_output(r, b); 751: 752: 753: void 754: flush(r) 755: CODE: 756: 757: ngx_http_request_t *r; 758: ngx_buf_t *b; 759: 760: ngx_http_perl_set_request(r); 761: 762: b = ngx_calloc_buf(r->pool); 763: if (b == NULL) { 764: XSRETURN_EMPTY; 765: } 766: 767: b->flush = 1; 768: 769: ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "$r->flush"); 770: 771: (void) ngx_http_perl_output(r, b); 772: 773: XSRETURN_EMPTY; 774: 775: 776: void 777: internal_redirect(r, uri) 778: CODE: 779: 780: ngx_http_request_t *r; 781: SV *uri; 782: ngx_uint_t i; 783: ngx_http_perl_ctx_t *ctx; 784: 785: ngx_http_perl_set_request(r); 786: 787: uri = ST(1); 788: 789: ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); 790: 791: if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) { 792: XSRETURN_EMPTY; 793: } 794: 795: for (i = 0; i < ctx->redirect_uri.len; i++) { 796: if (ctx->redirect_uri.data[i] == '?') { 797: 798: ctx->redirect_args.len = ctx->redirect_uri.len - (i + 1); 799: ctx->redirect_args.data = &ctx->redirect_uri.data[i + 1]; 800: ctx->redirect_uri.len = i; 801: 802: XSRETURN_EMPTY; 803: } 804: } 805: 806: 807: void 808: allow_ranges(r) 809: CODE: 810: 811: ngx_http_request_t *r; 812: 813: ngx_http_perl_set_request(r); 814: 815: r->allow_ranges = 1; 816: 817: 818: void 819: unescape(r, text, type = 0) 820: CODE: 821: 822: dXSTARG; 823: ngx_http_request_t *r; 824: SV *text; 825: int type; 826: u_char *p, *dst, *src; 827: STRLEN len; 828: 829: ngx_http_perl_set_request(r); 830: 831: text = ST(1); 832: 833: src = (u_char *) SvPV(text, len); 834: 835: p = ngx_pnalloc(r->pool, len + 1); 836: if (p == NULL) { 837: XSRETURN_UNDEF; 838: } 839: 840: dst = p; 841: 842: type = items < 3 ? 0 : SvIV(ST(2)); 843: 844: ngx_unescape_uri(&dst, &src, len, (ngx_uint_t) type); 845: *dst = '\0'; 846: 847: ngx_http_perl_set_targ(p, dst - p); 848: 849: ST(0) = TARG; 850: 851: 852: void 853: variable(r, name, value = NULL) 854: CODE: 855: 856: dXSTARG; 857: ngx_http_request_t *r; 858: SV *name, *value; 859: u_char *p, *lowcase; 860: STRLEN len; 861: ngx_str_t var, val; 862: ngx_uint_t i, hash; 863: ngx_http_perl_var_t *v; 864: ngx_http_perl_ctx_t *ctx; 865: ngx_http_variable_value_t *vv; 866: 867: ngx_http_perl_set_request(r); 868: 869: name = ST(1); 870: 871: if (SvROK(name) && SvTYPE(SvRV(name)) == SVt_PV) { 872: name = SvRV(name); 873: } 874: 875: if (items == 2) { 876: value = NULL; 877: 878: } else { 879: value = ST(2); 880: 881: if (SvROK(value) && SvTYPE(SvRV(value)) == SVt_PV) { 882: value = SvRV(value); 883: } 884: 885: if (ngx_http_perl_sv2str(aTHX_ r, &val, value) != NGX_OK) { 886: XSRETURN_UNDEF; 887: } 888: } 889: 890: p = (u_char *) SvPV(name, len); 891: 892: lowcase = ngx_pnalloc(r->pool, len); 893: if (lowcase == NULL) { 894: XSRETURN_UNDEF; 895: } 896: 897: hash = ngx_hash_strlow(lowcase, p, len); 898: 899: var.len = len; 900: var.data = lowcase; 901: 902: #if (NGX_DEBUG) 903: 904: if (value) { 905: ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 906: "perl variable: \"%V\"=\"%V\"", &var, &val); 907: } else { 908: ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 909: "perl variable: \"%V\"", &var); 910: } 911: 912: #endif 913: 914: vv = ngx_http_get_variable(r, &var, hash); 915: if (vv == NULL) { 916: XSRETURN_UNDEF; 917: } 918: 919: if (vv->not_found) { 920: 921: ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); 922: 923: if (ctx->variables) { 924: 925: v = ctx->variables->elts; 926: for (i = 0; i < ctx->variables->nelts; i++) { 927: 928: if (hash != v[i].hash 929: || len != v[i].name.len 930: || ngx_strncmp(lowcase, v[i].name.data, len) != 0) 931: { 932: continue; 933: } 934: 935: if (value) { 936: v[i].value = val; 937: XSRETURN_UNDEF; 938: } 939: 940: ngx_http_perl_set_targ(v[i].value.data, v[i].value.len); 941: 942: goto done; 943: } 944: } 945: 946: if (value) { 947: if (ctx->variables == NULL) { 948: ctx->variables = ngx_array_create(r->pool, 1, 949: sizeof(ngx_http_perl_var_t)); 950: if (ctx->variables == NULL) { 951: XSRETURN_UNDEF; 952: } 953: } 954: 955: v = ngx_array_push(ctx->variables); 956: if (v == NULL) { 957: XSRETURN_UNDEF; 958: } 959: 960: v->hash = hash; 961: v->name.len = len; 962: v->name.data = lowcase; 963: v->value = val; 964: 965: XSRETURN_UNDEF; 966: } 967: 968: XSRETURN_UNDEF; 969: } 970: 971: if (value) { 972: vv->len = val.len; 973: vv->valid = 1; 974: vv->no_cacheable = 0; 975: vv->not_found = 0; 976: vv->data = val.data; 977: 978: XSRETURN_UNDEF; 979: } 980: 981: ngx_http_perl_set_targ(vv->data, vv->len); 982: 983: done: 984: 985: ST(0) = TARG; 986: 987: 988: void 989: sleep(r, sleep, next) 990: CODE: 991: 992: ngx_http_request_t *r; 993: ngx_msec_t sleep; 994: ngx_http_perl_ctx_t *ctx; 995: 996: ngx_http_perl_set_request(r); 997: 998: sleep = (ngx_msec_t) SvIV(ST(1)); 999: 1000: ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1001: "perl sleep: %M", sleep); 1002: 1003: ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); 1004: 1005: ctx->next = SvRV(ST(2)); 1006: 1007: ngx_add_timer(r->connection->write, sleep); 1008: 1009: r->write_event_handler = ngx_http_perl_sleep_handler; 1010: r->main->count++; 1011: 1012: 1013: void 1014: log_error(r, err, msg) 1015: CODE: 1016: 1017: ngx_http_request_t *r; 1018: SV *err, *msg; 1019: u_char *p; 1020: STRLEN len; 1021: ngx_err_t e; 1022: 1023: ngx_http_perl_set_request(r); 1024: 1025: err = ST(1); 1026: 1027: if (SvROK(err) && SvTYPE(SvRV(err)) == SVt_PV) { 1028: err = SvRV(err); 1029: } 1030: 1031: e = SvIV(err); 1032: 1033: msg = ST(2); 1034: 1035: if (SvROK(msg) && SvTYPE(SvRV(msg)) == SVt_PV) { 1036: msg = SvRV(msg); 1037: } 1038: 1039: p = (u_char *) SvPV(msg, len); 1040: 1041: ngx_log_error(NGX_LOG_ERR, r->connection->log, e, "perl: %s", p);