Annotation of embedaddon/php/ext/standard/url.c, revision 1.1.1.2
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1997-2012 The PHP Group |
6: +----------------------------------------------------------------------+
7: | This source file is subject to version 3.01 of the PHP license, |
8: | that is bundled with this package in the file LICENSE, and is |
9: | available through the world-wide-web at the following url: |
10: | http://www.php.net/license/3_01.txt |
11: | If you did not receive a copy of the PHP license and are unable to |
12: | obtain it through the world-wide-web, please send a note to |
13: | license@php.net so we can mail you a copy immediately. |
14: +----------------------------------------------------------------------+
15: | Author: Jim Winstead <jimw@php.net> |
16: +----------------------------------------------------------------------+
17: */
1.1.1.2 ! misho 18: /* $Id$ */
1.1 misho 19:
20: #include <stdlib.h>
21: #include <string.h>
22: #include <ctype.h>
23: #include <sys/types.h>
24:
25: #include "php.h"
26:
27: #include "url.h"
28: #include "file.h"
29: #ifdef _OSD_POSIX
30: #ifndef APACHE
31: #error On this EBCDIC platform, PHP is only supported as an Apache module.
32: #else /*APACHE*/
33: #ifndef CHARSET_EBCDIC
34: #define CHARSET_EBCDIC /* this machine uses EBCDIC, not ASCII! */
35: #endif
36: #include "ebcdic.h"
37: #endif /*APACHE*/
38: #endif /*_OSD_POSIX*/
39:
40: /* {{{ free_url
41: */
42: PHPAPI void php_url_free(php_url *theurl)
43: {
44: if (theurl->scheme)
45: efree(theurl->scheme);
46: if (theurl->user)
47: efree(theurl->user);
48: if (theurl->pass)
49: efree(theurl->pass);
50: if (theurl->host)
51: efree(theurl->host);
52: if (theurl->path)
53: efree(theurl->path);
54: if (theurl->query)
55: efree(theurl->query);
56: if (theurl->fragment)
57: efree(theurl->fragment);
58: efree(theurl);
59: }
60: /* }}} */
61:
62: /* {{{ php_replace_controlchars
63: */
64: PHPAPI char *php_replace_controlchars_ex(char *str, int len)
65: {
66: unsigned char *s = (unsigned char *)str;
67: unsigned char *e = (unsigned char *)str + len;
68:
69: if (!str) {
70: return (NULL);
71: }
72:
73: while (s < e) {
74:
75: if (iscntrl(*s)) {
76: *s='_';
77: }
78: s++;
79: }
80:
81: return (str);
82: }
83: /* }}} */
84:
85: PHPAPI char *php_replace_controlchars(char *str)
86: {
87: return php_replace_controlchars_ex(str, strlen(str));
88: }
89:
90: PHPAPI php_url *php_url_parse(char const *str)
91: {
92: return php_url_parse_ex(str, strlen(str));
93: }
94:
95: /* {{{ php_url_parse
96: */
97: PHPAPI php_url *php_url_parse_ex(char const *str, int length)
98: {
99: char port_buf[6];
100: php_url *ret = ecalloc(1, sizeof(php_url));
101: char const *s, *e, *p, *pp, *ue;
102:
103: s = str;
104: ue = s + length;
105:
106: /* parse scheme */
107: if ((e = memchr(s, ':', length)) && (e - s)) {
108: /* validate scheme */
109: p = s;
110: while (p < e) {
111: /* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] */
112: if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') {
113: if (e + 1 < ue) {
114: goto parse_port;
115: } else {
116: goto just_path;
117: }
118: }
119: p++;
120: }
121:
122: if (*(e + 1) == '\0') { /* only scheme is available */
123: ret->scheme = estrndup(s, (e - s));
124: php_replace_controlchars_ex(ret->scheme, (e - s));
125: goto end;
126: }
127:
128: /*
129: * certain schemas like mailto: and zlib: may not have any / after them
130: * this check ensures we support those.
131: */
132: if (*(e+1) != '/') {
133: /* check if the data we get is a port this allows us to
134: * correctly parse things like a.com:80
135: */
136: p = e + 1;
137: while (isdigit(*p)) {
138: p++;
139: }
140:
141: if ((*p == '\0' || *p == '/') && (p - e) < 7) {
142: goto parse_port;
143: }
144:
145: ret->scheme = estrndup(s, (e-s));
146: php_replace_controlchars_ex(ret->scheme, (e - s));
147:
148: length -= ++e - s;
149: s = e;
150: goto just_path;
151: } else {
152: ret->scheme = estrndup(s, (e-s));
153: php_replace_controlchars_ex(ret->scheme, (e - s));
154:
155: if (*(e+2) == '/') {
156: s = e + 3;
157: if (!strncasecmp("file", ret->scheme, sizeof("file"))) {
158: if (*(e + 3) == '/') {
159: /* support windows drive letters as in:
160: file:///c:/somedir/file.txt
161: */
162: if (*(e + 5) == ':') {
163: s = e + 4;
164: }
165: goto nohost;
166: }
167: }
168: } else {
169: if (!strncasecmp("file", ret->scheme, sizeof("file"))) {
170: s = e + 1;
171: goto nohost;
172: } else {
173: length -= ++e - s;
174: s = e;
175: goto just_path;
176: }
177: }
178: }
179: } else if (e) { /* no scheme; starts with colon: look for port */
180: parse_port:
181: p = e + 1;
182: pp = p;
183:
184: while (pp-p < 6 && isdigit(*pp)) {
185: pp++;
186: }
187:
188: if (pp - p > 0 && pp - p < 6 && (*pp == '/' || *pp == '\0')) {
189: long port;
190: memcpy(port_buf, p, (pp - p));
191: port_buf[pp - p] = '\0';
192: port = strtol(port_buf, NULL, 10);
193: if (port > 0 && port <= 65535) {
194: ret->port = (unsigned short) port;
195: } else {
196: STR_FREE(ret->scheme);
197: efree(ret);
198: return NULL;
199: }
200: } else if (p == pp && *pp == '\0') {
201: STR_FREE(ret->scheme);
202: efree(ret);
203: return NULL;
204: } else {
205: goto just_path;
206: }
207: } else {
208: just_path:
209: ue = s + length;
210: goto nohost;
211: }
212:
213: e = ue;
214:
215: if (!(p = memchr(s, '/', (ue - s)))) {
216: char *query, *fragment;
217:
218: query = memchr(s, '?', (ue - s));
219: fragment = memchr(s, '#', (ue - s));
220:
221: if (query && fragment) {
222: if (query > fragment) {
223: p = e = fragment;
224: } else {
225: p = e = query;
226: }
227: } else if (query) {
228: p = e = query;
229: } else if (fragment) {
230: p = e = fragment;
231: }
232: } else {
233: e = p;
234: }
235:
236: /* check for login and password */
237: if ((p = zend_memrchr(s, '@', (e-s)))) {
238: if ((pp = memchr(s, ':', (p-s)))) {
239: if ((pp-s) > 0) {
240: ret->user = estrndup(s, (pp-s));
241: php_replace_controlchars_ex(ret->user, (pp - s));
242: }
243:
244: pp++;
245: if (p-pp > 0) {
246: ret->pass = estrndup(pp, (p-pp));
247: php_replace_controlchars_ex(ret->pass, (p-pp));
248: }
249: } else {
250: ret->user = estrndup(s, (p-s));
251: php_replace_controlchars_ex(ret->user, (p-s));
252: }
253:
254: s = p + 1;
255: }
256:
257: /* check for port */
258: if (*s == '[' && *(e-1) == ']') {
259: /* Short circuit portscan,
260: we're dealing with an
261: IPv6 embedded address */
262: p = s;
263: } else {
264: /* memrchr is a GNU specific extension
265: Emulate for wide compatability */
266: for(p = e; *p != ':' && p >= s; p--);
267: }
268:
269: if (p >= s && *p == ':') {
270: if (!ret->port) {
271: p++;
272: if (e-p > 5) { /* port cannot be longer then 5 characters */
273: STR_FREE(ret->scheme);
274: STR_FREE(ret->user);
275: STR_FREE(ret->pass);
276: efree(ret);
277: return NULL;
278: } else if (e - p > 0) {
279: long port;
280: memcpy(port_buf, p, (e - p));
281: port_buf[e - p] = '\0';
282: port = strtol(port_buf, NULL, 10);
283: if (port > 0 && port <= 65535) {
284: ret->port = (unsigned short)port;
285: } else {
286: STR_FREE(ret->scheme);
287: STR_FREE(ret->user);
288: STR_FREE(ret->pass);
289: efree(ret);
290: return NULL;
291: }
292: }
293: p--;
294: }
295: } else {
296: p = e;
297: }
298:
299: /* check if we have a valid host, if we don't reject the string as url */
300: if ((p-s) < 1) {
301: STR_FREE(ret->scheme);
302: STR_FREE(ret->user);
303: STR_FREE(ret->pass);
304: efree(ret);
305: return NULL;
306: }
307:
308: ret->host = estrndup(s, (p-s));
309: php_replace_controlchars_ex(ret->host, (p - s));
310:
311: if (e == ue) {
312: return ret;
313: }
314:
315: s = e;
316:
317: nohost:
318:
319: if ((p = memchr(s, '?', (ue - s)))) {
320: pp = strchr(s, '#');
321:
322: if (pp && pp < p) {
323: if (pp - s) {
324: ret->path = estrndup(s, (pp-s));
325: php_replace_controlchars_ex(ret->path, (pp - s));
326: }
327: p = pp;
328: goto label_parse;
329: }
330:
331: if (p - s) {
332: ret->path = estrndup(s, (p-s));
333: php_replace_controlchars_ex(ret->path, (p - s));
334: }
335:
336: if (pp) {
337: if (pp - ++p) {
338: ret->query = estrndup(p, (pp-p));
339: php_replace_controlchars_ex(ret->query, (pp - p));
340: }
341: p = pp;
342: goto label_parse;
343: } else if (++p - ue) {
344: ret->query = estrndup(p, (ue-p));
345: php_replace_controlchars_ex(ret->query, (ue - p));
346: }
347: } else if ((p = memchr(s, '#', (ue - s)))) {
348: if (p - s) {
349: ret->path = estrndup(s, (p-s));
350: php_replace_controlchars_ex(ret->path, (p - s));
351: }
352:
353: label_parse:
354: p++;
355:
356: if (ue - p) {
357: ret->fragment = estrndup(p, (ue-p));
358: php_replace_controlchars_ex(ret->fragment, (ue - p));
359: }
360: } else {
361: ret->path = estrndup(s, (ue-s));
362: php_replace_controlchars_ex(ret->path, (ue - s));
363: }
364: end:
365: return ret;
366: }
367: /* }}} */
368:
369: /* {{{ proto mixed parse_url(string url, [int url_component])
370: Parse a URL and return its components */
371: PHP_FUNCTION(parse_url)
372: {
373: char *str;
374: int str_len;
375: php_url *resource;
376: long key = -1;
377:
378: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &key) == FAILURE) {
379: return;
380: }
381:
382: resource = php_url_parse_ex(str, str_len);
383: if (resource == NULL) {
384: /* @todo Find a method to determine why php_url_parse_ex() failed */
385: RETURN_FALSE;
386: }
387:
388: if (key > -1) {
389: switch (key) {
390: case PHP_URL_SCHEME:
391: if (resource->scheme != NULL) RETVAL_STRING(resource->scheme, 1);
392: break;
393: case PHP_URL_HOST:
394: if (resource->host != NULL) RETVAL_STRING(resource->host, 1);
395: break;
396: case PHP_URL_PORT:
397: if (resource->port != 0) RETVAL_LONG(resource->port);
398: break;
399: case PHP_URL_USER:
400: if (resource->user != NULL) RETVAL_STRING(resource->user, 1);
401: break;
402: case PHP_URL_PASS:
403: if (resource->pass != NULL) RETVAL_STRING(resource->pass, 1);
404: break;
405: case PHP_URL_PATH:
406: if (resource->path != NULL) RETVAL_STRING(resource->path, 1);
407: break;
408: case PHP_URL_QUERY:
409: if (resource->query != NULL) RETVAL_STRING(resource->query, 1);
410: break;
411: case PHP_URL_FRAGMENT:
412: if (resource->fragment != NULL) RETVAL_STRING(resource->fragment, 1);
413: break;
414: default:
415: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid URL component identifier %ld", key);
416: RETVAL_FALSE;
417: }
418: goto done;
419: }
420:
421: /* allocate an array for return */
422: array_init(return_value);
423:
424: /* add the various elements to the array */
425: if (resource->scheme != NULL)
426: add_assoc_string(return_value, "scheme", resource->scheme, 1);
427: if (resource->host != NULL)
428: add_assoc_string(return_value, "host", resource->host, 1);
429: if (resource->port != 0)
430: add_assoc_long(return_value, "port", resource->port);
431: if (resource->user != NULL)
432: add_assoc_string(return_value, "user", resource->user, 1);
433: if (resource->pass != NULL)
434: add_assoc_string(return_value, "pass", resource->pass, 1);
435: if (resource->path != NULL)
436: add_assoc_string(return_value, "path", resource->path, 1);
437: if (resource->query != NULL)
438: add_assoc_string(return_value, "query", resource->query, 1);
439: if (resource->fragment != NULL)
440: add_assoc_string(return_value, "fragment", resource->fragment, 1);
441: done:
442: php_url_free(resource);
443: }
444: /* }}} */
445:
446: /* {{{ php_htoi
447: */
448: static int php_htoi(char *s)
449: {
450: int value;
451: int c;
452:
453: c = ((unsigned char *)s)[0];
454: if (isupper(c))
455: c = tolower(c);
456: value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
457:
458: c = ((unsigned char *)s)[1];
459: if (isupper(c))
460: c = tolower(c);
461: value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
462:
463: return (value);
464: }
465: /* }}} */
466:
467: /* rfc1738:
468:
469: ...The characters ";",
470: "/", "?", ":", "@", "=" and "&" are the characters which may be
471: reserved for special meaning within a scheme...
472:
473: ...Thus, only alphanumerics, the special characters "$-_.+!*'(),", and
474: reserved characters used for their reserved purposes may be used
475: unencoded within a URL...
476:
477: For added safety, we only leave -_. unencoded.
478: */
479:
480: static unsigned char hexchars[] = "0123456789ABCDEF";
481:
482: /* {{{ php_url_encode
483: */
484: PHPAPI char *php_url_encode(char const *s, int len, int *new_length)
485: {
486: register unsigned char c;
487: unsigned char *to, *start;
488: unsigned char const *from, *end;
489:
490: from = (unsigned char *)s;
491: end = (unsigned char *)s + len;
492: start = to = (unsigned char *) safe_emalloc(3, len, 1);
493:
494: while (from < end) {
495: c = *from++;
496:
497: if (c == ' ') {
498: *to++ = '+';
499: #ifndef CHARSET_EBCDIC
500: } else if ((c < '0' && c != '-' && c != '.') ||
501: (c < 'A' && c > '9') ||
502: (c > 'Z' && c < 'a' && c != '_') ||
503: (c > 'z')) {
504: to[0] = '%';
505: to[1] = hexchars[c >> 4];
506: to[2] = hexchars[c & 15];
507: to += 3;
508: #else /*CHARSET_EBCDIC*/
509: } else if (!isalnum(c) && strchr("_-.", c) == NULL) {
510: /* Allow only alphanumeric chars and '_', '-', '.'; escape the rest */
511: to[0] = '%';
512: to[1] = hexchars[os_toascii[c] >> 4];
513: to[2] = hexchars[os_toascii[c] & 15];
514: to += 3;
515: #endif /*CHARSET_EBCDIC*/
516: } else {
517: *to++ = c;
518: }
519: }
520: *to = 0;
521: if (new_length) {
522: *new_length = to - start;
523: }
524: return (char *) start;
525: }
526: /* }}} */
527:
528: /* {{{ proto string urlencode(string str)
529: URL-encodes string */
530: PHP_FUNCTION(urlencode)
531: {
532: char *in_str, *out_str;
533: int in_str_len, out_str_len;
534:
535: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
536: &in_str_len) == FAILURE) {
537: return;
538: }
539:
540: out_str = php_url_encode(in_str, in_str_len, &out_str_len);
541: RETURN_STRINGL(out_str, out_str_len, 0);
542: }
543: /* }}} */
544:
545: /* {{{ proto string urldecode(string str)
546: Decodes URL-encoded string */
547: PHP_FUNCTION(urldecode)
548: {
549: char *in_str, *out_str;
550: int in_str_len, out_str_len;
551:
552: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
553: &in_str_len) == FAILURE) {
554: return;
555: }
556:
557: out_str = estrndup(in_str, in_str_len);
558: out_str_len = php_url_decode(out_str, in_str_len);
559:
560: RETURN_STRINGL(out_str, out_str_len, 0);
561: }
562: /* }}} */
563:
564: /* {{{ php_url_decode
565: */
566: PHPAPI int php_url_decode(char *str, int len)
567: {
568: char *dest = str;
569: char *data = str;
570:
571: while (len--) {
572: if (*data == '+') {
573: *dest = ' ';
574: }
575: else if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1))
576: && isxdigit((int) *(data + 2))) {
577: #ifndef CHARSET_EBCDIC
578: *dest = (char) php_htoi(data + 1);
579: #else
580: *dest = os_toebcdic[(char) php_htoi(data + 1)];
581: #endif
582: data += 2;
583: len -= 2;
584: } else {
585: *dest = *data;
586: }
587: data++;
588: dest++;
589: }
590: *dest = '\0';
591: return dest - str;
592: }
593: /* }}} */
594:
595: /* {{{ php_raw_url_encode
596: */
597: PHPAPI char *php_raw_url_encode(char const *s, int len, int *new_length)
598: {
599: register int x, y;
600: unsigned char *str;
601:
602: str = (unsigned char *) safe_emalloc(3, len, 1);
603: for (x = 0, y = 0; len--; x++, y++) {
604: str[y] = (unsigned char) s[x];
605: #ifndef CHARSET_EBCDIC
606: if ((str[y] < '0' && str[y] != '-' && str[y] != '.') ||
607: (str[y] < 'A' && str[y] > '9') ||
608: (str[y] > 'Z' && str[y] < 'a' && str[y] != '_') ||
609: (str[y] > 'z' && str[y] != '~')) {
610: str[y++] = '%';
611: str[y++] = hexchars[(unsigned char) s[x] >> 4];
612: str[y] = hexchars[(unsigned char) s[x] & 15];
613: #else /*CHARSET_EBCDIC*/
614: if (!isalnum(str[y]) && strchr("_-.~", str[y]) != NULL) {
615: str[y++] = '%';
616: str[y++] = hexchars[os_toascii[(unsigned char) s[x]] >> 4];
617: str[y] = hexchars[os_toascii[(unsigned char) s[x]] & 15];
618: #endif /*CHARSET_EBCDIC*/
619: }
620: }
621: str[y] = '\0';
622: if (new_length) {
623: *new_length = y;
624: }
625: return ((char *) str);
626: }
627: /* }}} */
628:
629: /* {{{ proto string rawurlencode(string str)
630: URL-encodes string */
631: PHP_FUNCTION(rawurlencode)
632: {
633: char *in_str, *out_str;
634: int in_str_len, out_str_len;
635:
636: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
637: &in_str_len) == FAILURE) {
638: return;
639: }
640:
641: out_str = php_raw_url_encode(in_str, in_str_len, &out_str_len);
642: RETURN_STRINGL(out_str, out_str_len, 0);
643: }
644: /* }}} */
645:
646: /* {{{ proto string rawurldecode(string str)
647: Decodes URL-encodes string */
648: PHP_FUNCTION(rawurldecode)
649: {
650: char *in_str, *out_str;
651: int in_str_len, out_str_len;
652:
653: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
654: &in_str_len) == FAILURE) {
655: return;
656: }
657:
658: out_str = estrndup(in_str, in_str_len);
659: out_str_len = php_raw_url_decode(out_str, in_str_len);
660:
661: RETURN_STRINGL(out_str, out_str_len, 0);
662: }
663: /* }}} */
664:
665: /* {{{ php_raw_url_decode
666: */
667: PHPAPI int php_raw_url_decode(char *str, int len)
668: {
669: char *dest = str;
670: char *data = str;
671:
672: while (len--) {
673: if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1))
674: && isxdigit((int) *(data + 2))) {
675: #ifndef CHARSET_EBCDIC
676: *dest = (char) php_htoi(data + 1);
677: #else
678: *dest = os_toebcdic[(char) php_htoi(data + 1)];
679: #endif
680: data += 2;
681: len -= 2;
682: } else {
683: *dest = *data;
684: }
685: data++;
686: dest++;
687: }
688: *dest = '\0';
689: return dest - str;
690: }
691: /* }}} */
692:
693: /* {{{ proto array get_headers(string url[, int format])
694: fetches all the headers sent by the server in response to a HTTP request */
695: PHP_FUNCTION(get_headers)
696: {
697: char *url;
698: int url_len;
699: php_stream_context *context;
700: php_stream *stream;
701: zval **prev_val, **hdr = NULL, **h;
702: HashPosition pos;
703: HashTable *hashT;
704: long format = 0;
705:
706: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &url, &url_len, &format) == FAILURE) {
707: return;
708: }
1.1.1.2 ! misho 709: context = FG(default_context) ? FG(default_context) : (FG(default_context) = php_stream_context_alloc(TSRMLS_C));
1.1 misho 710:
711: if (!(stream = php_stream_open_wrapper_ex(url, "r", REPORT_ERRORS | STREAM_USE_URL | STREAM_ONLY_GET_HEADERS, NULL, context))) {
712: RETURN_FALSE;
713: }
714:
715: if (!stream->wrapperdata || Z_TYPE_P(stream->wrapperdata) != IS_ARRAY) {
716: php_stream_close(stream);
717: RETURN_FALSE;
718: }
719:
720: array_init(return_value);
721:
722: /* check for curl-wrappers that provide headers via a special "headers" element */
723: if (zend_hash_find(HASH_OF(stream->wrapperdata), "headers", sizeof("headers"), (void **)&h) != FAILURE && Z_TYPE_PP(h) == IS_ARRAY) {
724: /* curl-wrappers don't load data until the 1st read */
725: if (!Z_ARRVAL_PP(h)->nNumOfElements) {
726: php_stream_getc(stream);
727: }
728: zend_hash_find(HASH_OF(stream->wrapperdata), "headers", sizeof("headers"), (void **)&h);
729: hashT = Z_ARRVAL_PP(h);
730: } else {
731: hashT = HASH_OF(stream->wrapperdata);
732: }
733:
734: zend_hash_internal_pointer_reset_ex(hashT, &pos);
735: while (zend_hash_get_current_data_ex(hashT, (void**)&hdr, &pos) != FAILURE) {
736: if (!hdr || Z_TYPE_PP(hdr) != IS_STRING) {
737: zend_hash_move_forward_ex(hashT, &pos);
738: continue;
739: }
740: if (!format) {
741: no_name_header:
742: add_next_index_stringl(return_value, Z_STRVAL_PP(hdr), Z_STRLEN_PP(hdr), 1);
743: } else {
744: char c;
745: char *s, *p;
746:
747: if ((p = strchr(Z_STRVAL_PP(hdr), ':'))) {
748: c = *p;
749: *p = '\0';
750: s = p + 1;
751: while (isspace((int)*(unsigned char *)s)) {
752: s++;
753: }
754:
755: if (zend_hash_find(HASH_OF(return_value), Z_STRVAL_PP(hdr), (p - Z_STRVAL_PP(hdr) + 1), (void **) &prev_val) == FAILURE) {
756: add_assoc_stringl_ex(return_value, Z_STRVAL_PP(hdr), (p - Z_STRVAL_PP(hdr) + 1), s, (Z_STRLEN_PP(hdr) - (s - Z_STRVAL_PP(hdr))), 1);
757: } else { /* some headers may occur more then once, therefor we need to remake the string into an array */
758: convert_to_array(*prev_val);
759: add_next_index_stringl(*prev_val, s, (Z_STRLEN_PP(hdr) - (s - Z_STRVAL_PP(hdr))), 1);
760: }
761:
762: *p = c;
763: } else {
764: goto no_name_header;
765: }
766: }
767: zend_hash_move_forward_ex(hashT, &pos);
768: }
769:
770: php_stream_close(stream);
771: }
772: /* }}} */
773:
774: /*
775: * Local variables:
776: * tab-width: 4
777: * c-basic-offset: 4
778: * End:
779: * vim600: sw=4 ts=4 fdm=marker
780: * vim<600: sw=4 ts=4
781: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>