X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_api.c;h=af42cd5e641cb68a785d72176a967899e78abd92;hp=0e4e604f8ea3226913dd3e03cb3325ba3f18abcf;hb=074b1d2872d6ce1c7e35fe365aee9cf39ecace24;hpb=e9221ae5b72d1add77a6874595bbd0b98d0446a0 diff --git a/http_api.c b/http_api.c index 0e4e604..af42cd5 100644 --- a/http_api.c +++ b/http_api.c @@ -24,6 +24,12 @@ #include +#ifdef PHP_WIN32 +# include +#elif defined(HAVE_NETDB_H) +# include +#endif + #include "php.h" #include "php_version.h" #include "php_streams.h" @@ -886,8 +892,10 @@ PHP_HTTP_API char *_http_absolute_uri_ex( const char *host, size_t host_len, unsigned port TSRMLS_DC) { - php_url *purl, furl = {NULL}; +#if defined(PHP_WIN32) || defined(HAVE_NETDB_H) struct servent *se; +#endif + php_url *purl, furl = {NULL}; size_t full_len = 0; zval *zhost = NULL; char *scheme = NULL, *URL = ecalloc(1, HTTP_URI_MAXLEN + 1); @@ -915,8 +923,10 @@ PHP_HTTP_API char *_http_absolute_uri_ex( furl.scheme = scheme = estrdup(proto); } else if (purl->scheme) { furl.scheme = purl->scheme; - } else if (port && (se = getservbyport(htons(port), "tcp"))) { +#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"; } @@ -925,10 +935,15 @@ PHP_HTTP_API char *_http_absolute_uri_ex( furl.port = port; } else if (purl->port) { furl.port = purl->port; - } else if (strncmp(furl.scheme, "http", 4) && (se = getservbyname(furl.scheme, "tcp"))) { - furl.port = ntohs(se->s_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] ? 443 : 80; + furl.port = (furl.scheme[5] == 's') ? 443 : 80; } if (host) { @@ -973,14 +988,17 @@ PHP_HTTP_API char *_http_absolute_uri_ex( HTTP_URI_STRLCATL(URL, full_len, furl.host); - if ( (strcmp(furl.scheme, "http") && (furl.port != 80)) || - (strcmp(furl.scheme, "https") && (furl.port != 443))) { + if ( (!strcmp(furl.scheme, "http") && (furl.port != 80)) || + (!strcmp(furl.scheme, "https") && (furl.port != 443))) { char port_string[8] = {0}; snprintf(port_string, 7, ":%u", furl.port); HTTP_URI_STRLCATL(URL, full_len, port_string); } if (furl.path) { + if (furl.path[0] != '/') { + HTTP_URI_STRLCATS(URL, full_len, "/"); + } HTTP_URI_STRLCATL(URL, full_len, furl.path); } else { HTTP_URI_STRLCATS(URL, full_len, "/"); @@ -1379,7 +1397,7 @@ PHP_HTTP_API STATUS _http_send_stream_ex(php_stream *file, } /* }}} */ -/* {{{ proto STATUS http_chunked_decode(char *, size_t, char **, size_t *) */ +/* {{{ STATUS http_chunked_decode(char *, size_t, char **, size_t *) */ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, const size_t encoded_len, char **decoded, size_t *decoded_len TSRMLS_DC) { @@ -1443,33 +1461,44 @@ PHP_HTTP_API STATUS _http_chunked_decode(const char *encoded, } /* }}} */ -/* {{{ proto STATUS http_split_response_ex(char *, size_t, zval *, zval *) */ +/* {{{ STATUS http_split_response(zval *, zval *, zval *) */ +PHP_HTTP_API STATUS _http_split_response(zval *response, zval *headers, zval *body TSRMLS_DC) +{ + char *b = NULL; + size_t l = 0; + STATUS status = http_split_response_ex(Z_STRVAL_P(response), Z_STRLEN_P(response), Z_ARRVAL_P(headers), &b, &l); + ZVAL_STRINGL(body, b, l, 0); + return status; +} +/* }}} */ + +/* {{{ STATUS http_split_response(char *, size_t, HashTable *, char **, size_t *) */ PHP_HTTP_API STATUS _http_split_response_ex(char *response, size_t response_len, HashTable *headers, char **body, size_t *body_len TSRMLS_DC) { - char *header = response; - *body = NULL; + char *header = response, *real_body = NULL; while (0 < (response_len - (response - header + 4))) { if ( (*response++ == '\r') && (*response++ == '\n') && (*response++ == '\r') && (*response++ == '\n')) { - *body = response; + real_body = response; break; } } - if (*body && (*body_len = response_len - (*body - header))) { - *body = estrndup(*body, *body_len - 1); + if (real_body && (*body_len = (response_len - (real_body - header)))) { + *body = ecalloc(1, *body_len + 1); + memcpy(*body, real_body, *body_len); } - return http_parse_headers_ex(header, *body ? *body - header : response_len, headers, 1); + return http_parse_headers_ex(header, real_body ? response_len - *body_len : response_len, headers, 1); } /* }}} */ /* {{{ STATUS http_parse_headers(char *, long, zval *) */ -PHP_HTTP_API STATUS _http_parse_headers_ex(char *header, int header_len, +PHP_HTTP_API STATUS _http_parse_headers_ex(char *header, int header_len, HashTable *headers, zend_bool prettify TSRMLS_DC) { char *colon = NULL, *line = NULL, *begin = header; @@ -1549,17 +1578,17 @@ PHP_HTTP_API void _http_get_request_headers_ex(HashTable *headers, zend_bool pre char *key = NULL; long idx = 0; zval array; - + Z_ARRVAL(array) = headers; FOREACH_HASH_KEY(HTTP_SERVER_VARS, key, idx) { if (key && !strncmp(key, "HTTP_", 5)) { zval **header; - + if (prettify) { key = pretty_key(key + 5, strlen(key) - 5, 1, 1); } - + zend_hash_get_current_data(HTTP_SERVER_VARS, (void **) &header); add_assoc_stringl(&array, key, Z_STRVAL_PP(header), Z_STRLEN_PP(header), 1); key = NULL;