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