Mercurial > hg > nginx
annotate src/http/modules/perl/nginx.xs @ 869:978a1e0fa9c1
it seems the PERL_NO_GET_CONTEXT was needed to disable warnings only
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sat, 25 Nov 2006 23:24:24 +0000 |
parents | dbc6819acfcc |
children | 26c3e48b9996 |
rev | line source |
---|---|
599 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 #include <ngx_http_perl_module.h> | |
11 | |
603 | 12 #include "XSUB.h" |
13 | |
633 | 14 #define ngx_http_perl_set_request(r) \ |
15 r = INT2PTR(ngx_http_request_t *, SvIV((SV *) SvRV(ST(0)))) | |
16 | |
17 | |
18 #define ngx_http_perl_set_targ(p, len, z) \ | |
19 \ | |
20 sv_upgrade(TARG, SVt_PV); \ | |
21 SvPOK_on(TARG); \ | |
22 SvPV_set(TARG, (char *) p); \ | |
23 SvLEN_set(TARG, len + z); \ | |
24 SvCUR_set(TARG, len); \ | |
25 SvFAKE_on(TARG); \ | |
26 SvREADONLY_on(TARG); \ | |
27 | |
599 | 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)) { | |
44 s->data = p; | |
45 return NGX_OK; | |
46 } | |
47 | |
48 s->data = ngx_palloc(r->pool, len); | |
49 if (s->data == NULL) { | |
50 return NGX_ERROR; | |
51 } | |
52 | |
53 ngx_memcpy(s->data, p, len); | |
54 | |
55 return NGX_OK; | |
56 } | |
57 | |
58 | |
59 static ngx_int_t | |
60 ngx_http_perl_output(ngx_http_request_t *r, ngx_buf_t *b) | |
61 { | |
617 | 62 ngx_chain_t out; |
63 #if (NGX_HTTP_SSI) | |
64 ngx_chain_t *cl; | |
599 | 65 ngx_http_perl_ctx_t *ctx; |
66 | |
67 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
68 | |
69 if (ctx->ssi) { | |
70 cl = ngx_alloc_chain_link(r->pool); | |
71 if (cl == NULL) { | |
72 return NGX_ERROR; | |
73 } | |
74 | |
75 cl->buf = b; | |
76 cl->next = NULL; | |
77 *ctx->ssi->last_out = cl; | |
78 ctx->ssi->last_out = &cl->next; | |
79 | |
80 return NGX_OK; | |
81 } | |
617 | 82 #endif |
599 | 83 |
84 out.buf = b; | |
85 out.next = NULL; | |
86 | |
87 return ngx_http_output_filter(r, &out); | |
88 } | |
89 | |
90 | |
91 MODULE = nginx PACKAGE = nginx | |
92 | |
93 | |
633 | 94 void |
599 | 95 send_http_header(r, ...) |
633 | 96 CODE: |
599 | 97 |
633 | 98 ngx_http_request_t *r; |
99 SV *sv; | |
599 | 100 |
633 | 101 ngx_http_perl_set_request(r); |
599 | 102 |
103 if (r->headers_out.status == 0) { | |
104 r->headers_out.status = NGX_HTTP_OK; | |
105 } | |
106 | |
107 if (items != 1) { | |
108 sv = ST(1); | |
109 | |
110 if (ngx_http_perl_sv2str(aTHX_ r, &r->headers_out.content_type, sv) | |
111 != NGX_OK) | |
112 { | |
633 | 113 XSRETURN_EMPTY; |
599 | 114 } |
115 | |
116 } else { | |
673 | 117 if (ngx_http_set_content_type(r) != NGX_OK) { |
118 XSRETURN_EMPTY; | |
599 | 119 } |
120 } | |
121 | |
633 | 122 (void) ngx_http_send_header(r); |
599 | 123 |
124 | |
633 | 125 void |
126 header_only(r) | |
599 | 127 CODE: |
128 | |
633 | 129 dXSTARG; |
130 ngx_http_request_t *r; | |
131 | |
132 ngx_http_perl_set_request(r); | |
599 | 133 |
633 | 134 sv_upgrade(TARG, SVt_IV); |
135 sv_setiv(TARG, r->header_only); | |
599 | 136 |
633 | 137 ST(0) = TARG; |
599 | 138 |
139 | |
633 | 140 void |
141 uri(r) | |
142 CODE: | |
143 | |
144 dXSTARG; | |
145 ngx_http_request_t *r; | |
599 | 146 |
633 | 147 ngx_http_perl_set_request(r); |
148 ngx_http_perl_set_targ(r->uri.data, r->uri.len, 0); | |
149 | |
150 ST(0) = TARG; | |
151 | |
152 | |
153 void | |
154 args(r) | |
599 | 155 CODE: |
156 | |
633 | 157 dXSTARG; |
158 ngx_http_request_t *r; | |
599 | 159 |
633 | 160 ngx_http_perl_set_request(r); |
161 ngx_http_perl_set_targ(r->args.data, r->args.len, 0); | |
599 | 162 |
633 | 163 ST(0) = TARG; |
599 | 164 |
165 | |
633 | 166 void |
629 | 167 request_method(r) |
633 | 168 CODE: |
169 | |
170 dXSTARG; | |
171 ngx_http_request_t *r; | |
629 | 172 |
633 | 173 ngx_http_perl_set_request(r); |
174 ngx_http_perl_set_targ(r->method_name.data, r->method_name.len, 0); | |
175 | |
176 ST(0) = TARG; | |
177 | |
178 | |
179 void | |
180 remote_addr(r) | |
629 | 181 CODE: |
182 | |
633 | 183 dXSTARG; |
184 ngx_http_request_t *r; | |
629 | 185 |
633 | 186 ngx_http_perl_set_request(r); |
187 ngx_http_perl_set_targ(r->connection->addr_text.data, | |
188 r->connection->addr_text.len, 1); | |
629 | 189 |
633 | 190 ST(0) = TARG; |
629 | 191 |
192 | |
633 | 193 void |
194 header_in(r, key) | |
629 | 195 CODE: |
196 | |
633 | 197 dXSTARG; |
667 | 198 ngx_http_request_t *r; |
199 SV *key; | |
200 u_char *p, *lowcase_key, *cookie; | |
201 STRLEN len; | |
202 ssize_t size; | |
203 ngx_uint_t i, n, hash; | |
204 ngx_list_part_t *part; | |
205 ngx_table_elt_t *h, **ph; | |
206 ngx_http_header_t *hh; | |
207 ngx_http_core_main_conf_t *cmcf; | |
629 | 208 |
633 | 209 ngx_http_perl_set_request(r); |
599 | 210 |
633 | 211 key = ST(1); |
599 | 212 |
213 if (SvROK(key) && SvTYPE(SvRV(key)) == SVt_PV) { | |
214 key = SvRV(key); | |
215 } | |
216 | |
217 p = (u_char *) SvPV(key, len); | |
218 | |
667 | 219 /* look up hashed headers */ |
220 | |
221 lowcase_key = ngx_palloc(r->pool, len); | |
222 if (lowcase_key == NULL) { | |
223 XSRETURN_UNDEF; | |
224 } | |
225 | |
226 hash = 0; | |
227 for (i = 0; i < len; i++) { | |
228 lowcase_key[i] = ngx_tolower(p[i]); | |
229 hash = ngx_hash(hash, lowcase_key[i]); | |
230 } | |
231 | |
232 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
233 | |
234 hh = ngx_hash_find(&cmcf->headers_in_hash, hash, lowcase_key, len); | |
235 | |
236 if (hh) { | |
237 if (hh->offset) { | |
238 | |
239 ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset); | |
240 | |
241 if (*ph) { | |
242 ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len, 0); | |
243 | |
244 goto done; | |
245 } | |
246 | |
247 XSRETURN_UNDEF; | |
248 } | |
249 | |
250 /* Cookie */ | |
251 | |
252 n = r->headers_in.cookies.nelts; | |
253 | |
254 if (n == 0) { | |
255 XSRETURN_UNDEF; | |
256 } | |
257 | |
258 ph = r->headers_in.cookies.elts; | |
259 | |
260 if (n == 1) { | |
261 ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len, 0); | |
262 | |
263 goto done; | |
264 } | |
265 | |
266 size = - (ssize_t) (sizeof("; ") - 1); | |
267 | |
268 for (i = 0; i < n; i++) { | |
269 size += ph[i]->value.len + sizeof("; ") - 1; | |
270 } | |
271 | |
272 cookie = ngx_palloc(r->pool, size); | |
273 if (cookie == NULL) { | |
274 XSRETURN_UNDEF; | |
275 } | |
276 | |
277 p = cookie; | |
278 | |
279 for (i = 0; /* void */ ; i++) { | |
280 p = ngx_copy(p, ph[i]->value.data, ph[i]->value.len); | |
281 | |
282 if (i == n - 1) { | |
283 break; | |
284 } | |
285 | |
286 *p++ = ';'; *p++ = ' '; | |
287 } | |
288 | |
289 ngx_http_perl_set_targ(cookie, size, 0); | |
290 | |
291 goto done; | |
292 } | |
293 | |
294 /* iterate over all headers */ | |
295 | |
599 | 296 part = &r->headers_in.headers.part; |
667 | 297 h = part->elts; |
599 | 298 |
299 for (i = 0; /* void */ ; i++) { | |
300 | |
301 if (i >= part->nelts) { | |
302 if (part->next == NULL) { | |
303 break; | |
304 } | |
305 | |
306 part = part->next; | |
667 | 307 h = part->elts; |
599 | 308 i = 0; |
309 } | |
310 | |
667 | 311 if (len != h[i].key.len |
312 || ngx_strcasecmp(p, h[i].key.data) != 0) | |
599 | 313 { |
314 continue; | |
315 } | |
316 | |
667 | 317 ngx_http_perl_set_targ(h[i].value.data, h[i].value.len, 0); |
599 | 318 |
319 goto done; | |
320 } | |
321 | |
322 XSRETURN_UNDEF; | |
323 | |
324 done: | |
325 | |
633 | 326 ST(0) = TARG; |
599 | 327 |
328 | |
633 | 329 void |
681 | 330 has_request_body(r, next) |
331 CODE: | |
332 | |
333 dXSTARG; | |
334 ngx_http_request_t *r; | |
335 SV *next; | |
336 ngx_http_perl_ctx_t *ctx; | |
337 | |
338 ngx_http_perl_set_request(r); | |
339 | |
340 if (r->headers_in.content_length_n <= 0) { | |
341 XSRETURN_UNDEF; | |
342 } | |
343 | |
344 next = ST(1); | |
345 | |
346 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
347 ctx->next = next; | |
348 | |
349 r->request_body_in_single_buf = 1; | |
350 r->request_body_in_persistent_file = 1; | |
351 r->request_body_delete_incomplete_file = 1; | |
352 | |
353 if (r->request_body_in_file_only) { | |
354 r->request_body_file_log_level = 0; | |
355 } | |
356 | |
357 ngx_http_read_client_request_body(r, ngx_http_perl_handle_request); | |
358 | |
359 sv_upgrade(TARG, SVt_IV); | |
360 sv_setiv(TARG, 1); | |
361 | |
362 ST(0) = TARG; | |
363 | |
364 | |
365 void | |
631 | 366 request_body(r) |
367 CODE: | |
368 | |
633 | 369 dXSTARG; |
370 ngx_http_request_t *r; | |
371 size_t len; | |
372 | |
373 ngx_http_perl_set_request(r); | |
631 | 374 |
633 | 375 if (r->request_body->temp_file || r->request_body->bufs == NULL) { |
376 XSRETURN_UNDEF; | |
377 } | |
631 | 378 |
633 | 379 len = r->request_body->bufs->buf->last - r->request_body->bufs->buf->pos; |
631 | 380 |
381 if (len == 0) { | |
382 XSRETURN_UNDEF; | |
383 } | |
384 | |
633 | 385 ngx_http_perl_set_targ(r->request_body->bufs->buf->pos, len, 0); |
631 | 386 |
633 | 387 ST(0) = TARG; |
631 | 388 |
389 | |
633 | 390 void |
391 request_body_file(r) | |
392 CODE: | |
393 | |
394 dXSTARG; | |
395 ngx_http_request_t *r; | |
396 | |
397 ngx_http_perl_set_request(r); | |
398 | |
399 if (r->request_body->temp_file == NULL) { | |
400 XSRETURN_UNDEF; | |
401 } | |
402 | |
403 ngx_http_perl_set_targ(r->request_body->temp_file->file.name.data, | |
404 r->request_body->temp_file->file.name.len, 1); | |
599 | 405 |
633 | 406 ST(0) = TARG; |
407 | |
408 | |
409 void | |
410 header_out(r, key, value) | |
411 CODE: | |
599 | 412 |
633 | 413 ngx_http_request_t *r; |
414 SV *key; | |
415 SV *value; | |
416 ngx_table_elt_t *header; | |
599 | 417 |
633 | 418 ngx_http_perl_set_request(r); |
419 | |
420 key = ST(1); | |
421 value = ST(2); | |
599 | 422 |
423 header = ngx_list_push(&r->headers_out.headers); | |
424 if (header == NULL) { | |
633 | 425 XSRETURN_EMPTY; |
599 | 426 } |
427 | |
428 header->hash = 1; | |
429 | |
430 if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) { | |
633 | 431 XSRETURN_EMPTY; |
599 | 432 } |
433 | |
434 if (ngx_http_perl_sv2str(aTHX_ r, &header->value, value) != NGX_OK) { | |
633 | 435 XSRETURN_EMPTY; |
599 | 436 } |
437 | |
438 if (header->key.len == sizeof("Content-Length") - 1 | |
439 && ngx_strncasecmp(header->key.data, "Content-Length", | |
741
63a08390a8a2
$r->headers_out("Content-Length", "NNN") did not work
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
440 sizeof("Content-Length") - 1) == 0) |
599 | 441 { |
741
63a08390a8a2
$r->headers_out("Content-Length", "NNN") did not work
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
442 r->headers_out.content_length_n = (off_t) SvIV(value); |
599 | 443 r->headers_out.content_length = header; |
444 } | |
445 | |
633 | 446 XSRETURN_EMPTY; |
599 | 447 |
448 | |
633 | 449 void |
599 | 450 filename(r) |
633 | 451 CODE: |
599 | 452 |
633 | 453 dXSTARG; |
774
589841f06b87
previous commit broke two modules
Igor Sysoev <igor@sysoev.ru>
parents:
741
diff
changeset
|
454 size_t root; |
633 | 455 ngx_http_request_t *r; |
599 | 456 ngx_http_perl_ctx_t *ctx; |
457 | |
633 | 458 ngx_http_perl_set_request(r); |
599 | 459 |
460 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
633 | 461 if (ctx->filename.data) { |
599 | 462 goto done; |
463 } | |
464 | |
774
589841f06b87
previous commit broke two modules
Igor Sysoev <igor@sysoev.ru>
parents:
741
diff
changeset
|
465 if (ngx_http_map_uri_to_path(r, &ctx->filename, &root, 0) == NULL) { |
599 | 466 XSRETURN_UNDEF; |
467 } | |
468 | |
633 | 469 ctx->filename.len--; |
470 sv_setpv(PL_statname, (char *) ctx->filename.data); | |
599 | 471 |
472 done: | |
473 | |
633 | 474 ngx_http_perl_set_targ(ctx->filename.data, ctx->filename.len, 1); |
599 | 475 |
633 | 476 ST(0) = TARG; |
599 | 477 |
478 | |
633 | 479 void |
599 | 480 print(r, ...) |
481 CODE: | |
482 | |
633 | 483 ngx_http_request_t *r; |
484 SV *sv; | |
485 int i; | |
486 u_char *p; | |
487 size_t size; | |
488 STRLEN len; | |
489 ngx_buf_t *b; | |
490 | |
491 ngx_http_perl_set_request(r); | |
599 | 492 |
493 if (items == 2) { | |
494 | |
495 /* | |
496 * do zero copy for prolate single read-only SV: | |
497 * $r->print("some text\n"); | |
498 */ | |
499 | |
500 sv = ST(1); | |
501 | |
502 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
503 sv = SvRV(sv); | |
504 } | |
505 | |
506 if (SvREADONLY(sv)) { | |
507 | |
508 p = (u_char *) SvPV(sv, len); | |
509 | |
510 if (len == 0) { | |
633 | 511 XSRETURN_EMPTY; |
599 | 512 } |
513 | |
514 b = ngx_calloc_buf(r->pool); | |
515 if (b == NULL) { | |
633 | 516 XSRETURN_EMPTY; |
599 | 517 } |
518 | |
519 b->memory = 1; | |
520 b->pos = p; | |
521 b->last = p + len; | |
522 b->start = p; | |
523 b->end = b->last; | |
524 | |
601 | 525 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
526 "$r->print: read-only SV: %z", len); | |
527 | |
599 | 528 goto out; |
529 } | |
530 } | |
531 | |
532 size = 0; | |
533 | |
534 for (i = 1; i < items; i++) { | |
535 | |
536 sv = ST(i); | |
537 | |
538 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
539 sv = SvRV(sv); | |
540 } | |
541 | |
601 | 542 (void) SvPV(sv, len); |
599 | 543 |
601 | 544 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
545 "$r->print: copy SV: %z", len); | |
599 | 546 |
547 size += len; | |
548 } | |
549 | |
550 if (size == 0) { | |
633 | 551 XSRETURN_EMPTY; |
599 | 552 } |
553 | |
554 b = ngx_create_temp_buf(r->pool, size); | |
555 if (b == NULL) { | |
633 | 556 XSRETURN_EMPTY; |
599 | 557 } |
558 | |
559 for (i = 1; i < items; i++) { | |
560 sv = ST(i); | |
561 | |
562 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
563 sv = SvRV(sv); | |
564 } | |
565 | |
566 p = (u_char *) SvPV(sv, len); | |
567 b->last = ngx_cpymem(b->last, p, len); | |
568 } | |
569 | |
570 out: | |
571 | |
633 | 572 (void) ngx_http_perl_output(r, b); |
599 | 573 |
633 | 574 XSRETURN_EMPTY; |
599 | 575 |
576 | |
633 | 577 void |
613 | 578 sendfile(r, filename, offset = -1, bytes = 0) |
633 | 579 CODE: |
580 | |
581 ngx_http_request_t *r; | |
582 char *filename; | |
613 | 583 int offset; |
584 size_t bytes; | |
599 | 585 ngx_fd_t fd; |
586 ngx_buf_t *b; | |
587 ngx_file_info_t fi; | |
588 ngx_pool_cleanup_t *cln; | |
589 ngx_pool_cleanup_file_t *clnf; | |
590 | |
633 | 591 ngx_http_perl_set_request(r); |
592 | |
593 filename = SvPV_nolen(ST(1)); | |
599 | 594 |
595 if (filename == NULL) { | |
596 croak("sendfile(): NULL filename"); | |
597 } | |
598 | |
633 | 599 offset = items < 3 ? -1 : SvIV(ST(2)); |
600 bytes = items < 4 ? 0 : SvIV(ST(3)); | |
601 | |
599 | 602 b = ngx_calloc_buf(r->pool); |
603 if (b == NULL) { | |
633 | 604 XSRETURN_EMPTY; |
599 | 605 } |
606 | |
607 b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)); | |
608 if (b->file == NULL) { | |
633 | 609 XSRETURN_EMPTY; |
599 | 610 } |
611 | |
612 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t)); | |
613 if (cln == NULL) { | |
633 | 614 XSRETURN_EMPTY; |
599 | 615 } |
616 | |
617 fd = ngx_open_file((u_char *) filename, NGX_FILE_RDONLY, NGX_FILE_OPEN); | |
618 | |
619 if (fd == NGX_INVALID_FILE) { | |
620 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, | |
621 ngx_open_file_n " \"%s\" failed", filename); | |
633 | 622 XSRETURN_EMPTY; |
599 | 623 } |
624 | |
613 | 625 if (offset == -1) { |
626 offset = 0; | |
627 } | |
628 | |
629 if (bytes == 0) { | |
630 if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) { | |
631 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, | |
632 ngx_fd_info_n " \"%s\" failed", filename); | |
599 | 633 |
613 | 634 if (ngx_close_file(fd) == NGX_FILE_ERROR) { |
635 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, | |
636 ngx_close_file_n " \"%s\" failed", filename); | |
637 } | |
638 | |
633 | 639 XSRETURN_EMPTY; |
599 | 640 } |
641 | |
613 | 642 bytes = ngx_file_size(&fi) - offset; |
599 | 643 } |
644 | |
645 cln->handler = ngx_pool_cleanup_file; | |
646 clnf = cln->data; | |
647 | |
648 clnf->fd = fd; | |
649 clnf->name = (u_char *) ""; | |
650 clnf->log = r->pool->log; | |
651 | |
652 b->in_file = 1; | |
613 | 653 |
654 b->file_pos = offset; | |
655 b->file_last = offset + bytes; | |
599 | 656 |
657 b->file->fd = fd; | |
658 b->file->log = r->connection->log; | |
659 | |
633 | 660 (void) ngx_http_perl_output(r, b); |
599 | 661 |
633 | 662 XSRETURN_EMPTY; |
599 | 663 |
664 | |
633 | 665 void |
599 | 666 rflush(r) |
633 | 667 CODE: |
599 | 668 |
633 | 669 ngx_http_request_t *r; |
670 ngx_buf_t *b; | |
599 | 671 |
633 | 672 ngx_http_perl_set_request(r); |
599 | 673 |
674 b = ngx_calloc_buf(r->pool); | |
675 if (b == NULL) { | |
633 | 676 XSRETURN_EMPTY; |
599 | 677 } |
678 | |
679 b->flush = 1; | |
680 | |
601 | 681 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "$r->rflush"); |
682 | |
633 | 683 (void) ngx_http_perl_output(r, b); |
599 | 684 |
633 | 685 XSRETURN_EMPTY; |
599 | 686 |
687 | |
688 void | |
689 internal_redirect(r, uri) | |
633 | 690 CODE: |
599 | 691 |
633 | 692 ngx_http_request_t *r; |
693 SV *uri; | |
599 | 694 ngx_uint_t i; |
695 ngx_http_perl_ctx_t *ctx; | |
696 | |
633 | 697 ngx_http_perl_set_request(r); |
698 | |
699 uri = ST(1); | |
599 | 700 |
701 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
702 | |
703 if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) { | |
704 XSRETURN_EMPTY; | |
705 } | |
706 | |
707 for (i = 0; i < ctx->redirect_uri.len; i++) { | |
708 if (ctx->redirect_uri.data[i] == '?') { | |
709 | |
710 ctx->redirect_args.len = ctx->redirect_uri.len - (i + 1); | |
711 ctx->redirect_args.data = &ctx->redirect_uri.data[i + 1]; | |
712 ctx->redirect_uri.len = i; | |
713 | |
714 XSRETURN_EMPTY; | |
715 } | |
716 } | |
601 | 717 |
718 | |
633 | 719 void |
811 | 720 allow_ranges(r) |
721 CODE: | |
722 | |
723 ngx_http_request_t *r; | |
724 | |
725 ngx_http_perl_set_request(r); | |
726 | |
727 r->allow_ranges = 1; | |
728 | |
729 XSRETURN_EMPTY; | |
730 | |
731 | |
732 void | |
601 | 733 unescape(r, text, type = 0) |
734 CODE: | |
735 | |
633 | 736 dXSTARG; |
737 ngx_http_request_t *r; | |
738 SV *text; | |
739 int type; | |
740 u_char *p, *dst, *src; | |
741 STRLEN len; | |
601 | 742 |
633 | 743 ngx_http_perl_set_request(r); |
744 | |
745 text = ST(1); | |
746 | |
747 src = (u_char *) SvPV(text, len); | |
748 | |
749 p = ngx_palloc(r->pool, len + 1); | |
601 | 750 if (p == NULL) { |
751 XSRETURN_UNDEF; | |
752 } | |
753 | |
754 dst = p; | |
755 | |
633 | 756 type = items < 3 ? 0 : SvIV(ST(2)); |
757 | |
758 ngx_unescape_uri(&dst, &src, len, (ngx_uint_t) type); | |
601 | 759 *dst = '\0'; |
760 | |
633 | 761 ngx_http_perl_set_targ(p, dst - p, 1); |
601 | 762 |
633 | 763 ST(0) = TARG; |
833 | 764 |
765 | |
766 void | |
767 variable(r, name, value = NULL) | |
768 CODE: | |
769 | |
770 dXSTARG; | |
771 ngx_http_request_t *r; | |
772 SV *name, *value; | |
773 u_char *p, *lowcase; | |
774 STRLEN len; | |
775 ngx_str_t var, val; | |
776 ngx_uint_t i, hash; | |
777 ngx_http_variable_value_t *vv; | |
778 | |
779 ngx_http_perl_set_request(r); | |
780 | |
781 name = ST(1); | |
782 | |
783 if (SvROK(name) && SvTYPE(SvRV(name)) == SVt_PV) { | |
784 name = SvRV(name); | |
785 } | |
786 | |
787 if (items == 2) { | |
788 value = NULL; | |
789 | |
790 } else { | |
791 value = ST(2); | |
792 | |
793 if (SvROK(value) && SvTYPE(SvRV(value)) == SVt_PV) { | |
794 value = SvRV(value); | |
795 } | |
796 | |
797 if (ngx_http_perl_sv2str(aTHX_ r, &val, value) != NGX_OK) { | |
798 XSRETURN_UNDEF; | |
799 } | |
800 } | |
801 | |
802 p = (u_char *) SvPV(name, len); | |
803 | |
804 lowcase = ngx_palloc(r->pool, len); | |
805 if (lowcase == NULL) { | |
806 XSRETURN_UNDEF; | |
807 } | |
808 | |
809 hash = 0; | |
810 for (i = 0; i < len; i++) { | |
811 lowcase[i] = ngx_tolower(p[i]); | |
812 hash = ngx_hash(hash, lowcase[i]); | |
813 } | |
814 | |
815 var.len = len; | |
816 var.data = lowcase; | |
817 | |
818 vv = ngx_http_get_variable(r, &var, hash, 1); | |
819 if (vv == NULL) { | |
820 XSRETURN_UNDEF; | |
821 } | |
822 | |
823 if (vv->not_found) { | |
824 if (value == NULL) { | |
825 XSRETURN_UNDEF; | |
826 } | |
827 | |
828 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
829 "variable \"%V\" not found", &var); | |
830 | |
831 XSRETURN_UNDEF; | |
832 } | |
833 | |
834 if (value) { | |
835 vv->len = val.len; | |
836 vv->valid = 1; | |
837 vv->no_cachable = 0; | |
838 vv->not_found = 0; | |
839 vv->data = val.data; | |
840 | |
841 XSRETURN_UNDEF; | |
842 } | |
843 | |
844 ngx_http_perl_set_targ(vv->data, vv->len, 0); | |
845 | |
846 ST(0) = TARG; |