Mercurial > hg > nginx
comparison src/http/modules/perl/nginx.xs @ 633:f971949ffb58 release-0.3.38
nginx-0.3.38-RELEASE import
*) Feature: the ngx_http_dav_module.
*) Change: the ngx_http_perl_module optimizations.
Thanks to Sergey Skvortsov.
*) Feature: the ngx_http_perl_module supports the $r->request_body_file
method.
*) Feature: the "client_body_in_file_only" directive.
*) Workaround: now on disk overflow nginx tries to write access logs
once a second only.
Thanks to Anton Yuzhaninov and Maxim Dounin.
*) Bugfix: now the "limit_rate" directive more precisely limits rate if
rate is more than 100 Kbyte/s.
Thanks to ForJest.
*) Bugfix: now the IMAP/POP3 proxy escapes the "\r" and "\n" symbols in
login and password to pass authorization server.
Thanks to Maxim Dounin.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 14 Apr 2006 09:53:38 +0000 |
parents | 5d2b8078c1c2 |
children | 63a820b0bc6c |
comparison
equal
deleted
inserted
replaced
632:5c60f5f0887d | 633:f971949ffb58 |
---|---|
10 #include <ngx_core.h> | 10 #include <ngx_core.h> |
11 #include <ngx_http.h> | 11 #include <ngx_http.h> |
12 #include <ngx_http_perl_module.h> | 12 #include <ngx_http_perl_module.h> |
13 | 13 |
14 #include "XSUB.h" | 14 #include "XSUB.h" |
15 | |
16 #define ngx_http_perl_set_request(r) \ | |
17 r = INT2PTR(ngx_http_request_t *, SvIV((SV *) SvRV(ST(0)))) | |
18 | |
19 | |
20 #define ngx_http_perl_set_targ(p, len, z) \ | |
21 \ | |
22 sv_upgrade(TARG, SVt_PV); \ | |
23 SvPOK_on(TARG); \ | |
24 SvPV_set(TARG, (char *) p); \ | |
25 SvLEN_set(TARG, len + z); \ | |
26 SvCUR_set(TARG, len); \ | |
27 SvFAKE_on(TARG); \ | |
28 SvREADONLY_on(TARG); \ | |
15 | 29 |
16 | 30 |
17 static ngx_int_t | 31 static ngx_int_t |
18 ngx_http_perl_sv2str(pTHX_ ngx_http_request_t *r, ngx_str_t *s, SV *sv) | 32 ngx_http_perl_sv2str(pTHX_ ngx_http_request_t *r, ngx_str_t *s, SV *sv) |
19 { | 33 { |
77 | 91 |
78 | 92 |
79 MODULE = nginx PACKAGE = nginx | 93 MODULE = nginx PACKAGE = nginx |
80 | 94 |
81 | 95 |
82 int | 96 void |
83 send_http_header(r, ...) | 97 send_http_header(r, ...) |
84 nginx r | 98 CODE: |
85 | 99 |
86 PREINIT: | 100 ngx_http_request_t *r; |
87 | 101 SV *sv; |
88 SV *sv; | 102 |
89 | 103 ngx_http_perl_set_request(r); |
90 CODE: | |
91 | 104 |
92 if (r->headers_out.status == 0) { | 105 if (r->headers_out.status == 0) { |
93 r->headers_out.status = NGX_HTTP_OK; | 106 r->headers_out.status = NGX_HTTP_OK; |
94 } | 107 } |
95 | 108 |
97 sv = ST(1); | 110 sv = ST(1); |
98 | 111 |
99 if (ngx_http_perl_sv2str(aTHX_ r, &r->headers_out.content_type, sv) | 112 if (ngx_http_perl_sv2str(aTHX_ r, &r->headers_out.content_type, sv) |
100 != NGX_OK) | 113 != NGX_OK) |
101 { | 114 { |
102 RETVAL = NGX_ERROR; | 115 XSRETURN_EMPTY; |
103 goto done; | |
104 } | 116 } |
105 | 117 |
106 } else { | 118 } else { |
107 if (r->headers_out.content_type.len == 0) { | 119 if (r->headers_out.content_type.len == 0) { |
108 if (ngx_http_set_content_type(r) != NGX_OK) { | 120 if (ngx_http_set_content_type(r) != NGX_OK) { |
109 RETVAL = NGX_ERROR; | 121 XSRETURN_EMPTY; |
110 goto done; | |
111 } | 122 } |
112 } | 123 } |
113 } | 124 } |
114 | 125 |
115 RETVAL = ngx_http_send_header(r); | 126 (void) ngx_http_send_header(r); |
116 | 127 |
117 done: | 128 |
118 | 129 void |
119 OUTPUT: | |
120 RETVAL | |
121 | |
122 | |
123 int | |
124 header_only(r) | 130 header_only(r) |
125 nginx r | 131 CODE: |
126 | 132 |
127 CODE: | 133 dXSTARG; |
128 RETVAL = r->header_only; | 134 ngx_http_request_t *r; |
129 | 135 |
130 OUTPUT: | 136 ngx_http_perl_set_request(r); |
131 RETVAL | 137 |
132 | 138 sv_upgrade(TARG, SVt_IV); |
133 | 139 sv_setiv(TARG, r->header_only); |
134 # The returning "char *" is more quickly than creating SV, because SV returned | 140 |
135 # from XS is never used as permanent storage. Even in simple case: | 141 ST(0) = TARG; |
136 # "$uri = $r->uri" the SV returned by $r->uri is copied to $uri's SV. | 142 |
137 | 143 |
138 char * | 144 void |
139 uri(r, ...) | 145 uri(r) |
140 nginx r | 146 CODE: |
141 | 147 |
142 CODE: | 148 dXSTARG; |
143 | 149 ngx_http_request_t *r; |
144 if (items != 1) { | 150 |
145 croak("$r->uri(text) is not implemented"); | 151 ngx_http_perl_set_request(r); |
146 } | 152 ngx_http_perl_set_targ(r->uri.data, r->uri.len, 0); |
147 | 153 |
148 RETVAL = ngx_palloc(r->pool, r->uri.len + 1); | 154 ST(0) = TARG; |
149 if (RETVAL == NULL) { | 155 |
150 XSRETURN_UNDEF; | 156 |
151 } | 157 void |
152 | 158 args(r) |
153 ngx_cpystrn((u_char *) RETVAL, r->uri.data, r->uri.len + 1); | 159 CODE: |
154 | 160 |
155 OUTPUT: | 161 dXSTARG; |
156 RETVAL | 162 ngx_http_request_t *r; |
157 | 163 |
158 | 164 ngx_http_perl_set_request(r); |
159 char * | 165 ngx_http_perl_set_targ(r->args.data, r->args.len, 0); |
160 args(r, ...) | 166 |
161 nginx r | 167 ST(0) = TARG; |
162 | 168 |
163 CODE: | 169 |
164 | 170 void |
165 if (items != 1) { | |
166 croak("$r->args(text) is not implemented"); | |
167 } | |
168 | |
169 RETVAL = ngx_palloc(r->pool, r->args.len + 1); | |
170 if (RETVAL == NULL) { | |
171 XSRETURN_UNDEF; | |
172 } | |
173 | |
174 ngx_cpystrn((u_char *) RETVAL, r->args.data, r->args.len + 1); | |
175 | |
176 OUTPUT: | |
177 RETVAL | |
178 | |
179 | |
180 char * | |
181 request_method(r) | 171 request_method(r) |
182 nginx r | 172 CODE: |
183 | 173 |
184 CODE: | 174 dXSTARG; |
185 | 175 ngx_http_request_t *r; |
186 RETVAL = ngx_palloc(r->pool, r->method_name.len + 1); | 176 |
187 if (RETVAL == NULL) { | 177 ngx_http_perl_set_request(r); |
188 XSRETURN_UNDEF; | 178 ngx_http_perl_set_targ(r->method_name.data, r->method_name.len, 0); |
189 } | 179 |
190 | 180 ST(0) = TARG; |
191 ngx_cpystrn((u_char *) RETVAL, r->method_name.data, r->method_name.len + 1); | 181 |
192 | 182 |
193 OUTPUT: | 183 void |
194 RETVAL | |
195 | |
196 | |
197 char * | |
198 remote_addr(r) | 184 remote_addr(r) |
199 nginx r | 185 CODE: |
200 | 186 |
201 CODE: | 187 dXSTARG; |
202 | 188 ngx_http_request_t *r; |
203 RETVAL = (char *) r->connection->addr_text.data; | 189 |
204 | 190 ngx_http_perl_set_request(r); |
205 OUTPUT: | 191 ngx_http_perl_set_targ(r->connection->addr_text.data, |
206 RETVAL | 192 r->connection->addr_text.len, 1); |
207 | 193 |
208 | 194 ST(0) = TARG; |
209 char * | 195 |
196 | |
197 void | |
210 header_in(r, key) | 198 header_in(r, key) |
211 nginx r | 199 CODE: |
212 SV *key | 200 |
213 | 201 dXSTARG; |
214 PREINIT: | 202 ngx_http_request_t *r; |
215 | 203 SV *key; |
216 u_char *p; | 204 u_char *p; |
217 STRLEN len; | 205 STRLEN len; |
218 ngx_uint_t i; | 206 ngx_uint_t i; |
219 ngx_list_part_t *part; | 207 ngx_list_part_t *part; |
220 ngx_table_elt_t *header; | 208 ngx_table_elt_t *header; |
221 | 209 |
222 CODE: | 210 ngx_http_perl_set_request(r); |
211 | |
212 key = ST(1); | |
223 | 213 |
224 if (SvROK(key) && SvTYPE(SvRV(key)) == SVt_PV) { | 214 if (SvROK(key) && SvTYPE(SvRV(key)) == SVt_PV) { |
225 key = SvRV(key); | 215 key = SvRV(key); |
226 } | 216 } |
227 | 217 |
246 || ngx_strcasecmp(p, header[i].key.data) != 0) | 236 || ngx_strcasecmp(p, header[i].key.data) != 0) |
247 { | 237 { |
248 continue; | 238 continue; |
249 } | 239 } |
250 | 240 |
251 RETVAL = (char *) header[i].value.data; | 241 ngx_http_perl_set_targ(header[i].value.data, header[i].value.len, 0); |
252 | 242 |
253 goto done; | 243 goto done; |
254 } | 244 } |
255 | 245 |
256 XSRETURN_UNDEF; | 246 XSRETURN_UNDEF; |
257 | 247 |
258 done: | 248 done: |
259 | 249 |
260 OUTPUT: | 250 ST(0) = TARG; |
261 RETVAL | 251 |
262 | 252 |
263 | 253 void |
264 SV * | |
265 request_body(r) | 254 request_body(r) |
266 nginx r | 255 CODE: |
267 | 256 |
268 PREINIT: | 257 dXSTARG; |
269 | 258 ngx_http_request_t *r; |
270 STRLEN len; | 259 size_t len; |
271 ngx_chain_t *cl; | 260 |
272 | 261 ngx_http_perl_set_request(r); |
273 CODE: | 262 |
274 | 263 if (r->request_body->temp_file || r->request_body->bufs == NULL) { |
275 len = 0; | 264 XSRETURN_UNDEF; |
276 | 265 } |
277 for (cl = r->request_body->bufs; cl; cl = cl->next) { | 266 |
278 if (cl->buf->in_file) { | 267 len = r->request_body->bufs->buf->last - r->request_body->bufs->buf->pos; |
279 XSRETURN_UNDEF; | |
280 } | |
281 | |
282 len += cl->buf->last - cl->buf->pos; | |
283 } | |
284 | 268 |
285 if (len == 0) { | 269 if (len == 0) { |
286 XSRETURN_UNDEF; | 270 XSRETURN_UNDEF; |
287 } | 271 } |
288 | 272 |
289 RETVAL = newSV(len); | 273 ngx_http_perl_set_targ(r->request_body->bufs->buf->pos, len, 0); |
290 | 274 |
291 for (cl = r->request_body->bufs; cl; cl = cl->next) { | 275 ST(0) = TARG; |
292 sv_catpvn(RETVAL, cl->buf->pos, cl->buf->last - cl->buf->pos); | 276 |
293 } | 277 |
294 | 278 void |
295 OUTPUT: | 279 request_body_file(r) |
296 RETVAL | 280 CODE: |
297 | 281 |
298 | 282 dXSTARG; |
299 int | 283 ngx_http_request_t *r; |
284 | |
285 ngx_http_perl_set_request(r); | |
286 | |
287 if (r->request_body->temp_file == NULL) { | |
288 XSRETURN_UNDEF; | |
289 } | |
290 | |
291 ngx_http_perl_set_targ(r->request_body->temp_file->file.name.data, | |
292 r->request_body->temp_file->file.name.len, 1); | |
293 | |
294 ST(0) = TARG; | |
295 | |
296 | |
297 void | |
300 header_out(r, key, value) | 298 header_out(r, key, value) |
301 nginx r | 299 CODE: |
302 SV *key | 300 |
303 SV *value | 301 ngx_http_request_t *r; |
304 | 302 SV *key; |
305 PREINIT: | 303 SV *value; |
306 | 304 ngx_table_elt_t *header; |
307 ngx_table_elt_t *header; | 305 |
308 | 306 ngx_http_perl_set_request(r); |
309 CODE: | 307 |
308 key = ST(1); | |
309 value = ST(2); | |
310 | 310 |
311 header = ngx_list_push(&r->headers_out.headers); | 311 header = ngx_list_push(&r->headers_out.headers); |
312 if (header == NULL) { | 312 if (header == NULL) { |
313 RETVAL = NGX_ERROR; | 313 XSRETURN_EMPTY; |
314 goto done; | |
315 } | 314 } |
316 | 315 |
317 header->hash = 1; | 316 header->hash = 1; |
318 | 317 |
319 if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) { | 318 if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) { |
320 RETVAL = NGX_ERROR; | 319 XSRETURN_EMPTY; |
321 goto done; | |
322 } | 320 } |
323 | 321 |
324 if (ngx_http_perl_sv2str(aTHX_ r, &header->value, value) != NGX_OK) { | 322 if (ngx_http_perl_sv2str(aTHX_ r, &header->value, value) != NGX_OK) { |
325 RETVAL = NGX_ERROR; | 323 XSRETURN_EMPTY; |
326 goto done; | |
327 } | 324 } |
328 | 325 |
329 if (header->key.len == sizeof("Content-Length") - 1 | 326 if (header->key.len == sizeof("Content-Length") - 1 |
330 && ngx_strncasecmp(header->key.data, "Content-Length", | 327 && ngx_strncasecmp(header->key.data, "Content-Length", |
331 sizeof("Content-Length") - 1) == 0 | 328 sizeof("Content-Length") - 1) == 0 |
333 { | 330 { |
334 r->headers_out.content_length_n = (ssize_t) SvIV(value);; | 331 r->headers_out.content_length_n = (ssize_t) SvIV(value);; |
335 r->headers_out.content_length = header; | 332 r->headers_out.content_length = header; |
336 } | 333 } |
337 | 334 |
338 RETVAL = NGX_OK; | 335 XSRETURN_EMPTY; |
336 | |
337 | |
338 void | |
339 filename(r) | |
340 CODE: | |
341 | |
342 dXSTARG; | |
343 ngx_http_request_t *r; | |
344 ngx_http_perl_ctx_t *ctx; | |
345 | |
346 ngx_http_perl_set_request(r); | |
347 | |
348 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
349 if (ctx->filename.data) { | |
350 goto done; | |
351 } | |
352 | |
353 if (ngx_http_map_uri_to_path(r, &ctx->filename, 0) == NULL) { | |
354 XSRETURN_UNDEF; | |
355 } | |
356 | |
357 ctx->filename.len--; | |
358 sv_setpv(PL_statname, (char *) ctx->filename.data); | |
339 | 359 |
340 done: | 360 done: |
341 | 361 |
342 OUTPUT: | 362 ngx_http_perl_set_targ(ctx->filename.data, ctx->filename.len, 1); |
343 RETVAL | 363 |
344 | 364 ST(0) = TARG; |
345 | 365 |
346 char * | 366 |
347 filename(r) | 367 void |
348 nginx r | |
349 | |
350 PREINIT: | |
351 | |
352 ngx_str_t path; | |
353 ngx_http_perl_ctx_t *ctx; | |
354 | |
355 CODE: | |
356 | |
357 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
358 if (ctx->filename) { | |
359 goto done; | |
360 } | |
361 | |
362 if (ngx_http_map_uri_to_path(r, &path, 0) == NULL) { | |
363 XSRETURN_UNDEF; | |
364 } | |
365 | |
366 ctx->filename = (char *) path.data; | |
367 | |
368 sv_setpv(PL_statname, ctx->filename); | |
369 | |
370 done: | |
371 | |
372 RETVAL = ctx->filename; | |
373 | |
374 OUTPUT: | |
375 RETVAL | |
376 | |
377 | |
378 int | |
379 print(r, ...) | 368 print(r, ...) |
380 nginx r | 369 CODE: |
381 | 370 |
382 PREINIT: | 371 ngx_http_request_t *r; |
383 | 372 SV *sv; |
384 SV *sv; | 373 int i; |
385 int i; | 374 u_char *p; |
386 u_char *p; | 375 size_t size; |
387 size_t size; | 376 STRLEN len; |
388 STRLEN len; | 377 ngx_buf_t *b; |
389 ngx_buf_t *b; | 378 |
390 | 379 ngx_http_perl_set_request(r); |
391 CODE: | |
392 | |
393 RETVAL = NGX_OK; | |
394 | 380 |
395 if (items == 2) { | 381 if (items == 2) { |
396 | 382 |
397 /* | 383 /* |
398 * do zero copy for prolate single read-only SV: | 384 * do zero copy for prolate single read-only SV: |
408 if (SvREADONLY(sv)) { | 394 if (SvREADONLY(sv)) { |
409 | 395 |
410 p = (u_char *) SvPV(sv, len); | 396 p = (u_char *) SvPV(sv, len); |
411 | 397 |
412 if (len == 0) { | 398 if (len == 0) { |
413 goto done; | 399 XSRETURN_EMPTY; |
414 } | 400 } |
415 | 401 |
416 b = ngx_calloc_buf(r->pool); | 402 b = ngx_calloc_buf(r->pool); |
417 if (b == NULL) { | 403 if (b == NULL) { |
418 RETVAL = NGX_ERROR; | 404 XSRETURN_EMPTY; |
419 goto done; | |
420 } | 405 } |
421 | 406 |
422 b->memory = 1; | 407 b->memory = 1; |
423 b->pos = p; | 408 b->pos = p; |
424 b->last = p + len; | 409 b->last = p + len; |
449 | 434 |
450 size += len; | 435 size += len; |
451 } | 436 } |
452 | 437 |
453 if (size == 0) { | 438 if (size == 0) { |
454 goto done; | 439 XSRETURN_EMPTY; |
455 } | 440 } |
456 | 441 |
457 b = ngx_create_temp_buf(r->pool, size); | 442 b = ngx_create_temp_buf(r->pool, size); |
458 if (b == NULL) { | 443 if (b == NULL) { |
459 RETVAL = NGX_ERROR; | 444 XSRETURN_EMPTY; |
460 goto done; | |
461 } | 445 } |
462 | 446 |
463 for (i = 1; i < items; i++) { | 447 for (i = 1; i < items; i++) { |
464 sv = ST(i); | 448 sv = ST(i); |
465 | 449 |
471 b->last = ngx_cpymem(b->last, p, len); | 455 b->last = ngx_cpymem(b->last, p, len); |
472 } | 456 } |
473 | 457 |
474 out: | 458 out: |
475 | 459 |
476 RETVAL = ngx_http_perl_output(r, b); | 460 (void) ngx_http_perl_output(r, b); |
477 | 461 |
478 done: | 462 XSRETURN_EMPTY; |
479 | 463 |
480 OUTPUT: | 464 |
481 RETVAL | 465 void |
482 | |
483 | |
484 int | |
485 sendfile(r, filename, offset = -1, bytes = 0) | 466 sendfile(r, filename, offset = -1, bytes = 0) |
486 nginx r | 467 CODE: |
487 char *filename | 468 |
469 ngx_http_request_t *r; | |
470 char *filename; | |
488 int offset; | 471 int offset; |
489 size_t bytes; | 472 size_t bytes; |
490 | |
491 PREINIT: | |
492 | |
493 ngx_fd_t fd; | 473 ngx_fd_t fd; |
494 ngx_buf_t *b; | 474 ngx_buf_t *b; |
495 ngx_file_info_t fi; | 475 ngx_file_info_t fi; |
496 ngx_pool_cleanup_t *cln; | 476 ngx_pool_cleanup_t *cln; |
497 ngx_pool_cleanup_file_t *clnf; | 477 ngx_pool_cleanup_file_t *clnf; |
498 | 478 |
499 CODE: | 479 ngx_http_perl_set_request(r); |
480 | |
481 filename = SvPV_nolen(ST(1)); | |
500 | 482 |
501 if (filename == NULL) { | 483 if (filename == NULL) { |
502 croak("sendfile(): NULL filename"); | 484 croak("sendfile(): NULL filename"); |
503 } | 485 } |
504 | 486 |
487 offset = items < 3 ? -1 : SvIV(ST(2)); | |
488 bytes = items < 4 ? 0 : SvIV(ST(3)); | |
489 | |
505 b = ngx_calloc_buf(r->pool); | 490 b = ngx_calloc_buf(r->pool); |
506 if (b == NULL) { | 491 if (b == NULL) { |
507 RETVAL = NGX_ERROR; | 492 XSRETURN_EMPTY; |
508 goto done; | |
509 } | 493 } |
510 | 494 |
511 b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)); | 495 b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)); |
512 if (b->file == NULL) { | 496 if (b->file == NULL) { |
513 RETVAL = NGX_ERROR; | 497 XSRETURN_EMPTY; |
514 goto done; | |
515 } | 498 } |
516 | 499 |
517 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t)); | 500 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t)); |
518 if (cln == NULL) { | 501 if (cln == NULL) { |
519 RETVAL = NGX_ERROR; | 502 XSRETURN_EMPTY; |
520 goto done; | |
521 } | 503 } |
522 | 504 |
523 fd = ngx_open_file((u_char *) filename, NGX_FILE_RDONLY, NGX_FILE_OPEN); | 505 fd = ngx_open_file((u_char *) filename, NGX_FILE_RDONLY, NGX_FILE_OPEN); |
524 | 506 |
525 if (fd == NGX_INVALID_FILE) { | 507 if (fd == NGX_INVALID_FILE) { |
526 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, | 508 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, |
527 ngx_open_file_n " \"%s\" failed", filename); | 509 ngx_open_file_n " \"%s\" failed", filename); |
528 RETVAL = NGX_ERROR; | 510 XSRETURN_EMPTY; |
529 goto done; | |
530 } | 511 } |
531 | 512 |
532 if (offset == -1) { | 513 if (offset == -1) { |
533 offset = 0; | 514 offset = 0; |
534 } | 515 } |
541 if (ngx_close_file(fd) == NGX_FILE_ERROR) { | 522 if (ngx_close_file(fd) == NGX_FILE_ERROR) { |
542 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, | 523 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, |
543 ngx_close_file_n " \"%s\" failed", filename); | 524 ngx_close_file_n " \"%s\" failed", filename); |
544 } | 525 } |
545 | 526 |
546 RETVAL = NGX_ERROR; | 527 XSRETURN_EMPTY; |
547 goto done; | |
548 | |
549 } | 528 } |
550 | 529 |
551 bytes = ngx_file_size(&fi) - offset; | 530 bytes = ngx_file_size(&fi) - offset; |
552 } | 531 } |
553 | 532 |
564 b->file_last = offset + bytes; | 543 b->file_last = offset + bytes; |
565 | 544 |
566 b->file->fd = fd; | 545 b->file->fd = fd; |
567 b->file->log = r->connection->log; | 546 b->file->log = r->connection->log; |
568 | 547 |
569 RETVAL = ngx_http_perl_output(r, b); | 548 (void) ngx_http_perl_output(r, b); |
570 | 549 |
571 done: | 550 XSRETURN_EMPTY; |
572 | 551 |
573 OUTPUT: | 552 |
574 RETVAL | 553 void |
575 | |
576 | |
577 int | |
578 rflush(r) | 554 rflush(r) |
579 nginx r | 555 CODE: |
580 | 556 |
581 PREINIT: | 557 ngx_http_request_t *r; |
582 | 558 ngx_buf_t *b; |
583 ngx_buf_t *b; | 559 |
584 | 560 ngx_http_perl_set_request(r); |
585 CODE: | |
586 | 561 |
587 b = ngx_calloc_buf(r->pool); | 562 b = ngx_calloc_buf(r->pool); |
588 if (b == NULL) { | 563 if (b == NULL) { |
589 RETVAL = NGX_ERROR; | 564 XSRETURN_EMPTY; |
590 goto done; | |
591 } | 565 } |
592 | 566 |
593 b->flush = 1; | 567 b->flush = 1; |
594 | 568 |
595 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "$r->rflush"); | 569 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "$r->rflush"); |
596 | 570 |
597 RETVAL = ngx_http_perl_output(r, b); | 571 (void) ngx_http_perl_output(r, b); |
598 | 572 |
599 done: | 573 XSRETURN_EMPTY; |
600 | |
601 OUTPUT: | |
602 RETVAL | |
603 | 574 |
604 | 575 |
605 void | 576 void |
606 internal_redirect(r, uri) | 577 internal_redirect(r, uri) |
607 nginx r | 578 CODE: |
608 SV *uri | 579 |
609 | 580 ngx_http_request_t *r; |
610 PREINIT: | 581 SV *uri; |
611 | |
612 ngx_uint_t i; | 582 ngx_uint_t i; |
613 ngx_http_perl_ctx_t *ctx; | 583 ngx_http_perl_ctx_t *ctx; |
614 | 584 |
615 CODE: | 585 ngx_http_perl_set_request(r); |
586 | |
587 uri = ST(1); | |
616 | 588 |
617 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | 589 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); |
618 | 590 |
619 if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) { | 591 if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) { |
620 XSRETURN_EMPTY; | 592 XSRETURN_EMPTY; |
630 XSRETURN_EMPTY; | 602 XSRETURN_EMPTY; |
631 } | 603 } |
632 } | 604 } |
633 | 605 |
634 | 606 |
635 char * | 607 void |
636 unescape(r, text, type = 0) | 608 unescape(r, text, type = 0) |
637 nginx r | 609 CODE: |
638 SV *text | 610 |
639 int type | 611 dXSTARG; |
640 | 612 ngx_http_request_t *r; |
641 PREINIT: | 613 SV *text; |
642 | 614 int type; |
643 u_char *p, *dst, *src; | 615 u_char *p, *dst, *src; |
644 STRLEN n; | 616 STRLEN len; |
645 | 617 |
646 CODE: | 618 ngx_http_perl_set_request(r); |
647 | 619 |
648 src = (u_char *) SvPV(text, n); | 620 text = ST(1); |
649 | 621 |
650 p = ngx_palloc(r->pool, n + 1); | 622 src = (u_char *) SvPV(text, len); |
623 | |
624 p = ngx_palloc(r->pool, len + 1); | |
651 if (p == NULL) { | 625 if (p == NULL) { |
652 XSRETURN_UNDEF; | 626 XSRETURN_UNDEF; |
653 } | 627 } |
654 | 628 |
655 dst = p; | 629 dst = p; |
656 | 630 |
657 ngx_unescape_uri(&dst, &src, n, (ngx_uint_t) type); | 631 type = items < 3 ? 0 : SvIV(ST(2)); |
632 | |
633 ngx_unescape_uri(&dst, &src, len, (ngx_uint_t) type); | |
658 *dst = '\0'; | 634 *dst = '\0'; |
659 | 635 |
660 RETVAL = (char *) p; | 636 ngx_http_perl_set_targ(p, dst - p, 1); |
661 | 637 |
662 OUTPUT: | 638 ST(0) = TARG; |
663 RETVAL |