X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_url_api.c;h=827c7b6a2c5d6c1db62c459deb9af71ed7aaa011;hp=cac64ec81ee880812cb10e186169363b50252855;hb=5773d11d8c9c28fb8b0e3389258f548fc4717892;hpb=5b969e9665308562361cb01c0f63a2793f81f0ef diff --git a/http_url_api.c b/http_url_api.c index cac64ec..827c7b6 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,21 +62,28 @@ 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; } PHP_HTTP_API char *_http_absolute_url(const char *url TSRMLS_DC) { - char *abs = estrdup(url); - php_url *purl = php_url_parse(abs); + char *abs = NULL; + php_url *purl = NULL; - STR_SET(abs, NULL); + if (url) { + purl = php_url_parse(abs = estrdup(url)); + STR_SET(abs, NULL); + 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; @@ -125,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); } @@ -138,6 +157,10 @@ PHP_HTTP_API void _http_build_url(int flags, const php_url *old_url, const php_u } if (!url->scheme) { + 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: @@ -175,7 +198,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) { @@ -186,30 +209,23 @@ 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; - - 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)); - } - - php_dirname(uri, len); - spprintf(&path, 0, "%s/%s", uri, url->path); - efree(uri); - STR_SET(url->path, path); - } else { - char *uri; - - spprintf(&uri, 0, "/%s", url->path); - STR_SET(url->path, uri); + } else if (url->path[0] != '/' && 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 (SG(request_info).request_uri[ulen-1] != '/') { + for (--ulen; ulen && SG(request_info).request_uri[ulen - 1] != '/'; --ulen); } + + 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); } - 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, "/.")) { @@ -385,14 +401,14 @@ PHP_HTTP_API STATUS _http_urlencode_hash_recursive(HashTable *ht, phpstr *str, c phpstr_init(&new_prefix); if (prefix && prefix_len) { phpstr_append(&new_prefix, prefix, prefix_len); - phpstr_appends(&new_prefix, "["); + phpstr_appends(&new_prefix, "%5B"); } phpstr_append(&new_prefix, encoded_key, encoded_len); efree(encoded_key); if (prefix && prefix_len) { - phpstr_appends(&new_prefix, "]"); + phpstr_appends(&new_prefix, "%5D"); } phpstr_fix(&new_prefix); }