Merge branch 'master' into phpng
[m6w6/ext-http] / php_http_url.c
index 93849baf077efc3eb2ae657032cf30f3cdd8ab58..6c70bc3f2566f04bdaf0b5e782a27054ff12ad66 100644 (file)
@@ -57,7 +57,7 @@ static inline char *localhostname(void)
        return estrndup("localhost", lenof("localhost"));
 }
 
-#define url(buf) ((php_http_url_t *) buf.data)
+#define url(buf) ((php_http_url_t *) (buf).data)
 
 static php_http_url_t *php_http_url_from_env(void)
 {
@@ -125,13 +125,30 @@ static php_http_url_t *php_http_url_from_env(void)
 
 #define url_isset(u,n) \
        ((u)&&(u)->n)
+#define url_append(buf, append) do { \
+       char *_ptr = (buf)->data; \
+       php_http_url_t *_url = (php_http_url_t *) _ptr, _mem = *_url; \
+       append; \
+       /* relocate */ \
+       if (_ptr != (buf)->data) { \
+               ptrdiff_t diff = (buf)->data - _ptr; \
+               _url = (php_http_url_t *) (buf)->data; \
+               if (_mem.scheme)        _url->scheme += diff; \
+               if (_mem.user)          _url->user += diff; \
+               if (_mem.pass)          _url->pass += diff; \
+               if (_mem.host)          _url->host += diff; \
+               if (_mem.path)          _url->path += diff; \
+               if (_mem.query)         _url->query += diff; \
+               if (_mem.fragment)      _url->fragment += diff; \
+       } \
+} while (0)
 #define url_copy(n) do { \
        if (url_isset(new_url, n)) { \
                url(buf)->n = &buf.data[buf.used]; \
-               php_http_buffer_append(&buf, new_url->n, strlen(new_url->n) + 1); \
+               url_append(&buf, php_http_buffer_append(&buf, new_url->n, strlen(new_url->n) + 1)); \
        } else if (url_isset(old_url, n)) { \
                url(buf)->n = &buf.data[buf.used]; \
-               php_http_buffer_append(&buf, old_url->n, strlen(old_url->n) + 1); \
+               url_append(&buf, php_http_buffer_append(&buf, old_url->n, strlen(old_url->n) + 1)); \
        } \
 } while (0)
 
