Mercurial > hg > nginx-quic
annotate src/http/modules/perl/nginx.xs @ 7125:b8fc701daf8e
Upstream: even better handling of invalid headers in cache files.
When parsing of headers in a cache file fails, already parsed headers
need to be cleared, and protocol state needs to be reinitialized. To do
so, u->request_sent is now set to ensure ngx_http_upstream_reinit() will
be called.
This change complements improvements in 46ddff109e72.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 09 Oct 2017 15:59:10 +0300 |
parents | 0cdee26605f3 |
children | 36c52a0f6ded |
rev | line source |
---|---|
599 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
599 | 5 */ |
6 | |
7 | |
882
26c3e48b9996
the PERL_NO_GET_CONTEXT is actually required, see perlguts
Igor Sysoev <igor@sysoev.ru>
parents:
869
diff
changeset
|
8 #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
|
9 |
599 | 10 #include <ngx_config.h> |
11 #include <ngx_core.h> | |
12 #include <ngx_http.h> | |
13 #include <ngx_http_perl_module.h> | |
14 | |
603 | 15 #include "XSUB.h" |
16 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
17 |
633 | 18 #define ngx_http_perl_set_request(r) \ |
19 r = INT2PTR(ngx_http_request_t *, SvIV((SV *) SvRV(ST(0)))) | |
20 | |
21 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
22 #define ngx_http_perl_set_targ(p, len) \ |
633 | 23 \ |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
24 SvUPGRADE(TARG, SVt_PV); \ |
633 | 25 SvPOK_on(TARG); \ |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
26 sv_setpvn(TARG, (char *) p, len) |
633 | 27 |
599 | 28 |
29 static ngx_int_t | |
30 ngx_http_perl_sv2str(pTHX_ ngx_http_request_t *r, ngx_str_t *s, SV *sv) | |
31 { | |
32 u_char *p; | |
33 STRLEN len; | |
34 | |
35 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
36 sv = SvRV(sv); | |
37 } | |
38 | |
39 p = (u_char *) SvPV(sv, len); | |
40 | |
41 s->len = len; | |
42 | |
1703
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
43 if (SvREADONLY(sv) && SvPOK(sv)) { |
599 | 44 s->data = p; |
1703
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
45 |
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
46 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
|
47 "perl sv2str: %08XD \"%V\"", sv->sv_flags, s); |
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
48 |
599 | 49 return NGX_OK; |
50 } | |
51 | |
2049 | 52 s->data = ngx_pnalloc(r->pool, len); |
599 | 53 if (s->data == NULL) { |
54 return NGX_ERROR; | |
55 } | |
56 | |
57 ngx_memcpy(s->data, p, len); | |
58 | |
1703
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
59 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
|
60 "perl sv2str: %08XD \"%V\"", sv->sv_flags, s); |
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
61 |
599 | 62 return NGX_OK; |
63 } | |
64 | |
65 | |
66 static ngx_int_t | |
67 ngx_http_perl_output(ngx_http_request_t *r, ngx_buf_t *b) | |
68 { | |
617 | 69 ngx_chain_t out; |
70 #if (NGX_HTTP_SSI) | |
71 ngx_chain_t *cl; | |
599 | 72 ngx_http_perl_ctx_t *ctx; |
73 | |
74 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
75 | |
76 if (ctx->ssi) { | |
77 cl = ngx_alloc_chain_link(r->pool); | |
78 if (cl == NULL) { | |
79 return NGX_ERROR; | |
80 } | |
81 | |
82 cl->buf = b; | |
83 cl->next = NULL; | |
84 *ctx->ssi->last_out = cl; | |
85 ctx->ssi->last_out = &cl->next; | |
86 | |
87 return NGX_OK; | |
88 } | |
617 | 89 #endif |
599 | 90 |
91 out.buf = b; | |
92 out.next = NULL; | |
93 | |
94 return ngx_http_output_filter(r, &out); | |
95 } | |
96 | |
97 | |
98 MODULE = nginx PACKAGE = nginx | |
99 | |
100 | |
6233
c6cc0b79a43d
Perl: prototyping behavior explicitly specified.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6232
diff
changeset
|
101 PROTOTYPES: DISABLE |
c6cc0b79a43d
Perl: prototyping behavior explicitly specified.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6232
diff
changeset
|
102 |
c6cc0b79a43d
Perl: prototyping behavior explicitly specified.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6232
diff
changeset
|
103 |
633 | 104 void |
915 | 105 status(r, code) |
106 CODE: | |
107 | |
108 ngx_http_request_t *r; | |
109 | |
110 ngx_http_perl_set_request(r); | |
111 | |
112 r->headers_out.status = SvIV(ST(1)); | |
113 | |
114 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
115 "perl status: %d", r->headers_out.status); | |
116 | |
117 XSRETURN_UNDEF; | |
118 | |
119 | |
120 void | |
599 | 121 send_http_header(r, ...) |
633 | 122 CODE: |
599 | 123 |
633 | 124 ngx_http_request_t *r; |
125 SV *sv; | |
599 | 126 |
633 | 127 ngx_http_perl_set_request(r); |
599 | 128 |
129 if (r->headers_out.status == 0) { | |
130 r->headers_out.status = NGX_HTTP_OK; | |
131 } | |
132 | |
133 if (items != 1) { | |
134 sv = ST(1); | |
135 | |
136 if (ngx_http_perl_sv2str(aTHX_ r, &r->headers_out.content_type, sv) | |
137 != NGX_OK) | |
138 { | |
633 | 139 XSRETURN_EMPTY; |
599 | 140 } |
141 | |
1444
37938e68910b
allow to append charset to the "Content-Type" header
Igor Sysoev <igor@sysoev.ru>
parents:
1372
diff
changeset
|
142 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
|
143 |
599 | 144 } else { |
673 | 145 if (ngx_http_set_content_type(r) != NGX_OK) { |
146 XSRETURN_EMPTY; | |
599 | 147 } |
148 } | |
149 | |
633 | 150 (void) ngx_http_send_header(r); |
599 | 151 |
152 | |
633 | 153 void |
154 header_only(r) | |
599 | 155 CODE: |
156 | |
633 | 157 dXSTARG; |
158 ngx_http_request_t *r; | |
159 | |
160 ngx_http_perl_set_request(r); | |
599 | 161 |
633 | 162 sv_upgrade(TARG, SVt_IV); |
163 sv_setiv(TARG, r->header_only); | |
599 | 164 |
633 | 165 ST(0) = TARG; |
599 | 166 |
167 | |
633 | 168 void |
169 uri(r) | |
170 CODE: | |
171 | |
172 dXSTARG; | |
173 ngx_http_request_t *r; | |
599 | 174 |
633 | 175 ngx_http_perl_set_request(r); |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
176 ngx_http_perl_set_targ(r->uri.data, r->uri.len); |
633 | 177 |
178 ST(0) = TARG; | |
179 | |
180 | |
181 void | |
182 args(r) | |
599 | 183 CODE: |
184 | |
633 | 185 dXSTARG; |
186 ngx_http_request_t *r; | |
599 | 187 |
633 | 188 ngx_http_perl_set_request(r); |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
189 ngx_http_perl_set_targ(r->args.data, r->args.len); |
599 | 190 |
633 | 191 ST(0) = TARG; |
599 | 192 |
193 | |
633 | 194 void |
629 | 195 request_method(r) |
633 | 196 CODE: |
197 | |
198 dXSTARG; | |
199 ngx_http_request_t *r; | |
629 | 200 |
633 | 201 ngx_http_perl_set_request(r); |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
202 ngx_http_perl_set_targ(r->method_name.data, r->method_name.len); |
633 | 203 |
204 ST(0) = TARG; | |
205 | |
206 | |
207 void | |
208 remote_addr(r) | |
629 | 209 CODE: |
210 | |
633 | 211 dXSTARG; |
212 ngx_http_request_t *r; | |
629 | 213 |
633 | 214 ngx_http_perl_set_request(r); |
215 ngx_http_perl_set_targ(r->connection->addr_text.data, | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
216 r->connection->addr_text.len); |
629 | 217 |
633 | 218 ST(0) = TARG; |
629 | 219 |
220 | |
633 | 221 void |
222 header_in(r, key) | |
629 | 223 CODE: |
224 | |
633 | 225 dXSTARG; |
667 | 226 ngx_http_request_t *r; |
227 SV *key; | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
228 u_char *p, *lowcase_key, *value, sep; |
667 | 229 STRLEN len; |
230 ssize_t size; | |
231 ngx_uint_t i, n, hash; | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
232 ngx_array_t *a; |
667 | 233 ngx_list_part_t *part; |
234 ngx_table_elt_t *h, **ph; | |
235 ngx_http_header_t *hh; | |
236 ngx_http_core_main_conf_t *cmcf; | |
629 | 237 |
633 | 238 ngx_http_perl_set_request(r); |
599 | 239 |
633 | 240 key = ST(1); |
599 | 241 |
242 if (SvROK(key) && SvTYPE(SvRV(key)) == SVt_PV) { | |
243 key = SvRV(key); | |
244 } | |
245 | |
246 p = (u_char *) SvPV(key, len); | |
247 | |
667 | 248 /* look up hashed headers */ |
249 | |
2049 | 250 lowcase_key = ngx_pnalloc(r->pool, len); |
667 | 251 if (lowcase_key == NULL) { |
252 XSRETURN_UNDEF; | |
253 } | |
254 | |
2136 | 255 hash = ngx_hash_strlow(lowcase_key, p, len); |
667 | 256 |
257 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
258 | |
259 hh = ngx_hash_find(&cmcf->headers_in_hash, hash, lowcase_key, len); | |
260 | |
261 if (hh) { | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
262 |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
263 if (hh->offset == offsetof(ngx_http_headers_in_t, cookies)) { |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
264 sep = ';'; |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
265 goto multi; |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
266 } |
5306
43900b822890
Perl: fixed syntax usage for C preprocessor directives.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5248
diff
changeset
|
267 #if (NGX_HTTP_X_FORWARDED_FOR) |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
268 if (hh->offset == offsetof(ngx_http_headers_in_t, x_forwarded_for)) { |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
269 sep = ','; |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
270 goto multi; |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
271 } |
5306
43900b822890
Perl: fixed syntax usage for C preprocessor directives.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5248
diff
changeset
|
272 #endif |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
273 |
6232
5f2a0739da19
Perl: fixed warning about "sep" may be used uninitialized.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5306
diff
changeset
|
274 ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset); |
667 | 275 |
6232
5f2a0739da19
Perl: fixed warning about "sep" may be used uninitialized.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5306
diff
changeset
|
276 if (*ph) { |
5f2a0739da19
Perl: fixed warning about "sep" may be used uninitialized.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5306
diff
changeset
|
277 ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); |
667 | 278 |
6232
5f2a0739da19
Perl: fixed warning about "sep" may be used uninitialized.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5306
diff
changeset
|
279 goto done; |
5f2a0739da19
Perl: fixed warning about "sep" may be used uninitialized.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5306
diff
changeset
|
280 } |
667 | 281 |
6232
5f2a0739da19
Perl: fixed warning about "sep" may be used uninitialized.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5306
diff
changeset
|
282 XSRETURN_UNDEF; |
667 | 283 |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
284 multi: |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
285 |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
286 /* Cookie, X-Forwarded-For */ |
667 | 287 |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
288 a = (ngx_array_t *) ((char *) &r->headers_in + hh->offset); |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
289 |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
290 n = a->nelts; |
667 | 291 |
292 if (n == 0) { | |
293 XSRETURN_UNDEF; | |
294 } | |
295 | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
296 ph = a->elts; |
667 | 297 |
298 if (n == 1) { | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
299 ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); |
667 | 300 |
301 goto done; | |
302 } | |
303 | |
304 size = - (ssize_t) (sizeof("; ") - 1); | |
305 | |
306 for (i = 0; i < n; i++) { | |
307 size += ph[i]->value.len + sizeof("; ") - 1; | |
308 } | |
309 | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
310 value = ngx_pnalloc(r->pool, size); |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
311 if (value == NULL) { |
667 | 312 XSRETURN_UNDEF; |
313 } | |
314 | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
315 p = value; |
667 | 316 |
317 for (i = 0; /* void */ ; i++) { | |
318 p = ngx_copy(p, ph[i]->value.data, ph[i]->value.len); | |
319 | |
320 if (i == n - 1) { | |
321 break; | |
322 } | |
323 | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
324 *p++ = sep; *p++ = ' '; |
667 | 325 } |
326 | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
327 ngx_http_perl_set_targ(value, size); |
667 | 328 |
329 goto done; | |
330 } | |
331 | |
332 /* iterate over all headers */ | |
333 | |
599 | 334 part = &r->headers_in.headers.part; |
667 | 335 h = part->elts; |
599 | 336 |
337 for (i = 0; /* void */ ; i++) { | |
338 | |
339 if (i >= part->nelts) { | |
340 if (part->next == NULL) { | |
341 break; | |
342 } | |
343 | |
344 part = part->next; | |
667 | 345 h = part->elts; |
599 | 346 i = 0; |
347 } | |
348 | |
667 | 349 if (len != h[i].key.len |
350 || ngx_strcasecmp(p, h[i].key.data) != 0) | |
599 | 351 { |
352 continue; | |
353 } | |
354 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
355 ngx_http_perl_set_targ(h[i].value.data, h[i].value.len); |
599 | 356 |
357 goto done; | |
358 } | |
359 | |
360 XSRETURN_UNDEF; | |
361 | |
362 done: | |
363 | |
633 | 364 ST(0) = TARG; |
599 | 365 |
366 | |
633 | 367 void |
681 | 368 has_request_body(r, next) |
369 CODE: | |
370 | |
371 dXSTARG; | |
372 ngx_http_request_t *r; | |
373 ngx_http_perl_ctx_t *ctx; | |
374 | |
375 ngx_http_perl_set_request(r); | |
376 | |
5181
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
377 if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) { |
681 | 378 XSRETURN_UNDEF; |
379 } | |
380 | |
381 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
909 | 382 ctx->next = SvRV(ST(1)); |
681 | 383 |
384 r->request_body_in_single_buf = 1; | |
385 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
|
386 r->request_body_in_clean_file = 1; |
681 | 387 |
388 if (r->request_body_in_file_only) { | |
389 r->request_body_file_log_level = 0; | |
390 } | |
391 | |
392 ngx_http_read_client_request_body(r, ngx_http_perl_handle_request); | |
393 | |
394 sv_upgrade(TARG, SVt_IV); | |
395 sv_setiv(TARG, 1); | |
396 | |
397 ST(0) = TARG; | |
398 | |
399 | |
400 void | |
631 | 401 request_body(r) |
402 CODE: | |
403 | |
633 | 404 dXSTARG; |
405 ngx_http_request_t *r; | |
5181
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
406 u_char *p, *data; |
633 | 407 size_t len; |
5181
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
408 ngx_buf_t *buf; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
409 ngx_chain_t *cl; |
633 | 410 |
411 ngx_http_perl_set_request(r); | |
631 | 412 |
941 | 413 if (r->request_body == NULL |
414 || r->request_body->temp_file | |
415 || r->request_body->bufs == NULL) | |
416 { | |
633 | 417 XSRETURN_UNDEF; |
418 } | |
631 | 419 |
5181
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
420 cl = r->request_body->bufs; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
421 buf = cl->buf; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
422 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
423 if (cl->next == NULL) { |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
424 len = buf->last - buf->pos; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
425 data = buf->pos; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
426 goto done; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
427 } |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
428 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
429 len = buf->last - buf->pos; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
430 cl = cl->next; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
431 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
432 for ( /* void */ ; cl; cl = cl->next) { |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
433 buf = cl->buf; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
434 len += buf->last - buf->pos; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
435 } |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
436 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
437 p = ngx_pnalloc(r->pool, len); |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
438 if (p == NULL) { |
5198
e530b88b088b
Perl: extra "return" removed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5181
diff
changeset
|
439 XSRETURN_UNDEF; |
5181
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
440 } |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
441 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
442 data = p; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
443 cl = r->request_body->bufs; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
444 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
445 for ( /* void */ ; cl; cl = cl->next) { |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
446 buf = cl->buf; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
447 p = ngx_cpymem(p, buf->pos, buf->last - buf->pos); |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
448 } |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
449 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
450 done: |
631 | 451 |
452 if (len == 0) { | |
453 XSRETURN_UNDEF; | |
454 } | |
455 | |
5181
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
456 ngx_http_perl_set_targ(data, len); |
631 | 457 |
633 | 458 ST(0) = TARG; |
631 | 459 |
460 | |
633 | 461 void |
462 request_body_file(r) | |
463 CODE: | |
464 | |
465 dXSTARG; | |
466 ngx_http_request_t *r; | |
467 | |
468 ngx_http_perl_set_request(r); | |
469 | |
941 | 470 if (r->request_body == NULL || r->request_body->temp_file == NULL) { |
633 | 471 XSRETURN_UNDEF; |
472 } | |
473 | |
474 ngx_http_perl_set_targ(r->request_body->temp_file->file.name.data, | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
475 r->request_body->temp_file->file.name.len); |
599 | 476 |
633 | 477 ST(0) = TARG; |
478 | |
479 | |
480 void | |
1371 | 481 discard_request_body(r) |
482 CODE: | |
483 | |
484 ngx_http_request_t *r; | |
485 | |
486 ngx_http_perl_set_request(r); | |
487 | |
488 ngx_http_discard_request_body(r); | |
489 | |
490 | |
491 void | |
633 | 492 header_out(r, key, value) |
493 CODE: | |
599 | 494 |
633 | 495 ngx_http_request_t *r; |
496 SV *key; | |
497 SV *value; | |
498 ngx_table_elt_t *header; | |
599 | 499 |
633 | 500 ngx_http_perl_set_request(r); |
501 | |
502 key = ST(1); | |
503 value = ST(2); | |
599 | 504 |
505 header = ngx_list_push(&r->headers_out.headers); | |
506 if (header == NULL) { | |
633 | 507 XSRETURN_EMPTY; |
599 | 508 } |
509 | |
510 header->hash = 1; | |
511 | |
512 if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) { | |
6986
0cdee26605f3
Cleaned up r->headers_out.headers allocation error handling.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6960
diff
changeset
|
513 header->hash = 0; |
633 | 514 XSRETURN_EMPTY; |
599 | 515 } |
516 | |
517 if (ngx_http_perl_sv2str(aTHX_ r, &header->value, value) != NGX_OK) { | |
6986
0cdee26605f3
Cleaned up r->headers_out.headers allocation error handling.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6960
diff
changeset
|
518 header->hash = 0; |
633 | 519 XSRETURN_EMPTY; |
599 | 520 } |
521 | |
522 if (header->key.len == sizeof("Content-Length") - 1 | |
3870 | 523 && ngx_strncasecmp(header->key.data, (u_char *) "Content-Length", |
741
63a08390a8a2
$r->headers_out("Content-Length", "NNN") did not work
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
524 sizeof("Content-Length") - 1) == 0) |
599 | 525 { |
741
63a08390a8a2
$r->headers_out("Content-Length", "NNN") did not work
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
526 r->headers_out.content_length_n = (off_t) SvIV(value); |
599 | 527 r->headers_out.content_length = header; |
528 } | |
529 | |
4196
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
530 if (header->key.len == sizeof("Content-Encoding") - 1 |
4644
95763fce86a8
Fixed warning during nginx.xs compilation.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4494
diff
changeset
|
531 && ngx_strncasecmp(header->key.data, (u_char *) "Content-Encoding", |
4196
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
532 sizeof("Content-Encoding") - 1) == 0) |
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
533 { |
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
534 r->headers_out.content_encoding = header; |
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
535 } |
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
536 |
599 | 537 |
633 | 538 void |
599 | 539 filename(r) |
633 | 540 CODE: |
599 | 541 |
633 | 542 dXSTARG; |
774
589841f06b87
previous commit broke two modules
Igor Sysoev <igor@sysoev.ru>
parents:
741
diff
changeset
|
543 size_t root; |
633 | 544 ngx_http_request_t *r; |
599 | 545 ngx_http_perl_ctx_t *ctx; |
546 | |
633 | 547 ngx_http_perl_set_request(r); |
599 | 548 |
549 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
633 | 550 if (ctx->filename.data) { |
599 | 551 goto done; |
552 } | |
553 | |
774
589841f06b87
previous commit broke two modules
Igor Sysoev <igor@sysoev.ru>
parents:
741
diff
changeset
|
554 if (ngx_http_map_uri_to_path(r, &ctx->filename, &root, 0) == NULL) { |
599 | 555 XSRETURN_UNDEF; |
556 } | |
557 | |
633 | 558 ctx->filename.len--; |
559 sv_setpv(PL_statname, (char *) ctx->filename.data); | |
599 | 560 |
561 done: | |
562 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
563 ngx_http_perl_set_targ(ctx->filename.data, ctx->filename.len); |
599 | 564 |
633 | 565 ST(0) = TARG; |
599 | 566 |
567 | |
633 | 568 void |
599 | 569 print(r, ...) |
570 CODE: | |
571 | |
633 | 572 ngx_http_request_t *r; |
573 SV *sv; | |
574 int i; | |
575 u_char *p; | |
576 size_t size; | |
577 STRLEN len; | |
578 ngx_buf_t *b; | |
579 | |
580 ngx_http_perl_set_request(r); | |
599 | 581 |
582 if (items == 2) { | |
583 | |
584 /* | |
585 * do zero copy for prolate single read-only SV: | |
586 * $r->print("some text\n"); | |
587 */ | |
588 | |
589 sv = ST(1); | |
590 | |
591 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
592 sv = SvRV(sv); | |
593 } | |
594 | |
1703
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
595 if (SvREADONLY(sv) && SvPOK(sv)) { |
599 | 596 |
597 p = (u_char *) SvPV(sv, len); | |
598 | |
599 if (len == 0) { | |
633 | 600 XSRETURN_EMPTY; |
599 | 601 } |
602 | |
603 b = ngx_calloc_buf(r->pool); | |
604 if (b == NULL) { | |
633 | 605 XSRETURN_EMPTY; |
599 | 606 } |
607 | |
608 b->memory = 1; | |
609 b->pos = p; | |
610 b->last = p + len; | |
611 b->start = p; | |
612 b->end = b->last; | |
613 | |
601 | 614 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
615 "$r->print: read-only SV: %z", len); | |
616 | |
599 | 617 goto out; |
618 } | |
619 } | |
620 | |
621 size = 0; | |
622 | |
623 for (i = 1; i < items; i++) { | |
624 | |
625 sv = ST(i); | |
626 | |
627 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
628 sv = SvRV(sv); | |
629 } | |
630 | |
601 | 631 (void) SvPV(sv, len); |
599 | 632 |
601 | 633 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
634 "$r->print: copy SV: %z", len); | |
599 | 635 |
636 size += len; | |
637 } | |
638 | |
639 if (size == 0) { | |
633 | 640 XSRETURN_EMPTY; |
599 | 641 } |
642 | |
643 b = ngx_create_temp_buf(r->pool, size); | |
644 if (b == NULL) { | |
633 | 645 XSRETURN_EMPTY; |
599 | 646 } |
647 | |
648 for (i = 1; i < items; i++) { | |
649 sv = ST(i); | |
650 | |
651 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
652 sv = SvRV(sv); | |
653 } | |
654 | |
655 p = (u_char *) SvPV(sv, len); | |
656 b->last = ngx_cpymem(b->last, p, len); | |
657 } | |
658 | |
659 out: | |
660 | |
633 | 661 (void) ngx_http_perl_output(r, b); |
599 | 662 |
663 | |
633 | 664 void |
613 | 665 sendfile(r, filename, offset = -1, bytes = 0) |
633 | 666 CODE: |
667 | |
1454 | 668 ngx_http_request_t *r; |
669 char *filename; | |
2794
92bd6afe8d9c
use off_t in $r->sendfile(), this allows to use 64-bit off_t on platforms
Igor Sysoev <igor@sysoev.ru>
parents:
2756
diff
changeset
|
670 off_t offset; |
1454 | 671 size_t bytes; |
672 ngx_str_t path; | |
673 ngx_buf_t *b; | |
674 ngx_open_file_info_t of; | |
675 ngx_http_core_loc_conf_t *clcf; | |
599 | 676 |
633 | 677 ngx_http_perl_set_request(r); |
678 | |
679 filename = SvPV_nolen(ST(1)); | |
599 | 680 |
681 if (filename == NULL) { | |
682 croak("sendfile(): NULL filename"); | |
683 } | |
684 | |
633 | 685 offset = items < 3 ? -1 : SvIV(ST(2)); |
686 bytes = items < 4 ? 0 : SvIV(ST(3)); | |
687 | |
599 | 688 b = ngx_calloc_buf(r->pool); |
689 if (b == NULL) { | |
633 | 690 XSRETURN_EMPTY; |
599 | 691 } |
692 | |
693 b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)); | |
694 if (b->file == NULL) { | |
633 | 695 XSRETURN_EMPTY; |
599 | 696 } |
697 | |
1454 | 698 path.len = ngx_strlen(filename); |
699 | |
2061
b0a1c84725cf
change useless ngx_pcalloc() to ngx_pnalloc()
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
700 path.data = ngx_pnalloc(r->pool, path.len + 1); |
1454 | 701 if (path.data == NULL) { |
633 | 702 XSRETURN_EMPTY; |
599 | 703 } |
704 | |
3870 | 705 (void) ngx_cpystrn(path.data, (u_char *) filename, path.len + 1); |
1560
25ee6eee7573
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
1457
diff
changeset
|
706 |
2063
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
707 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
708 |
2068
75a8d34459c5
ngx_memzero() ngx_open_file_info_t
Igor Sysoev <igor@sysoev.ru>
parents:
2063
diff
changeset
|
709 ngx_memzero(&of, sizeof(ngx_open_file_info_t)); |
75a8d34459c5
ngx_memzero() ngx_open_file_info_t
Igor Sysoev <igor@sysoev.ru>
parents:
2063
diff
changeset
|
710 |
3178 | 711 of.read_ahead = clcf->read_ahead; |
2129 | 712 of.directio = clcf->directio; |
2063
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
713 of.valid = clcf->open_file_cache_valid; |
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
714 of.min_uses = clcf->open_file_cache_min_uses; |
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
715 of.errors = clcf->open_file_cache_errors; |
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
716 of.events = clcf->open_file_cache_events; |
4494
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
717 |
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
718 if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) { |
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
719 XSRETURN_EMPTY; |
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
720 } |
2063
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
721 |
1799 | 722 if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) |
723 != NGX_OK) | |
724 { | |
1454 | 725 if (of.err == 0) { |
726 XSRETURN_EMPTY; | |
727 } | |
728 | |
599 | 729 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, |
2756
09cab3f8d92e
*) of.test_only to not open file if only stat() is enough
Igor Sysoev <igor@sysoev.ru>
parents:
2231
diff
changeset
|
730 "%s \"%s\" failed", of.failed, filename); |
633 | 731 XSRETURN_EMPTY; |
599 | 732 } |
733 | |
613 | 734 if (offset == -1) { |
735 offset = 0; | |
736 } | |
737 | |
738 if (bytes == 0) { | |
1454 | 739 bytes = of.size - offset; |
599 | 740 } |
741 | |
742 b->in_file = 1; | |
613 | 743 |
744 b->file_pos = offset; | |
745 b->file_last = offset + bytes; | |
599 | 746 |
1454 | 747 b->file->fd = of.fd; |
599 | 748 b->file->log = r->connection->log; |
2231
8564129d49b6
*) handle unaligned file part for directio
Igor Sysoev <igor@sysoev.ru>
parents:
2136
diff
changeset
|
749 b->file->directio = of.is_directio; |
599 | 750 |
633 | 751 (void) ngx_http_perl_output(r, b); |
599 | 752 |
753 | |
633 | 754 void |
1178
a77f6980de50
rename $r->rflush to $r->flush
Igor Sysoev <igor@sysoev.ru>
parents:
1075
diff
changeset
|
755 flush(r) |
633 | 756 CODE: |
599 | 757 |
633 | 758 ngx_http_request_t *r; |
759 ngx_buf_t *b; | |
599 | 760 |
633 | 761 ngx_http_perl_set_request(r); |
599 | 762 |
763 b = ngx_calloc_buf(r->pool); | |
764 if (b == NULL) { | |
633 | 765 XSRETURN_EMPTY; |
599 | 766 } |
767 | |
768 b->flush = 1; | |
769 | |
1178
a77f6980de50
rename $r->rflush to $r->flush
Igor Sysoev <igor@sysoev.ru>
parents:
1075
diff
changeset
|
770 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "$r->flush"); |
601 | 771 |
633 | 772 (void) ngx_http_perl_output(r, b); |
599 | 773 |
633 | 774 XSRETURN_EMPTY; |
599 | 775 |
776 | |
777 void | |
778 internal_redirect(r, uri) | |
633 | 779 CODE: |
599 | 780 |
633 | 781 ngx_http_request_t *r; |
782 SV *uri; | |
599 | 783 ngx_uint_t i; |
784 ngx_http_perl_ctx_t *ctx; | |
785 | |
633 | 786 ngx_http_perl_set_request(r); |
787 | |
788 uri = ST(1); | |
599 | 789 |
790 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
791 | |
792 if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) { | |
793 XSRETURN_EMPTY; | |
794 } | |
795 | |
796 for (i = 0; i < ctx->redirect_uri.len; i++) { | |
797 if (ctx->redirect_uri.data[i] == '?') { | |
798 | |
799 ctx->redirect_args.len = ctx->redirect_uri.len - (i + 1); | |
800 ctx->redirect_args.data = &ctx->redirect_uri.data[i + 1]; | |
801 ctx->redirect_uri.len = i; | |
802 | |
803 XSRETURN_EMPTY; | |
804 } | |
805 } | |
601 | 806 |
807 | |
633 | 808 void |
811 | 809 allow_ranges(r) |
810 CODE: | |
811 | |
812 ngx_http_request_t *r; | |
813 | |
814 ngx_http_perl_set_request(r); | |
815 | |
816 r->allow_ranges = 1; | |
817 | |
818 | |
819 void | |
601 | 820 unescape(r, text, type = 0) |
821 CODE: | |
822 | |
633 | 823 dXSTARG; |
824 ngx_http_request_t *r; | |
825 SV *text; | |
826 int type; | |
827 u_char *p, *dst, *src; | |
828 STRLEN len; | |
601 | 829 |
633 | 830 ngx_http_perl_set_request(r); |
831 | |
832 text = ST(1); | |
833 | |
834 src = (u_char *) SvPV(text, len); | |
835 | |
2049 | 836 p = ngx_pnalloc(r->pool, len + 1); |
601 | 837 if (p == NULL) { |
838 XSRETURN_UNDEF; | |
839 } | |
840 | |
841 dst = p; | |
842 | |
633 | 843 type = items < 3 ? 0 : SvIV(ST(2)); |
844 | |
845 ngx_unescape_uri(&dst, &src, len, (ngx_uint_t) type); | |
601 | 846 *dst = '\0'; |
847 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
848 ngx_http_perl_set_targ(p, dst - p); |
601 | 849 |
633 | 850 ST(0) = TARG; |
833 | 851 |
852 | |
853 void | |
854 variable(r, name, value = NULL) | |
855 CODE: | |
856 | |
857 dXSTARG; | |
858 ngx_http_request_t *r; | |
859 SV *name, *value; | |
860 u_char *p, *lowcase; | |
861 STRLEN len; | |
862 ngx_str_t var, val; | |
863 ngx_uint_t i, hash; | |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
864 ngx_http_perl_var_t *v; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
865 ngx_http_perl_ctx_t *ctx; |
833 | 866 ngx_http_variable_value_t *vv; |
867 | |
868 ngx_http_perl_set_request(r); | |
869 | |
870 name = ST(1); | |
871 | |
872 if (SvROK(name) && SvTYPE(SvRV(name)) == SVt_PV) { | |
873 name = SvRV(name); | |
874 } | |
875 | |
876 if (items == 2) { | |
877 value = NULL; | |
878 | |
879 } else { | |
880 value = ST(2); | |
881 | |
882 if (SvROK(value) && SvTYPE(SvRV(value)) == SVt_PV) { | |
883 value = SvRV(value); | |
884 } | |
885 | |
886 if (ngx_http_perl_sv2str(aTHX_ r, &val, value) != NGX_OK) { | |
887 XSRETURN_UNDEF; | |
888 } | |
889 } | |
890 | |
891 p = (u_char *) SvPV(name, len); | |
892 | |
2049 | 893 lowcase = ngx_pnalloc(r->pool, len); |
833 | 894 if (lowcase == NULL) { |
895 XSRETURN_UNDEF; | |
896 } | |
897 | |
2136 | 898 hash = ngx_hash_strlow(lowcase, p, len); |
833 | 899 |
900 var.len = len; | |
901 var.data = lowcase; | |
5306
43900b822890
Perl: fixed syntax usage for C preprocessor directives.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5248
diff
changeset
|
902 #if (NGX_DEBUG) |
912
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 if (value) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
905 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
|
906 "perl variable: \"%V\"=\"%V\"", &var, &val); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
907 } else { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
908 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
|
909 "perl variable: \"%V\"", &var); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
910 } |
5306
43900b822890
Perl: fixed syntax usage for C preprocessor directives.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5248
diff
changeset
|
911 #endif |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
912 |
3500
0eb46e3c5c02
change processing variables accessed by SSI and perl module:
Igor Sysoev <igor@sysoev.ru>
parents:
3447
diff
changeset
|
913 vv = ngx_http_get_variable(r, &var, hash); |
833 | 914 if (vv == NULL) { |
915 XSRETURN_UNDEF; | |
916 } | |
917 | |
918 if (vv->not_found) { | |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
919 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
920 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
|
921 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
922 if (ctx->variables) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
923 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
924 v = ctx->variables->elts; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
925 for (i = 0; i < ctx->variables->nelts; i++) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
926 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
927 if (hash != v[i].hash |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
928 || len != v[i].name.len |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
929 || 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
|
930 { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
931 continue; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
932 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
933 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
934 if (value) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
935 v[i].value = val; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
936 XSRETURN_UNDEF; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
937 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
938 |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
939 ngx_http_perl_set_targ(v[i].value.data, v[i].value.len); |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
940 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
941 goto done; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
942 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
943 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
944 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
945 if (value) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
946 if (ctx->variables == NULL) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
947 ctx->variables = ngx_array_create(r->pool, 1, |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
948 sizeof(ngx_http_perl_var_t)); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
949 if (ctx->variables == NULL) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
950 XSRETURN_UNDEF; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
951 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
952 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
953 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
954 v = ngx_array_push(ctx->variables); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
955 if (v == NULL) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
956 XSRETURN_UNDEF; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
957 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
958 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
959 v->hash = hash; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
960 v->name.len = len; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
961 v->name.data = lowcase; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
962 v->value = val; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
963 |
833 | 964 XSRETURN_UNDEF; |
965 } | |
966 | |
967 XSRETURN_UNDEF; | |
968 } | |
969 | |
970 if (value) { | |
971 vv->len = val.len; | |
972 vv->valid = 1; | |
1565 | 973 vv->no_cacheable = 0; |
833 | 974 vv->not_found = 0; |
975 vv->data = val.data; | |
976 | |
977 XSRETURN_UNDEF; | |
978 } | |
979 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
980 ngx_http_perl_set_targ(vv->data, vv->len); |
833 | 981 |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
982 done: |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
983 |
833 | 984 ST(0) = TARG; |
907 | 985 |
986 | |
987 void | |
911 | 988 sleep(r, sleep, next) |
989 CODE: | |
990 | |
991 ngx_http_request_t *r; | |
1897 | 992 ngx_msec_t sleep; |
911 | 993 ngx_http_perl_ctx_t *ctx; |
994 | |
995 ngx_http_perl_set_request(r); | |
996 | |
1898 | 997 sleep = (ngx_msec_t) SvIV(ST(1)); |
1897 | 998 |
999 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1000 "perl sleep: %M", sleep); | |
1001 | |
911 | 1002 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); |
1003 | |
1004 ctx->next = SvRV(ST(2)); | |
1005 | |
6960
1c5e5e5b008d
Perl: fixed delaying subrequests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6233
diff
changeset
|
1006 r->connection->write->delayed = 1; |
1897 | 1007 ngx_add_timer(r->connection->write, sleep); |
1008 | |
1009 r->write_event_handler = ngx_http_perl_sleep_handler; | |
3447
de70f912ad58
fix request counter for $r->sleep(), the bug was introduced in r3050
Igor Sysoev <igor@sysoev.ru>
parents:
3317
diff
changeset
|
1010 r->main->count++; |
911 | 1011 |
1012 | |
1013 void | |
907 | 1014 log_error(r, err, msg) |
1015 CODE: | |
1016 | |
1017 ngx_http_request_t *r; | |
1018 SV *err, *msg; | |
1019 u_char *p; | |
1020 STRLEN len; | |
1021 ngx_err_t e; | |
1022 | |
1023 ngx_http_perl_set_request(r); | |
1024 | |
1025 err = ST(1); | |
1026 | |
1027 if (SvROK(err) && SvTYPE(SvRV(err)) == SVt_PV) { | |
1028 err = SvRV(err); | |
1029 } | |
1030 | |
1031 e = SvIV(err); | |
1032 | |
1033 msg = ST(2); | |
1034 | |
1035 if (SvROK(msg) && SvTYPE(SvRV(msg)) == SVt_PV) { | |
1036 msg = SvRV(msg); | |
1037 } | |
1038 | |
1039 p = (u_char *) SvPV(msg, len); | |
1040 | |
910 | 1041 ngx_log_error(NGX_LOG_ERR, r->connection->log, e, "perl: %s", p); |