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