+
+ furl.user = purl->user;
+ furl.pass = purl->pass;
+ furl.path = purl->path;
+ furl.query = purl->query;
+ furl.fragment = purl->fragment;
+
+ if (proto) {
+ furl.scheme = scheme = estrdup(proto);
+ } else if (purl->scheme) {
+ furl.scheme = purl->scheme;
+#if defined(PHP_WIN32) || defined(HAVE_NETDB_H)
+ } else if (port && (se = getservbyport(port, "tcp"))) {
+ furl.scheme = (scheme = estrdup(se->s_name));
+#endif
+ } else {
+ furl.scheme = "http";
+ }
+
+ if (port) {
+ furl.port = port;
+ } else if (purl->port) {
+ furl.port = purl->port;
+ } else if (strncmp(furl.scheme, "http", 4)) {
+#if defined(PHP_WIN32) || defined(HAVE_NETDB_H)
+ if (se = getservbyname(furl.scheme, "tcp")) {
+ furl.port = se->s_port;
+ } else
+#endif
+ furl.port = 80;
+ } else {
+ furl.port = (furl.scheme[5] == 's') ? 443 : 80;
+ }
+
+ if (host) {
+ furl.host = (char *) host;
+ } else if (purl->host) {
+ furl.host = purl->host;
+ } else if ( (zhost = http_get_server_var("HTTP_HOST")) ||
+ (zhost = http_get_server_var("SERVER_NAME"))) {
+ furl.host = Z_STRVAL_P(zhost);
+ } else {
+ furl.host = "localhost";
+ }
+
+#define HTTP_URI_STRLCATS(URL, full_len, add_string) HTTP_URI_STRLCAT(URL, full_len, add_string, sizeof(add_string)-1)
+#define HTTP_URI_STRLCATL(URL, full_len, add_string) HTTP_URI_STRLCAT(URL, full_len, add_string, strlen(add_string))
+#define HTTP_URI_STRLCAT(URL, full_len, add_string, add_len) \
+ if ((full_len += add_len) > HTTP_URI_MAXLEN) { \
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, \
+ "Absolute URI would have exceeded max URI length (%d bytes) - " \
+ "tried to add %d bytes ('%s')", \
+ HTTP_URI_MAXLEN, add_len, add_string); \
+ if (scheme) { \
+ efree(scheme); \
+ } \
+ php_url_free(purl); \
+ return URL; \
+ } else { \
+ strcat(URL, add_string); \
+ }
+
+ HTTP_URI_STRLCATL(URL, full_len, furl.scheme);
+ HTTP_URI_STRLCATS(URL, full_len, "://");
+
+ if (furl.user) {
+ HTTP_URI_STRLCATL(URL, full_len, furl.user);
+ if (furl.pass) {
+ HTTP_URI_STRLCATS(URL, full_len, ":");
+ HTTP_URI_STRLCATL(URL, full_len, furl.pass);