@@ -182,9 +199,9 @@ php_http_url_t *php_http_url_mod(const php_http_url_t *old_url, const php_http_u
                        
                        url(buf)->path = &buf.data[buf.used];
                        if (path[0] != '/') {
-                               php_http_buffer_append(&buf, "/", 1);
+                               url_append(&buf, php_http_buffer_append(&buf, "/", 1));
                        }
-                       php_http_buffer_append(&buf, path, strlen(path) + 1);
+                       url_append(&buf, php_http_buffer_append(&buf, path, strlen(path) + 1));
                        efree(path);
                } else {
                        const char *path = NULL;
@@ -198,7 +215,7 @@ php_http_url_t *php_http_url_mod(const php_http_url_t *old_url, const php_http_u
                        if (path) {
                                url(buf)->path = &buf.data[buf.used];
 
-                               php_http_buffer_append(&buf, path, strlen(path) + 1);
+                               url_append(&buf, php_http_buffer_append(&buf, path, strlen(path) + 1));
                        }
 
 
@@ -211,16 +228,18 @@ php_http_url_t *php_http_url_mod(const php_http_url_t *old_url, const php_http_u
                        
                        array_init(&qarr);
                        
-                       ZVAL_STR(&qstr, php_http_cs2zs(old_url->query, strlen(old_url->query)));
+                       ZVAL_STRING(&qstr, old_url->query);
                        php_http_querystring_update(&qarr, &qstr, NULL);
-                       ZVAL_STR(&qstr, php_http_cs2zs(new_url->query, strlen(new_url->query)));
+                       zval_ptr_dtor(&qstr);
+                       ZVAL_STRING(&qstr, new_url->query);
                        php_http_querystring_update(&qarr, &qstr, NULL);
+                       zval_ptr_dtor(&qstr);
                        
                        ZVAL_NULL(&qstr);
                        php_http_querystring_update(&qarr, NULL, &qstr);
 
                        url(buf)->query = &buf.data[buf.used];
-                       php_http_buffer_append(&buf, Z_STRVAL(qstr), Z_STRLEN(qstr) + 1);
+                       url_append(&buf, php_http_buffer_append(&buf, Z_STRVAL(qstr), Z_STRLEN(qstr) + 1));
 
                        zval_dtor(&qstr);
                        zval_dtor(&qarr);
@@ -292,8 +311,8 @@ php_http_url_t *php_http_url_mod(const php_http_url_t *old_url, const php_http_u
        }
        /* unset default ports */
        if (url(buf)->port) {
-               if (    ((url(buf)->port == 80) && !strcmp(url(buf)->scheme, "http"))
-                       ||      ((url(buf)->port ==443) && !strcmp(url(buf)->scheme, "https"))
+               if (    ((url(buf)->port == 80) && url(buf)->scheme && !strcmp(url(buf)->scheme, "http"))
+                       ||      ((url(buf)->port ==443) && url(buf)->scheme && !strcmp(url(buf)->scheme, "https"))
                ) {
                        url(buf)->port = 0;
                }
@@ -365,6 +384,42 @@ char *php_http_url_to_string(const php_http_url_t *url, char **url_str, size_t *
        return buf.data;
 }
 
+char *php_http_url_authority_to_string(const php_http_url_t *url, char **url_str, size_t *url_len)
+{
+       php_http_buffer_t buf;
+
+       php_http_buffer_init(&buf);
+
+       if (url->user && *url->user) {
+               php_http_buffer_appendl(&buf, url->user);
+               if (url->pass && *url->pass) {
+                       php_http_buffer_appends(&buf, ":");
+                       php_http_buffer_appendl(&buf, url->pass);
+               }
+               php_http_buffer_appends(&buf, "@");
+       }
+
+       if (url->host && *url->host) {
+               php_http_buffer_appendl(&buf, url->host);
+               if (url->port) {
+                       php_http_buffer_appendf(&buf, ":%hu", url->port);
+               }
+       }
+
+       php_http_buffer_shrink(&buf);
+       php_http_buffer_fix(&buf);
+
+       if (url_len) {
+               *url_len = buf.used;
+       }
+
+       if (url_str) {
+               *url_str = buf.data;
+       }
+
+       return buf.data;
+}
+
 php_http_url_t *php_http_url_from_zval(zval *value, unsigned flags)
 {
        zend_string *zs;
@@ -394,49 +449,49 @@ php_http_url_t *php_http_url_from_struct(HashTable *ht)
        php_http_buffer_account(&buf, sizeof(php_http_url_t));
        memset(buf.data, 0, buf.used);
 
-       if ((e = zend_hash_str_find(ht, ZEND_STRL("scheme")))) {
+       if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("scheme")))) {
                zend_string *zs = zval_get_string(e);
                url(buf)->scheme = &buf.data[buf.used];
-               php_http_buffer_append(&buf, zs->val, zs->len + 1);
+               url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
                zend_string_release(zs);
        }
-       if ((e = zend_hash_str_find(ht, ZEND_STRL("user")))) {
+       if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("user")))) {
                zend_string *zs = zval_get_string(e);
                url(buf)->user = &buf.data[buf.used];
-               php_http_buffer_append(&buf, zs->val, zs->len + 1);
+               url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
                zend_string_release(zs);
        }
-       if ((e = zend_hash_str_find(ht, ZEND_STRL("pass")))) {
+       if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("pass")))) {
                zend_string *zs = zval_get_string(e);
                url(buf)->pass = &buf.data[buf.used];
-               php_http_buffer_append(&buf, zs->val, zs->len + 1);
+               url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
                zend_string_release(zs);
        }
-       if ((e = zend_hash_str_find(ht, ZEND_STRL("host")))) {
+       if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("host")))) {
                zend_string *zs = zval_get_string(e);
                url(buf)->host = &buf.data[buf.used];
-               php_http_buffer_append(&buf, zs->val, zs->len + 1);
+               url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
                zend_string_release(zs);
        }
-       if ((e = zend_hash_str_find(ht, ZEND_STRL("port")))) {
+       if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("port")))) {
                url(buf)->port = (unsigned short) zval_get_long(e);
        }
-       if ((e = zend_hash_str_find(ht, ZEND_STRL("path")))) {
+       if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("path")))) {
                zend_string *zs = zval_get_string(e);
                url(buf)->path = &buf.data[buf.used];
-               php_http_buffer_append(&buf, zs->val, zs->len + 1);
+               url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
                zend_string_release(zs);
        }
-       if ((e = zend_hash_str_find(ht, ZEND_STRL("query")))) {
+       if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("query")))) {
                zend_string *zs = zval_get_string(e);
                url(buf)->query = &buf.data[buf.used];
-               php_http_buffer_append(&buf, zs->val, zs->len + 1);
+               url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
                zend_string_release(zs);
        }
-       if ((e = zend_hash_str_find(ht, ZEND_STRL("fragment")))) {
+       if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("fragment")))) {
                zend_string *zs = zval_get_string(e);
                url(buf)->fragment = &buf.data[buf.used];
-               php_http_buffer_append(&buf, zs->val, zs->len + 1);
+               url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
                zend_string_release(zs);
        }
 
