Mercurial > hg > nginx-quic
annotate src/http/modules/perl/nginx.xs @ 5324:8ef1722143dc
SPDY: do not reject headers with empty value (ticket #396).
A quote from SPDY draft 2 specification: "The length of each name and
value must be greater than zero. A receiver of a zero-length name or
value must send a RST_STREAM with code PROTOCOL error."
But it appears that Chrome browser allows sending requests over SPDY/2
connection using JavaScript that contain headers with empty values.
For better compatibility across SPDY clients and to be compliant with
HTTP, such headers are no longer rejected.
Also, it is worth noting that in SPDY draft 3 the statement has been
changed so that it permits empty values for headers.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Thu, 15 Aug 2013 19:16:09 +0400 |
parents | 43900b822890 |
children | 5f2a0739da19 |
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 | |
633 | 101 void |
915 | 102 status(r, code) |
103 CODE: | |
104 | |
105 ngx_http_request_t *r; | |
106 | |
107 ngx_http_perl_set_request(r); | |
108 | |
109 r->headers_out.status = SvIV(ST(1)); | |
110 | |
111 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
112 "perl status: %d", r->headers_out.status); | |
113 | |
114 XSRETURN_UNDEF; | |
115 | |
116 | |
117 void | |
599 | 118 send_http_header(r, ...) |
633 | 119 CODE: |
599 | 120 |
633 | 121 ngx_http_request_t *r; |
122 SV *sv; | |
599 | 123 |
633 | 124 ngx_http_perl_set_request(r); |
599 | 125 |
126 if (r->headers_out.status == 0) { | |
127 r->headers_out.status = NGX_HTTP_OK; | |
128 } | |
129 | |
130 if (items != 1) { | |
131 sv = ST(1); | |
132 | |
133 if (ngx_http_perl_sv2str(aTHX_ r, &r->headers_out.content_type, sv) | |
134 != NGX_OK) | |
135 { | |
633 | 136 XSRETURN_EMPTY; |
599 | 137 } |
138 | |
1444
37938e68910b
allow to append charset to the "Content-Type" header
Igor Sysoev <igor@sysoev.ru>
parents:
1372
diff
changeset
|
139 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
|
140 |
599 | 141 } else { |
673 | 142 if (ngx_http_set_content_type(r) != NGX_OK) { |
143 XSRETURN_EMPTY; | |
599 | 144 } |
145 } | |
146 | |
633 | 147 (void) ngx_http_send_header(r); |
599 | 148 |
149 | |
633 | 150 void |
151 header_only(r) | |
599 | 152 CODE: |
153 | |
633 | 154 dXSTARG; |
155 ngx_http_request_t *r; | |
156 | |
157 ngx_http_perl_set_request(r); | |
599 | 158 |
633 | 159 sv_upgrade(TARG, SVt_IV); |
160 sv_setiv(TARG, r->header_only); | |
599 | 161 |
633 | 162 ST(0) = TARG; |
599 | 163 |
164 | |
633 | 165 void |
166 uri(r) | |
167 CODE: | |
168 | |
169 dXSTARG; | |
170 ngx_http_request_t *r; | |
599 | 171 |
633 | 172 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
|
173 ngx_http_perl_set_targ(r->uri.data, r->uri.len); |
633 | 174 |
175 ST(0) = TARG; | |
176 | |
177 | |
178 void | |
179 args(r) | |
599 | 180 CODE: |
181 | |
633 | 182 dXSTARG; |
183 ngx_http_request_t *r; | |
599 | 184 |
633 | 185 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
|
186 ngx_http_perl_set_targ(r->args.data, r->args.len); |
599 | 187 |
633 | 188 ST(0) = TARG; |
599 | 189 |
190 | |
633 | 191 void |
629 | 192 request_method(r) |
633 | 193 CODE: |
194 | |
195 dXSTARG; | |
196 ngx_http_request_t *r; | |
629 | 197 |
633 | 198 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
|
199 ngx_http_perl_set_targ(r->method_name.data, r->method_name.len); |
633 | 200 |
201 ST(0) = TARG; | |
202 | |
203 | |
204 void | |
205 remote_addr(r) | |
629 | 206 CODE: |
207 | |
633 | 208 dXSTARG; |
209 ngx_http_request_t *r; | |
629 | 210 |
633 | 211 ngx_http_perl_set_request(r); |
212 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
|
213 r->connection->addr_text.len); |
629 | 214 |
633 | 215 ST(0) = TARG; |
629 | 216 |
217 | |
633 | 218 void |
219 header_in(r, key) | |
629 | 220 CODE: |
221 | |
633 | 222 dXSTARG; |
667 | 223 ngx_http_request_t *r; |
224 SV *key; | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
225 u_char *p, *lowcase_key, *value, sep; |
667 | 226 STRLEN len; |
227 ssize_t size; | |
228 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
|
229 ngx_array_t *a; |
667 | 230 ngx_list_part_t *part; |
231 ngx_table_elt_t *h, **ph; | |
232 ngx_http_header_t *hh; | |
233 ngx_http_core_main_conf_t *cmcf; | |
629 | 234 |
633 | 235 ngx_http_perl_set_request(r); |
599 | 236 |
633 | 237 key = ST(1); |
599 | 238 |
239 if (SvROK(key) && SvTYPE(SvRV(key)) == SVt_PV) { | |
240 key = SvRV(key); | |
241 } | |
242 | |
243 p = (u_char *) SvPV(key, len); | |
244 | |
667 | 245 /* look up hashed headers */ |
246 | |
2049 | 247 lowcase_key = ngx_pnalloc(r->pool, len); |
667 | 248 if (lowcase_key == NULL) { |
249 XSRETURN_UNDEF; | |
250 } | |
251 | |
2136 | 252 hash = ngx_hash_strlow(lowcase_key, p, len); |
667 | 253 |
254 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
255 | |
256 hh = ngx_hash_find(&cmcf->headers_in_hash, hash, lowcase_key, len); | |
257 | |
258 if (hh) { | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
259 |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
260 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
|
261 sep = ';'; |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
262 goto multi; |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
263 } |
5306
43900b822890
Perl: fixed syntax usage for C preprocessor directives.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5248
diff
changeset
|
264 #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
|
265 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
|
266 sep = ','; |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
267 goto multi; |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
268 } |
5306
43900b822890
Perl: fixed syntax usage for C preprocessor directives.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5248
diff
changeset
|
269 #endif |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
270 |
667 | 271 if (hh->offset) { |
272 | |
273 ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset); | |
274 | |
275 if (*ph) { | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
276 ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); |
667 | 277 |
278 goto done; | |
279 } | |
280 | |
281 XSRETURN_UNDEF; | |
282 } | |
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) { | |
633 | 513 XSRETURN_EMPTY; |
599 | 514 } |
515 | |
516 if (ngx_http_perl_sv2str(aTHX_ r, &header->value, value) != NGX_OK) { | |
633 | 517 XSRETURN_EMPTY; |
599 | 518 } |
519 | |
520 if (header->key.len == sizeof("Content-Length") - 1 | |
3870 | 521 && 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
|
522 sizeof("Content-Length") - 1) == 0) |
599 | 523 { |
741
63a08390a8a2
$r->headers_out("Content-Length", "NNN") did not work
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
524 r->headers_out.content_length_n = (off_t) SvIV(value); |
599 | 525 r->headers_out.content_length = header; |
526 } | |
527 | |
4196
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
528 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
|
529 && 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
|
530 sizeof("Content-Encoding") - 1) == 0) |
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
531 { |
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
532 r->headers_out.content_encoding = header; |
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 |
599 | 535 |
633 | 536 void |
599 | 537 filename(r) |
633 | 538 CODE: |
599 | 539 |
633 | 540 dXSTARG; |
774
589841f06b87
previous commit broke two modules
Igor Sysoev <igor@sysoev.ru>
parents:
741
diff
changeset
|
541 size_t root; |
633 | 542 ngx_http_request_t *r; |
599 | 543 ngx_http_perl_ctx_t *ctx; |
544 | |
633 | 545 ngx_http_perl_set_request(r); |
599 | 546 |
547 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
633 | 548 if (ctx->filename.data) { |
599 | 549 goto done; |
550 } | |
551 | |
774
589841f06b87
previous commit broke two modules
Igor Sysoev <igor@sysoev.ru>
parents:
741
diff
changeset
|
552 if (ngx_http_map_uri_to_path(r, &ctx->filename, &root, 0) == NULL) { |
599 | 553 XSRETURN_UNDEF; |
554 } | |
555 | |
633 | 556 ctx->filename.len--; |
557 sv_setpv(PL_statname, (char *) ctx->filename.data); | |
599 | 558 |
559 done: | |
560 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
561 ngx_http_perl_set_targ(ctx->filename.data, ctx->filename.len); |
599 | 562 |
633 | 563 ST(0) = TARG; |
599 | 564 |
565 | |
633 | 566 void |
599 | 567 print(r, ...) |
568 CODE: | |
569 | |
633 | 570 ngx_http_request_t *r; |
571 SV *sv; | |
572 int i; | |
573 u_char *p; | |
574 size_t size; | |
575 STRLEN len; | |
576 ngx_buf_t *b; | |
577 | |
578 ngx_http_perl_set_request(r); | |
599 | 579 |
580 if (items == 2) { | |
581 | |
582 /* | |
583 * do zero copy for prolate single read-only SV: | |
584 * $r->print("some text\n"); | |
585 */ | |
586 | |
587 sv = ST(1); | |
588 | |
589 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
590 sv = SvRV(sv); | |
591 } | |
592 | |
1703
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
593 if (SvREADONLY(sv) && SvPOK(sv)) { |
599 | 594 |
595 p = (u_char *) SvPV(sv, len); | |
596 | |
597 if (len == 0) { | |
633 | 598 XSRETURN_EMPTY; |
599 | 599 } |
600 | |
601 b = ngx_calloc_buf(r->pool); | |
602 if (b == NULL) { | |
633 | 603 XSRETURN_EMPTY; |
599 | 604 } |
605 | |
606 b->memory = 1; | |
607 b->pos = p; | |
608 b->last = p + len; | |
609 b->start = p; | |
610 b->end = b->last; | |
611 | |
601 | 612 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
613 "$r->print: read-only SV: %z", len); | |
614 | |
599 | 615 goto out; |
616 } | |
617 } | |
618 | |
619 size = 0; | |
620 | |
621 for (i = 1; i < items; i++) { | |
622 | |
623 sv = ST(i); | |
624 | |
625 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
626 sv = SvRV(sv); | |
627 } | |
628 | |
601 | 629 (void) SvPV(sv, len); |
599 | 630 |
601 | 631 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
632 "$r->print: copy SV: %z", len); | |
599 | 633 |
634 size += len; | |
635 } | |
636 | |
637 if (size == 0) { | |
633 | 638 XSRETURN_EMPTY; |
599 | 639 } |
640 | |
641 b = ngx_create_temp_buf(r->pool, size); | |
642 if (b == NULL) { | |
633 | 643 XSRETURN_EMPTY; |
599 | 644 } |
645 | |
646 for (i = 1; i < items; i++) { | |
647 sv = ST(i); | |
648 | |
649 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
650 sv = SvRV(sv); | |
651 } | |
652 | |
653 p = (u_char *) SvPV(sv, len); | |
654 b->last = ngx_cpymem(b->last, p, len); | |
655 } | |
656 | |
657 out: | |
658 | |
633 | 659 (void) ngx_http_perl_output(r, b); |
599 | 660 |
661 | |
633 | 662 void |
613 | 663 sendfile(r, filename, offset = -1, bytes = 0) |
633 | 664 CODE: |
665 | |
1454 | 666 ngx_http_request_t *r; |
667 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
|
668 off_t offset; |
1454 | 669 size_t bytes; |
670 ngx_str_t path; | |
671 ngx_buf_t *b; | |
672 ngx_open_file_info_t of; | |
673 ngx_http_core_loc_conf_t *clcf; | |
599 | 674 |
633 | 675 ngx_http_perl_set_request(r); |
676 | |
677 filename = SvPV_nolen(ST(1)); | |
599 | 678 |
679 if (filename == NULL) { | |
680 croak("sendfile(): NULL filename"); | |
681 } | |
682 | |
633 | 683 offset = items < 3 ? -1 : SvIV(ST(2)); |
684 bytes = items < 4 ? 0 : SvIV(ST(3)); | |
685 | |
599 | 686 b = ngx_calloc_buf(r->pool); |
687 if (b == NULL) { | |
633 | 688 XSRETURN_EMPTY; |
599 | 689 } |
690 | |
691 b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)); | |
692 if (b->file == NULL) { | |
633 | 693 XSRETURN_EMPTY; |
599 | 694 } |
695 | |
1454 | 696 path.len = ngx_strlen(filename); |
697 | |
2061
b0a1c84725cf
change useless ngx_pcalloc() to ngx_pnalloc()
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
698 path.data = ngx_pnalloc(r->pool, path.len + 1); |
1454 | 699 if (path.data == NULL) { |
633 | 700 XSRETURN_EMPTY; |
599 | 701 } |
702 | |
3870 | 703 (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
|
704 |
2063
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
705 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
|
706 |
2068
75a8d34459c5
ngx_memzero() ngx_open_file_info_t
Igor Sysoev <igor@sysoev.ru>
parents:
2063
diff
changeset
|
707 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
|
708 |
3178 | 709 of.read_ahead = clcf->read_ahead; |
2129 | 710 of.directio = clcf->directio; |
2063
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
711 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
|
712 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
|
713 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
|
714 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
|
715 |
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
716 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
|
717 XSRETURN_EMPTY; |
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
718 } |
2063
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
719 |
1799 | 720 if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) |
721 != NGX_OK) | |
722 { | |
1454 | 723 if (of.err == 0) { |
724 XSRETURN_EMPTY; | |
725 } | |
726 | |
599 | 727 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
|
728 "%s \"%s\" failed", of.failed, filename); |
633 | 729 XSRETURN_EMPTY; |
599 | 730 } |
731 | |
613 | 732 if (offset == -1) { |
733 offset = 0; | |
734 } | |
735 | |
736 if (bytes == 0) { | |
1454 | 737 bytes = of.size - offset; |
599 | 738 } |
739 | |
740 b->in_file = 1; | |
613 | 741 |
742 b->file_pos = offset; | |
743 b->file_last = offset + bytes; | |
599 | 744 |
1454 | 745 b->file->fd = of.fd; |
599 | 746 b->file->log = r->connection->log; |
2231
8564129d49b6
*) handle unaligned file part for directio
Igor Sysoev <igor@sysoev.ru>
parents:
2136
diff
changeset
|
747 b->file->directio = of.is_directio; |
599 | 748 |
633 | 749 (void) ngx_http_perl_output(r, b); |
599 | 750 |
751 | |
633 | 752 void |
1178
a77f6980de50
rename $r->rflush to $r->flush
Igor Sysoev <igor@sysoev.ru>
parents:
1075
diff
changeset
|
753 flush(r) |
633 | 754 CODE: |
599 | 755 |
633 | 756 ngx_http_request_t *r; |
757 ngx_buf_t *b; | |
599 | 758 |
633 | 759 ngx_http_perl_set_request(r); |
599 | 760 |
761 b = ngx_calloc_buf(r->pool); | |
762 if (b == NULL) { | |
633 | 763 XSRETURN_EMPTY; |
599 | 764 } |
765 | |
766 b->flush = 1; | |
767 | |
1178
a77f6980de50
rename $r->rflush to $r->flush
Igor Sysoev <igor@sysoev.ru>
parents:
1075
diff
changeset
|
768 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "$r->flush"); |
601 | 769 |
633 | 770 (void) ngx_http_perl_output(r, b); |
599 | 771 |
633 | 772 XSRETURN_EMPTY; |
599 | 773 |
774 | |
775 void | |
776 internal_redirect(r, uri) | |
633 | 777 CODE: |
599 | 778 |
633 | 779 ngx_http_request_t *r; |
780 SV *uri; | |
599 | 781 ngx_uint_t i; |
782 ngx_http_perl_ctx_t *ctx; | |
783 | |
633 | 784 ngx_http_perl_set_request(r); |
785 | |
786 uri = ST(1); | |
599 | 787 |
788 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
789 | |
790 if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) { | |
791 XSRETURN_EMPTY; | |
792 } | |
793 | |
794 for (i = 0; i < ctx->redirect_uri.len; i++) { | |
795 if (ctx->redirect_uri.data[i] == '?') { | |
796 | |
797 ctx->redirect_args.len = ctx->redirect_uri.len - (i + 1); | |
798 ctx->redirect_args.data = &ctx->redirect_uri.data[i + 1]; | |
799 ctx->redirect_uri.len = i; | |
800 | |
801 XSRETURN_EMPTY; | |
802 } | |
803 } | |
601 | 804 |
805 | |
633 | 806 void |
811 | 807 allow_ranges(r) |
808 CODE: | |
809 | |
810 ngx_http_request_t *r; | |
811 | |
812 ngx_http_perl_set_request(r); | |
813 | |
814 r->allow_ranges = 1; | |
815 | |
816 | |
817 void | |
601 | 818 unescape(r, text, type = 0) |
819 CODE: | |
820 | |
633 | 821 dXSTARG; |
822 ngx_http_request_t *r; | |
823 SV *text; | |
824 int type; | |
825 u_char *p, *dst, *src; | |
826 STRLEN len; | |
601 | 827 |
633 | 828 ngx_http_perl_set_request(r); |
829 | |
830 text = ST(1); | |
831 | |
832 src = (u_char *) SvPV(text, len); | |
833 | |
2049 | 834 p = ngx_pnalloc(r->pool, len + 1); |
601 | 835 if (p == NULL) { |
836 XSRETURN_UNDEF; | |
837 } | |
838 | |
839 dst = p; | |
840 | |
633 | 841 type = items < 3 ? 0 : SvIV(ST(2)); |
842 | |
843 ngx_unescape_uri(&dst, &src, len, (ngx_uint_t) type); | |
601 | 844 *dst = '\0'; |
845 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
846 ngx_http_perl_set_targ(p, dst - p); |
601 | 847 |
633 | 848 ST(0) = TARG; |
833 | 849 |
850 | |
851 void | |
852 variable(r, name, value = NULL) | |
853 CODE: | |
854 | |
855 dXSTARG; | |
856 ngx_http_request_t *r; | |
857 SV *name, *value; | |
858 u_char *p, *lowcase; | |
859 STRLEN len; | |
860 ngx_str_t var, val; | |
861 ngx_uint_t i, hash; | |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
862 ngx_http_perl_var_t *v; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
863 ngx_http_perl_ctx_t *ctx; |
833 | 864 ngx_http_variable_value_t *vv; |
865 | |
866 ngx_http_perl_set_request(r); | |
867 | |
868 name = ST(1); | |
869 | |
870 if (SvROK(name) && SvTYPE(SvRV(name)) == SVt_PV) { | |
871 name = SvRV(name); | |
872 } | |
873 | |
874 if (items == 2) { | |
875 value = NULL; | |
876 | |
877 } else { | |
878 value = ST(2); | |
879 | |
880 if (SvROK(value) && SvTYPE(SvRV(value)) == SVt_PV) { | |
881 value = SvRV(value); | |
882 } | |
883 | |
884 if (ngx_http_perl_sv2str(aTHX_ r, &val, value) != NGX_OK) { | |
885 XSRETURN_UNDEF; | |
886 } | |
887 } | |
888 | |
889 p = (u_char *) SvPV(name, len); | |
890 | |
2049 | 891 lowcase = ngx_pnalloc(r->pool, len); |
833 | 892 if (lowcase == NULL) { |
893 XSRETURN_UNDEF; | |
894 } | |
895 | |
2136 | 896 hash = ngx_hash_strlow(lowcase, p, len); |
833 | 897 |
898 var.len = len; | |
899 var.data = lowcase; | |
5306
43900b822890
Perl: fixed syntax usage for C preprocessor directives.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5248
diff
changeset
|
900 #if (NGX_DEBUG) |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
901 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
902 if (value) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
903 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
|
904 "perl variable: \"%V\"=\"%V\"", &var, &val); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
905 } else { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
906 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
|
907 "perl variable: \"%V\"", &var); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
908 } |
5306
43900b822890
Perl: fixed syntax usage for C preprocessor directives.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5248
diff
changeset
|
909 #endif |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
910 |
3500
0eb46e3c5c02
change processing variables accessed by SSI and perl module:
Igor Sysoev <igor@sysoev.ru>
parents:
3447
diff
changeset
|
911 vv = ngx_http_get_variable(r, &var, hash); |
833 | 912 if (vv == NULL) { |
913 XSRETURN_UNDEF; | |
914 } | |
915 | |
916 if (vv->not_found) { | |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
917 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
918 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
|
919 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
920 if (ctx->variables) { |
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 v = ctx->variables->elts; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
923 for (i = 0; i < ctx->variables->nelts; i++) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
924 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
925 if (hash != v[i].hash |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
926 || len != v[i].name.len |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
927 || 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
|
928 { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
929 continue; |
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 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
932 if (value) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
933 v[i].value = val; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
934 XSRETURN_UNDEF; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
935 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
936 |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
937 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
|
938 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
939 goto done; |
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 } |
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 if (value) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
944 if (ctx->variables == NULL) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
945 ctx->variables = ngx_array_create(r->pool, 1, |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
946 sizeof(ngx_http_perl_var_t)); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
947 if (ctx->variables == NULL) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
948 XSRETURN_UNDEF; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
949 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
950 } |
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 v = ngx_array_push(ctx->variables); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
953 if (v == NULL) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
954 XSRETURN_UNDEF; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
955 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
956 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
957 v->hash = hash; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
958 v->name.len = len; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
959 v->name.data = lowcase; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
960 v->value = val; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
961 |
833 | 962 XSRETURN_UNDEF; |
963 } | |
964 | |
965 XSRETURN_UNDEF; | |
966 } | |
967 | |
968 if (value) { | |
969 vv->len = val.len; | |
970 vv->valid = 1; | |
1565 | 971 vv->no_cacheable = 0; |
833 | 972 vv->not_found = 0; |
973 vv->data = val.data; | |
974 | |
975 XSRETURN_UNDEF; | |
976 } | |
977 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
978 ngx_http_perl_set_targ(vv->data, vv->len); |
833 | 979 |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
980 done: |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
981 |
833 | 982 ST(0) = TARG; |
907 | 983 |
984 | |
985 void | |
911 | 986 sleep(r, sleep, next) |
987 CODE: | |
988 | |
989 ngx_http_request_t *r; | |
1897 | 990 ngx_msec_t sleep; |
911 | 991 ngx_http_perl_ctx_t *ctx; |
992 | |
993 ngx_http_perl_set_request(r); | |
994 | |
1898 | 995 sleep = (ngx_msec_t) SvIV(ST(1)); |
1897 | 996 |
997 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
998 "perl sleep: %M", sleep); | |
999 | |
911 | 1000 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); |
1001 | |
1002 ctx->next = SvRV(ST(2)); | |
1003 | |
1897 | 1004 ngx_add_timer(r->connection->write, sleep); |
1005 | |
1006 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
|
1007 r->main->count++; |
911 | 1008 |
1009 | |
1010 void | |
907 | 1011 log_error(r, err, msg) |
1012 CODE: | |
1013 | |
1014 ngx_http_request_t *r; | |
1015 SV *err, *msg; | |
1016 u_char *p; | |
1017 STRLEN len; | |
1018 ngx_err_t e; | |
1019 | |
1020 ngx_http_perl_set_request(r); | |
1021 | |
1022 err = ST(1); | |
1023 | |
1024 if (SvROK(err) && SvTYPE(SvRV(err)) == SVt_PV) { | |
1025 err = SvRV(err); | |
1026 } | |
1027 | |
1028 e = SvIV(err); | |
1029 | |
1030 msg = ST(2); | |
1031 | |
1032 if (SvROK(msg) && SvTYPE(SvRV(msg)) == SVt_PV) { | |
1033 msg = SvRV(msg); | |
1034 } | |
1035 | |
1036 p = (u_char *) SvPV(msg, len); | |
1037 | |
910 | 1038 ngx_log_error(NGX_LOG_ERR, r->connection->log, e, "perl: %s", p); |