From: Sara Golemon Date: Mon, 7 Apr 2003 21:02:04 +0000 (+0000) Subject: Introduce support for context options 'method', 'header', 'content' X-Git-Tag: RELEASE_0_5~106 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=70155b6dcfad63226ea598a1e95b2ba6106e49d8;p=php Introduce support for context options 'method', 'header', 'content' --- diff --git a/NEWS b/NEWS index 706241f00a..7c5334a47b 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ? ? ??? 200?, Version 5.0.0 +- Added context options to http_fopen_wrapper 'method', 'header', 'content'. (Sara) - Fixed bug #23009 (pg_select with timestamp). (Marcus, Jay) - Moved extensions to PECL (http://pear.php.net/): (James, Tal) . ext/fribidi diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index c6e04c1dfd..3a395a5054 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -81,7 +81,10 @@ #define HTTP_HEADER_BLOCK_SIZE 1024 #define PHP_URL_REDIRECT_MAX 20 - +#define HTTP_HEADER_USER_AGENT 1 +#define HTTP_HEADER_HOST 2 +#define HTTP_HEADER_AUTH 4 +#define HTTP_HEADER_FROM 8 php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context, int redirect_max STREAMS_DC TSRMLS_DC) { @@ -91,7 +94,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, char *scratch = NULL; char *tmp = NULL; char *ua_str = NULL; - zval **ua_zval = NULL; + zval **ua_zval = NULL, **tmpzval = NULL; int scratch_len = 0; int body = 0; char location[HTTP_HEADER_BLOCK_SIZE]; @@ -102,7 +105,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, size_t chunk_size = 0, file_size = 0; int eol_detect; char *transport_string, *errstr = NULL; - int transport_len; + int transport_len, have_header = 0; if (redirect_max < 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Circular redirect, aborting."); @@ -164,14 +167,21 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, scratch_len = strlen(path) + 32; scratch = emalloc(scratch_len); - strcpy(scratch, "GET "); + if (context && + php_stream_context_get_option(context, "http", "method", &tmpzval) == SUCCESS && + Z_STRLEN_PP(tmpzval) > 0 && + strncasecmp(Z_STRVAL_PP(tmpzval), "POST", Z_STRLEN_PP(tmpzval)) == 0) { + strcpy(scratch, "POST "); + } else { + strcpy(scratch, "GET "); + } /* file */ if (resource->path && *resource->path) strlcat(scratch, resource->path, scratch_len); else strlcat(scratch, "/", scratch_len); - + /* query string */ if (resource->query) { strlcat(scratch, "?", scratch_len); @@ -184,8 +194,37 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, /* send it */ php_stream_write(stream, scratch, strlen(scratch)); + if (context && + php_stream_context_get_option(context, "http", "header", &tmpzval) == SUCCESS && + Z_STRLEN_PP(tmpzval)) { + /* Remove newlines and spaces from start and end, + php_trim will estrndup() */ + tmp = php_trim(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval), NULL, 0, NULL, 3 TSRMLS_CC); + if (strlen(tmp) > 0) { + /* Output trimmed headers with \r\n at the end */ + php_stream_write(stream, tmp, strlen(tmp)); + php_stream_write(stream, "\r\n", sizeof("\r\n") - 1); + + /* Make lowercase for easy comparison against 'standard' headers */ + php_strtolower(tmp, strlen(tmp)); + if (strstr(tmp, "user-agent:")) { + have_header |= HTTP_HEADER_USER_AGENT; + } + if (strstr(tmp, "host:")) { + have_header |= HTTP_HEADER_HOST; + } + if (strstr(tmp, "from:")) { + have_header |= HTTP_HEADER_FROM; + } + if (strstr(tmp, "authorization:")) { + have_header |= HTTP_HEADER_AUTH; + } + } + efree(tmp); + } + /* auth header if it was specified */ - if (resource->user && resource->pass) { + if (((have_header & HTTP_HEADER_AUTH) == 0) && resource->user && resource->pass) { /* decode the strings first */ php_url_decode(resource->user, strlen(resource->user)); php_url_decode(resource->pass, strlen(resource->pass)); @@ -207,18 +246,22 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, } /* if the user has configured who they are, send a From: line */ - if (cfg_get_string("from", &tmp) == SUCCESS) { + if (((have_header & HTTP_HEADER_FROM) == 0) && cfg_get_string("from", &tmp) == SUCCESS) { if (snprintf(scratch, scratch_len, "From: %s\r\n", tmp) > 0) php_stream_write(stream, scratch, strlen(scratch)); } /* Send Host: header so name-based virtual hosts work */ - if ((use_ssl && resource->port != 443) || (!use_ssl && resource->port != 80)) { - if (snprintf(scratch, scratch_len, "Host: %s:%i\r\n", resource->host, resource->port) > 0) - php_stream_write(stream, scratch, strlen(scratch)); + if ((have_header & HTTP_HEADER_HOST) == 0) { + if ((use_ssl && resource->port != 443) || (!use_ssl && resource->port != 80)) { + if (snprintf(scratch, scratch_len, "Host: %s:%i\r\n", resource->host, resource->port) > 0) + php_stream_write(stream, scratch, strlen(scratch)); + } else { + if (snprintf(scratch, scratch_len, "Host: %s\r\n", resource->host) > 0) { + php_stream_write(stream, scratch, strlen(scratch)); + } + } } - else if (snprintf(scratch, scratch_len, "Host: %s\r\n", resource->host) > 0) - php_stream_write(stream, scratch, strlen(scratch)); if (context && php_stream_context_get_option(context, "http", "user_agent", &ua_zval) == SUCCESS) { @@ -227,7 +270,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, ua_str = FG(user_agent); } - if (ua_str) { + if (((have_header & HTTP_HEADER_USER_AGENT) == 0) && ua_str) { #define _UA_HEADER "User-Agent: %s\r\n" char *ua; size_t ua_len; @@ -252,6 +295,14 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, php_stream_write(stream, "\r\n", sizeof("\r\n")-1); + /* Request content, such as for POST requests */ + if (context && + php_stream_context_get_option(context, "http", "content", &tmpzval) == SUCCESS && + Z_STRLEN_PP(tmpzval) > 0) { + php_stream_write(stream, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval)); + php_stream_write(stream, "\r\n\r\n", sizeof("\r\n\r\n")-1); + } + location[0] = '\0'; MAKE_STD_ZVAL(response_header);