@@ -464,38 +519,46 @@ HashTable *php_http_url_to_struct(const php_http_url_t *url, zval *strct)
                zend_hash_init(ht, 8, NULL, ZVAL_PTR_DTOR, 0);
        }
 
+#define url_struct_add(part) \
+       if (Z_TYPE_P(strct) == IS_ARRAY) { \
+               zend_hash_str_update(Z_ARRVAL_P(strct), part, lenof(part), &tmp); \
+       } else { \
+               zend_update_property(Z_OBJCE_P(strct), strct, part, lenof(part), &tmp); \
+               zval_ptr_dtor(&tmp); \
+       }
+
        if (url) {
                if (url->scheme) {
                        ZVAL_STRING(&tmp, url->scheme);
-                       zend_hash_str_update(ht, "scheme", lenof("scheme"), &tmp);
+                       url_struct_add("scheme");
                }
                if (url->user) {
                        ZVAL_STRING(&tmp, url->user);
-                       zend_hash_str_update(ht, "user", lenof("user"), &tmp);
+                       url_struct_add("user");
                }
                if (url->pass) {
                        ZVAL_STRING(&tmp, url->pass);
-                       zend_hash_str_update(ht, "pass", lenof("pass"), &tmp);
+                       url_struct_add("pass");
                }
                if (url->host) {
                        ZVAL_STRING(&tmp, url->host);
-                       zend_hash_str_update(ht, "host", lenof("host"), &tmp);
+                       url_struct_add("host");
                }
                if (url->port) {
                        ZVAL_LONG(&tmp, url->port);
-                       zend_hash_str_update(ht, "port", lenof("port"), &tmp);
+                       url_struct_add("port");
                }
                if (url->path) {
                        ZVAL_STRING(&tmp, url->path);
-                       zend_hash_str_update(ht, "path", lenof("path"), &tmp);
+                       url_struct_add("path");
                }
                if (url->query) {
                        ZVAL_STRING(&tmp, url->query);
-                       zend_hash_str_update(ht, "query", lenof("query"), &tmp);
+                       url_struct_add("query");
                }
                if (url->fragment) {
                        ZVAL_STRING(&tmp, url->fragment);
-                       zend_hash_str_update(ht, "fragment", lenof("fragment"), &tmp);
+                       url_struct_add("fragment");
                }
        }
 
@@ -858,7 +921,9 @@ static ZEND_RESULT_CODE parse_hostinfo(struct parse_state *state, const char *pt
                        break;
 
                default:
-                       if (port) {
+                       if (ptr == end) {
+                               break;
+                       } else if (port) {
                                php_error_docref(NULL, E_WARNING,
                                                "Failed to parse port; unexpected byte 0x%02x at pos %u in '%s'",
                                                (unsigned char) *ptr, (unsigned) (ptr - tmp), tmp);
@@ -928,6 +993,7 @@ static const char *parse_authority(struct parse_state *state)
                case '?':
                case '#':
                case '\0':
+                       EOD:
                        /* host delimiter */
                        if (tmp != state->ptr && SUCCESS != parse_hostinfo(state, tmp)) {
                                return NULL;
@@ -936,7 +1002,8 @@ static const char *parse_authority(struct parse_state *state)
                }
        } while (++state->ptr <= state->end);
 
-       return NULL;
+       --state->ptr;
+       goto EOD;
 }
 
 static const char *parse_path(struct parse_state *state)
@@ -1233,6 +1300,33 @@ php_http_url_t *php_http_url_parse(const char *str, size_t len, unsigned flags)
        return (php_http_url_t *) state;
 }
 
+php_http_url_t *php_http_url_parse_authority(const char *str, size_t len, unsigned flags)
+{
+       size_t maxlen = 3 * len;
+       struct parse_state *state = ecalloc(1, sizeof(*state) + maxlen);
+
+       state->end = str + len;
+       state->ptr = str;
+       state->flags = flags;
+       state->maxlen = maxlen;
+       TSRMLS_SET_CTX(state->ts);
+
+       if (!(state->ptr = parse_authority(state))) {
+               efree(state);
+               return NULL;
+       }
+
+       if (state->ptr != state->end) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING,
+                               "Failed to parse URL authority, unexpected character at pos %u in '%s'",
+                               (unsigned) (state->ptr - str), str);
+               efree(state);
+               return NULL;
+       }
+
+       return (php_http_url_t *) state;
+}
+
 ZEND_BEGIN_ARG_INFO_EX(ai_HttpUrl___construct, 0, 0, 0)
        ZEND_ARG_INFO(0, old_url)
        ZEND_ARG_INFO(0, new_url)
@@ -1244,7 +1338,7 @@ PHP_METHOD(HttpUrl, __construct)
        zend_long flags = PHP_HTTP_URL_FROM_ENV;
        zend_error_handling zeh;
 
