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