+ zval *https, *zhost, *zport;
+ long port;
+#ifdef HAVE_GETSERVBYPORT
+ struct servent *se;
+#endif
+
+ if (!url) {
+ url = ecalloc(1, sizeof(*url));
+ }
+
+ /* port */
+ zport = php_http_env_get_server_var(ZEND_STRL("SERVER_PORT"), 1 TSRMLS_CC);
+ if (zport && IS_LONG == is_numeric_string(Z_STRVAL_P(zport), Z_STRLEN_P(zport), &port, NULL, 0)) {
+ url->port = port;
+ }
+
+ /* scheme */
+ https = php_http_env_get_server_var(ZEND_STRL("HTTPS"), 1 TSRMLS_CC);
+ 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;
+
+#ifndef HAVE_GETSERVBYPORT
+ default:
+#endif
+ case 80:
+ case 0:
+ url->scheme = estrndup("http", lenof("http"));
+ break;
+
+#ifdef HAVE_GETSERVBYPORT
+ default:
+ if ((se = getservbyport(htons(url->port), "tcp")) && se->s_name) {
+ url->scheme = estrdup(se->s_name);
+ } else {
+ url->scheme = estrndup("http", lenof("http"));
+ }
+ break;
+#endif
+ }
+
+ /* host */
+ if ((((zhost = php_http_env_get_server_var(ZEND_STRL("HTTP_HOST"), 1 TSRMLS_CC)) ||
+ (zhost = php_http_env_get_server_var(ZEND_STRL("SERVER_NAME"), 1 TSRMLS_CC)) ||
+ (zhost = php_http_env_get_server_var(ZEND_STRL("SERVER_ADDR"), 1 TSRMLS_CC)))) && Z_STRLEN_P(zhost)) {
+ url->host = estrndup(Z_STRVAL_P(zhost), Z_STRLEN_P(zhost));
+ } else {
+ url->host = localhostname();
+ }
+
+ /* path */
+ if (SG(request_info).request_uri && SG(request_info).request_uri[0]) {
+ const char *q = strchr(SG(request_info).request_uri, '?');
+
+ if (q) {
+ url->path = estrndup(SG(request_info).request_uri, q - SG(request_info).request_uri);
+ } else {
+ url->path = estrdup(SG(request_info).request_uri);