-       php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!z!l", &old_url, &new_url, &flags), invalid_arg, return);
+       php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|z!z!l", &old_url, &new_url, &flags), invalid_arg, return);
 
        zend_replace_error_handling(EH_THROW, php_http_exception_bad_url_class_entry, &zeh);
        {
@@ -1292,7 +1386,7 @@ PHP_METHOD(HttpUrl, mod)
        zend_long flags = PHP_HTTP_URL_JOIN_PATH | PHP_HTTP_URL_JOIN_QUERY;
        zend_error_handling zeh;
 
-       php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!|l", &new_url, &flags), invalid_arg, return);
+       php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "z!|l", &new_url, &flags), invalid_arg, return);
 
        zend_replace_error_handling(EH_THROW, php_http_exception_bad_url_class_entry, &zeh);
        {
@@ -1375,39 +1469,39 @@ PHP_MINIT_FUNCTION(http_url)
        zend_class_entry ce = {0};
 
        INIT_NS_CLASS_ENTRY(ce, "http", "Url", php_http_url_methods);
-       php_http_url_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
-
-       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("scheme"), ZEND_ACC_PUBLIC TSRMLS_CC);
-       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC);
-       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC);
-       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC);
-       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC);
-       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("path"), ZEND_ACC_PUBLIC TSRMLS_CC);
-       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC TSRMLS_CC);
-       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("fragment"), ZEND_ACC_PUBLIC TSRMLS_CC);
-
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("REPLACE"), PHP_HTTP_URL_REPLACE TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("JOIN_PATH"), PHP_HTTP_URL_JOIN_PATH TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("JOIN_QUERY"), PHP_HTTP_URL_JOIN_QUERY TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_USER"), PHP_HTTP_URL_STRIP_USER TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_PASS"), PHP_HTTP_URL_STRIP_PASS TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_AUTH"), PHP_HTTP_URL_STRIP_AUTH TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_PORT"), PHP_HTTP_URL_STRIP_PORT TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_PATH"), PHP_HTTP_URL_STRIP_PATH TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_QUERY"), PHP_HTTP_URL_STRIP_QUERY TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_FRAGMENT"), PHP_HTTP_URL_STRIP_FRAGMENT TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_ALL"), PHP_HTTP_URL_STRIP_ALL TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("FROM_ENV"), PHP_HTTP_URL_FROM_ENV TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("SANITIZE_PATH"), PHP_HTTP_URL_SANITIZE_PATH TSRMLS_CC);
+       php_http_url_class_entry = zend_register_internal_class(&ce);
+
+       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("scheme"), ZEND_ACC_PUBLIC);
+       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("user"), ZEND_ACC_PUBLIC);
+       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("pass"), ZEND_ACC_PUBLIC);
+       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("host"), ZEND_ACC_PUBLIC);
+       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("port"), ZEND_ACC_PUBLIC);
+       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("path"), ZEND_ACC_PUBLIC);
+       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC);
+       zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("fragment"), ZEND_ACC_PUBLIC);
+
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("REPLACE"), PHP_HTTP_URL_REPLACE);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("JOIN_PATH"), PHP_HTTP_URL_JOIN_PATH);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("JOIN_QUERY"), PHP_HTTP_URL_JOIN_QUERY);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_USER"), PHP_HTTP_URL_STRIP_USER);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_PASS"), PHP_HTTP_URL_STRIP_PASS);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_AUTH"), PHP_HTTP_URL_STRIP_AUTH);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_PORT"), PHP_HTTP_URL_STRIP_PORT);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_PATH"), PHP_HTTP_URL_STRIP_PATH);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_QUERY"), PHP_HTTP_URL_STRIP_QUERY);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_FRAGMENT"), PHP_HTTP_URL_STRIP_FRAGMENT);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_ALL"), PHP_HTTP_URL_STRIP_ALL);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("FROM_ENV"), PHP_HTTP_URL_FROM_ENV);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("SANITIZE_PATH"), PHP_HTTP_URL_SANITIZE_PATH);
 
 #ifdef PHP_HTTP_HAVE_WCHAR
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_MBLOC"), PHP_HTTP_URL_PARSE_MBLOC TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_MBLOC"), PHP_HTTP_URL_PARSE_MBLOC);
 #endif
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_MBUTF8"), PHP_HTTP_URL_PARSE_MBUTF8 TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_MBUTF8"), PHP_HTTP_URL_PARSE_MBUTF8);
 #ifdef PHP_HTTP_HAVE_IDN
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_TOIDN"), PHP_HTTP_URL_PARSE_TOIDN TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_TOIDN"), PHP_HTTP_URL_PARSE_TOIDN);
 #endif
-       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_TOPCT"), PHP_HTTP_URL_PARSE_TOPCT TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_TOPCT"), PHP_HTTP_URL_PARSE_TOPCT);
 
        return SUCCESS;
 }