X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=http_url_api.c;h=60fc11ffb19e086b114a64e10f3a471a2f1cdb0e;hb=84a00407857506ab8cfb9335cbe5f495a68e0880;hp=cb1b82f89363cdc7beb89668d784a916598d87a6;hpb=001564eec4dca90f93d7c474fecd15614387b48f;p=m6w6%2Fext-http diff --git a/http_url_api.c b/http_url_api.c index cb1b82f..60fc11f 100644 --- a/http_url_api.c +++ b/http_url_api.c @@ -21,6 +21,7 @@ #include "ext/standard/php_string.h" #include "php_http_api.h" +#include "php_http_querystring_api.h" #include "php_http_url_api.h" static inline char *localhostname(void) @@ -61,6 +62,7 @@ PHP_MINIT_FUNCTION(http_url) HTTP_LONG_CONSTANT("HTTP_URL_STRIP_PATH", HTTP_URL_STRIP_PATH); HTTP_LONG_CONSTANT("HTTP_URL_STRIP_QUERY", HTTP_URL_STRIP_QUERY); HTTP_LONG_CONSTANT("HTTP_URL_STRIP_FRAGMENT", HTTP_URL_STRIP_FRAGMENT); + HTTP_LONG_CONSTANT("HTTP_URL_STRIP_ALL", HTTP_URL_STRIP_ALL); return SUCCESS; } @@ -72,15 +74,16 @@ PHP_HTTP_API char *_http_absolute_url(const char *url TSRMLS_DC) if (url) { purl = php_url_parse(abs = estrdup(url)); STR_SET(abs, NULL); - } else { - purl = ecalloc(1, sizeof(php_url)); + if (!purl) { + http_error_ex(HE_WARNING, HTTP_E_URL, "Could not parse URL (%s)", url); + return NULL; + } } + http_build_url(0, purl, NULL, NULL, &abs, NULL); + if (purl) { - http_build_url(0, purl, NULL, NULL, &abs, NULL); php_url_free(purl); - } else { - http_error_ex(HE_WARNING, HTTP_E_URL, "Could not parse URL (%s)", url); } return abs; @@ -102,10 +105,10 @@ PHP_HTTP_API void _http_build_url(int flags, const php_url *old_url, const php_u if (!(flags & HTTP_URL_STRIP_PORT)) { url->port = (new_url&&new_url->port) ? new_url->port : ((old_url) ? old_url->port : 0); } - if ((!(flags & HTTP_URL_STRIP_AUTH)) && (!(flags & HTTP_URL_STRIP_USER))) { + if (!(flags & HTTP_URL_STRIP_USER)) { __URLCPY(user); } - if ((!(flags & HTTP_URL_STRIP_AUTH)) && (!(flags & HTTP_URL_STRIP_PASS))) { + if (!(flags & HTTP_URL_STRIP_PASS)) { __URLCPY(pass); } @@ -130,10 +133,21 @@ PHP_HTTP_API void _http_build_url(int flags, const php_url *old_url, const php_u } if (!(flags & HTTP_URL_STRIP_QUERY)) { if ((flags & HTTP_URL_JOIN_QUERY) && __URLSET(new_url, query) && __URLSET(old_url, query)) { - url->query = ecalloc(1, strlen(new_url->query) + strlen(old_url->query) + 1 + 1); - strcat(url->query, old_url->query); - strcat(url->query, "&"); - strcat(url->query, new_url->query); + zval qarr, qstr; + + INIT_PZVAL(&qstr); + INIT_PZVAL(&qarr); + array_init(&qarr); + + ZVAL_STRING(&qstr, old_url->query, 0); + http_querystring_modify(&qarr, &qstr); + ZVAL_STRING(&qstr, new_url->query, 0); + http_querystring_modify(&qarr, &qstr); + + ZVAL_NULL(&qstr); + http_querystring_update(&qarr, &qstr); + url->query = Z_STRVAL(qstr); + zval_dtor(&qarr); } else { __URLCPY(query); } @@ -143,18 +157,20 @@ PHP_HTTP_API void _http_build_url(int flags, const php_url *old_url, const php_u } if (!url->scheme) { - switch (url->port) - { + zval *https = http_get_server_var("HTTPS"); + if (https && !strcasecmp(Z_STRVAL_P(https), "ON")) { + url->scheme = estrndup("https", lenof("https")); + } else switch (url->port) { case 443: url->scheme = estrndup("https", lenof("https")); - break; + break; #ifndef HTTP_HAVE_NETDB default: #endif case 80: url->scheme = estrndup("http", lenof("http")); - break; + break; #ifdef HTTP_HAVE_NETDB default: @@ -163,7 +179,7 @@ PHP_HTTP_API void _http_build_url(int flags, const php_url *old_url, const php_u } else { url->scheme = estrndup("http", lenof("http")); } - break; + break; #endif } } @@ -180,7 +196,7 @@ PHP_HTTP_API void _http_build_url(int flags, const php_url *old_url, const php_u } if (!url->path) { - if (SG(request_info).request_uri && *SG(request_info).request_uri) { + if (SG(request_info).request_uri && SG(request_info).request_uri[0]) { const char *q = strchr(SG(request_info).request_uri, '?'); if (q) { @@ -191,42 +207,43 @@ PHP_HTTP_API void _http_build_url(int flags, const php_url *old_url, const php_u } else { url->path = estrndup("/", 1); } - } else if (*url->path != '/') { - if (SG(request_info).request_uri && *SG(request_info).request_uri) { - const char *q = strchr(SG(request_info).request_uri, '?'); - char *uri, *path; - size_t len; + } else if (url->path[0] != '/') { + if (SG(request_info).request_uri && SG(request_info).request_uri[0]) { + size_t ulen = strlen(SG(request_info).request_uri); + size_t plen = strlen(url->path); + char *path; - if (q) { - uri = estrndup(SG(request_info).request_uri, len = q - SG(request_info).request_uri); - } else { - uri = estrndup(SG(request_info).request_uri, len = strlen(SG(request_info).request_uri)); + if (SG(request_info).request_uri[ulen-1] != '/') { + for (--ulen; ulen && SG(request_info).request_uri[ulen - 1] != '/'; --ulen); } - php_dirname(uri, len); - spprintf(&path, 0, "%s/%s", uri, url->path); - efree(uri); + path = emalloc(ulen + plen + 1); + memcpy(path, SG(request_info).request_uri, ulen); + memcpy(path + ulen, url->path, plen); + path[ulen + plen] = '\0'; STR_SET(url->path, path); } else { - char *uri; + size_t plen = strlen(url->path); + char *path = emalloc(plen + 1 + 1); - spprintf(&uri, 0, "/%s", url->path); - STR_SET(url->path, uri); + path[0] = '/'; + memcpy(&path[1], url->path, plen + 1); + STR_SET(url->path, path); } } - if (url->path) { + /* replace directory references if path is not a single slash */ + if (url->path[0] && (url->path[0] != '/' || url->path[1])) { char *ptr, *end = url->path + strlen(url->path) + 1; for (ptr = strstr(url->path, "/."); ptr; ptr = strstr(ptr, "/.")) { - switch (ptr[2]) - { + switch (ptr[2]) { case '\0': ptr[1] = '\0'; - break; + break; case '/': memmove(&ptr[1], &ptr[3], end - &ptr[3]); - break; + break; case '.': if (ptr[3] == '/') { @@ -238,12 +255,12 @@ PHP_HTTP_API void _http_build_url(int flags, const php_url *old_url, const php_u } memmove(&ptr[1], pos, end - pos); } - break; + break; default: /* something else */ ++ptr; - break; + break; } } } @@ -288,9 +305,6 @@ PHP_HTTP_API void _http_build_url(int flags, const php_url *old_url, const php_u strlcat(*url_str, port_str, HTTP_URL_MAXLEN); } - if (*url->path != '/') { - strlcat(*url_str, "/", HTTP_URL_MAXLEN); - } strlcat(*url_str, url->path, HTTP_URL_MAXLEN); if (url->query && *url->query) {