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