summaryrefslogtreecommitdiff
path: root/ext/standard
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard')
-rw-r--r--ext/standard/Makefile.frag1
-rw-r--r--ext/standard/basic_functions.c2
-rw-r--r--ext/standard/file.c159
-rw-r--r--ext/standard/file.h2
-rw-r--r--ext/standard/ftp_fopen_wrapper.c76
-rw-r--r--ext/standard/http_fopen_wrapper.c57
-rw-r--r--ext/standard/php_fopen_wrapper.c2
-rw-r--r--ext/standard/php_fopen_wrappers.h4
8 files changed, 243 insertions, 60 deletions
diff --git a/ext/standard/Makefile.frag b/ext/standard/Makefile.frag
index 934f501e6c..d48cf2fd18 100644
--- a/ext/standard/Makefile.frag
+++ b/ext/standard/Makefile.frag
@@ -6,3 +6,4 @@ $(srcdir)/var_unserializer.c: $(srcdir)/var_unserializer.re
$(srcdir)/url_scanner_ex.c: $(srcdir)/url_scanner_ex.re
re2c -b $(srcdir)/url_scanner_ex.re > $@
+
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 28b2357c93..3a10750302 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -595,6 +595,8 @@ function_entry basic_functions[] = {
PHP_STATIC_FE("tmpfile", php_if_tmpfile, NULL)
PHP_FE(file, NULL)
PHP_FE(file_get_contents, NULL)
+ PHP_FE(file_context_create, NULL)
+ PHP_FE(file_context_set_params, NULL)
PHP_FE(fgetcsv, NULL)
PHP_FE(flock, NULL)
PHP_FE(get_meta_tags, NULL)
diff --git a/ext/standard/file.c b/ext/standard/file.c
index 616dba829e..f5f33e61c8 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -109,10 +109,16 @@ php_file_globals file_globals;
/* sharing globals is *evil* */
static int le_stream = FAILURE;
+static int le_stream_context = FAILURE;
/* }}} */
/* {{{ Module-Stuff */
+static ZEND_RSRC_DTOR_FUNC(file_context_dtor)
+{
+ php_stream_context_free((php_stream_context*)rsrc->ptr);
+}
+
static void _file_stream_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
php_stream *stream = (php_stream*)rsrc->ptr;
@@ -142,6 +148,7 @@ static void file_globals_dtor(php_file_globals *file_globals_p TSRMLS_DC)
PHP_MINIT_FUNCTION(file)
{
le_stream = zend_register_list_destructors_ex(_file_stream_dtor, NULL, "stream", module_number);
+ le_stream_context = zend_register_list_destructors_ex(file_context_dtor, NULL, "stream-context", module_number);
#ifdef ZTS
ts_allocate_id(&file_globals_id, sizeof(php_file_globals), (ts_allocate_ctor) file_globals_ctor, (ts_allocate_dtor) file_globals_dtor);
@@ -157,6 +164,19 @@ PHP_MINIT_FUNCTION(file)
REGISTER_LONG_CONSTANT("LOCK_UN", 3, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("LOCK_NB", 4, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_NOTIFY_CONNECT", PHP_STREAM_NOTIFY_CONNECT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_NOTIFY_AUTH_REQUIRED", PHP_STREAM_NOTIFY_AUTH_REQUIRED, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_NOTIFY_AUTH_RESULT", PHP_STREAM_NOTIFY_AUTH_RESULT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_NOTIFY_MIME_TYPE_IS", PHP_STREAM_NOTIFY_MIME_TYPE_IS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_NOTIFY_FILE_SIZE_IS", PHP_STREAM_NOTIFY_FILE_SIZE_IS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_NOTIFY_REDIRECTED", PHP_STREAM_NOTIFY_REDIRECTED, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_NOTIFY_PROGRESS", PHP_STREAM_NOTIFY_PROGRESS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_NOTIFY_FAILURE", PHP_STREAM_NOTIFY_FAILURE, CONST_CS | CONST_PERSISTENT);
+
+ REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_INFO", PHP_STREAM_NOTIFY_SEVERITY_INFO, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_WARN", PHP_STREAM_NOTIFY_SEVERITY_WARN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("STREAM_NOTIFY_SEVERITY_ERR", PHP_STREAM_NOTIFY_SEVERITY_ERR, CONST_CS | CONST_PERSISTENT);
+
return SUCCESS;
}
@@ -562,36 +582,126 @@ PHP_FUNCTION(file_get_wrapper_data)
}
/* }}} */
-/* {{{ proto resource fopen(string filename, string mode [, bool use_include_path])
- Open a file or a URL and return a file pointer */
-PHP_NAMED_FUNCTION(php_if_fopen)
+/* {{{ file_context related functions */
+static void user_space_stream_notifier(php_stream_context *context, int notifycode, int severity,
+ char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr TSRMLS_DC)
{
- zval **arg1, **arg2, **arg3;
- int use_include_path = 0;
- php_stream *stream;
+ zval *callback = (zval*)context->notifier->ptr;
+ zval *retval = NULL;
+ zval zcode, zseverity, zmsg, zxcode, zsofar, zmax;
+ zval *ptrs[6] = {&zcode, &zseverity, &zmsg, &zxcode, &zsofar, &zmax};
+ zval **args[6] = {&ptrs[0], &ptrs[1], &ptrs[2], &ptrs[3], &ptrs[4], &ptrs[5]};
- switch(ZEND_NUM_ARGS()) {
- case 2:
- if (zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
- WRONG_PARAM_COUNT;
- }
- break;
- case 3:
- if (zend_get_parameters_ex(3, &arg1, &arg2, &arg3) == FAILURE) {
- WRONG_PARAM_COUNT;
+ INIT_ZVAL(zcode);
+ INIT_ZVAL(zseverity);
+ INIT_ZVAL(zmsg);
+ INIT_ZVAL(zxcode);
+ INIT_ZVAL(zsofar);
+ INIT_ZVAL(zmax);
+
+ ZVAL_LONG(&zcode, notifycode);
+ ZVAL_LONG(&zseverity, severity);
+ ZVAL_LONG(&zxcode, xcode);
+ ZVAL_LONG(&zsofar, bytes_sofar);
+ ZVAL_LONG(&zmax, bytes_max);
+
+ if (xmsg) {
+ ZVAL_STRING(&zmsg, xmsg, 0);
+ } else {
+ ZVAL_NULL(&zmsg);
+ }
+
+ if (FAILURE == call_user_function_ex(EG(function_table), NULL, callback, &retval, 6, args, 0, NULL TSRMLS_CC)) {
+ zend_error(E_WARNING, "failed to call user notifier");
+ }
+ if (retval)
+ zval_ptr_dtor(&retval);
+}
+
+static int parse_context_options(php_stream_context *context, zval *params)
+{
+ int ret = SUCCESS;
+ zval **tmp;
+
+ if (SUCCESS == zend_hash_find(Z_ARRVAL_P(params), "notification", sizeof("notification"), (void**)&tmp)) {
+
+ if (context->notifier) {
+ php_stream_notification_free(context->notifier);
+ context->notifier = NULL;
}
- convert_to_long_ex(arg3);
- use_include_path = Z_LVAL_PP(arg3);
- break;
- default:
- WRONG_PARAM_COUNT;
+
+ context->notifier = php_stream_notification_alloc();
+ context->notifier->func = user_space_stream_notifier;
+ context->notifier->ptr = *tmp;
+ ZVAL_ADDREF(*tmp);
}
- convert_to_string_ex(arg1);
- convert_to_string_ex(arg2);
+
+ return ret;
+}
+/* }}} */
+
+/* {{{ proto bool file_context_set_params(resource context, array options)
+ Set parameters for a file context */
+PHP_FUNCTION(file_context_set_params)
+{
+ zval *params, *zcontext;
+ php_stream_context *context;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &zcontext, &params) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ context = (php_stream_context*)zend_fetch_resource(&zcontext TSRMLS_CC, -1, "Stream-Context", NULL, 1, le_stream_context);
+ ZEND_VERIFY_RESOURCE(context);
+
+ RETVAL_BOOL(parse_context_options(context, params) == SUCCESS);
+}
+/* }}} */
+
+/* {{{ proto resource file_context_create([array options])
+ Create a file context and optionally set parameters */
+PHP_FUNCTION(file_context_create)
+{
+ zval *params = NULL;
+ php_stream_context *context;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &params) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ context = php_stream_context_alloc();
+
+ if (params)
+ parse_context_options(context, params);
+
+ ZEND_REGISTER_RESOURCE(return_value, context, le_stream_context);
+}
+/* }}} */
- stream = php_stream_open_wrapper(Z_STRVAL_PP(arg1), Z_STRVAL_PP(arg2),
+/* {{{ proto resource fopen(string filename, string mode [, bool use_include_path [, resource context]])
+ Open a file or a URL and return a file pointer */
+PHP_NAMED_FUNCTION(php_if_fopen)
+{
+ char *filename, *mode;
+ int filename_len, mode_len;
+ zend_bool use_include_path = 0;
+ zval *zcontext = NULL;
+ php_stream *stream;
+ php_stream_context *context = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|br", &filename, &filename_len,
+ &mode, &mode_len, &use_include_path, &zcontext) == FAILURE) {
+ RETURN_FALSE;
+ }
+ if (zcontext) {
+ context = (php_stream_context*)zend_fetch_resource(&zcontext TSRMLS_CC, -1, "Stream-Context", NULL, 1, le_stream_context);
+ ZEND_VERIFY_RESOURCE(context);
+ }
+
+ stream = php_stream_open_wrapper_ex(filename, mode,
use_include_path | ENFORCE_SAFE_MODE | REPORT_ERRORS,
- NULL);
+ NULL, context);
+
if (stream == NULL) {
RETURN_FALSE;
}
@@ -622,6 +732,7 @@ PHPAPI PHP_FUNCTION(fclose)
}
/* }}} */
+
/* {{{ proto resource popen(string command, string mode)
Execute a command and open either a read or a write pipe to it */
diff --git a/ext/standard/file.h b/ext/standard/file.h
index 6d08e31ad9..3261aaba08 100644
--- a/ext/standard/file.h
+++ b/ext/standard/file.h
@@ -73,6 +73,8 @@ PHP_NAMED_FUNCTION(php_if_fstat);
PHP_FUNCTION(file_get_wrapper_data);
PHP_FUNCTION(file_register_wrapper);
+PHP_FUNCTION(file_context_create);
+PHP_FUNCTION(file_context_set_params);
PHP_MINIT_FUNCTION(user_streams);
PHPAPI int php_set_sock_blocking(int socketd, int block);
diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c
index e7f6eef638..2f3db50593 100644
--- a/ext/standard/ftp_fopen_wrapper.c
+++ b/ext/standard/ftp_fopen_wrapper.c
@@ -66,16 +66,16 @@
#include "php_fopen_wrappers.h"
-static int php_get_ftp_result(php_stream *stream TSRMLS_DC)
-{
- char tmp_line[513];
- while (php_stream_gets(stream, tmp_line, sizeof(tmp_line)-1) &&
- !(isdigit((int) tmp_line[0]) && isdigit((int) tmp_line[1]) &&
- isdigit((int) tmp_line[2]) && tmp_line[3] == ' '));
+static inline int get_ftp_result(php_stream *stream, char *buffer, size_t buffer_size TSRMLS_DC)
+{
+ while (php_stream_gets(stream, buffer, buffer_size-1) &&
+ !(isdigit((int) buffer[0]) && isdigit((int) buffer[1]) &&
+ isdigit((int) buffer[2]) && buffer[3] == ' '));
- return strtol(tmp_line, NULL, 10);
+ return strtol(buffer, NULL, 10);
}
+#define GET_FTP_RESULT(stream) get_ftp_result((stream), tmp_line, sizeof(tmp_line) TSRMLS_CC)
static int php_stream_ftp_stream_stat(php_stream_wrapper *wrapper,
php_stream *stream,
@@ -103,7 +103,7 @@ php_stream_wrapper php_stream_ftp_wrapper = {
/* {{{ php_fopen_url_wrap_ftp
*/
-php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC)
+php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
{
php_stream *stream=NULL;
php_url *resource=NULL;
@@ -113,6 +113,7 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
int result;
int i;
char *tpath, *ttpath;
+ size_t file_size = 0;
resource = php_url_parse((char *) path);
if (resource == NULL || resource->path == NULL)
@@ -126,10 +127,15 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
if (stream == NULL)
goto errexit;
+ php_stream_context_set(stream, context);
+ php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0);
+
/* Start talking to ftp server */
- result = php_get_ftp_result(stream TSRMLS_CC);
- if (result > 299 || result < 200)
+ result = GET_FTP_RESULT(stream);
+ if (result > 299 || result < 200) {
+ php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE, tmp_line, result);
goto errexit;
+ }
/* send the user name */
php_stream_write_string(stream, "USER ");
@@ -142,10 +148,12 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
php_stream_write_string(stream, "\r\n");
/* get the response */
- result = php_get_ftp_result(stream TSRMLS_CC);
+ result = GET_FTP_RESULT(stream);
/* if a password is required, send it */
if (result >= 300 && result <= 399) {
+ php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, tmp_line, 0);
+
php_stream_write_string(stream, "PASS ");
if (resource->pass != NULL) {
php_raw_url_decode(resource->pass, strlen(resource->pass));
@@ -162,14 +170,20 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
php_stream_write_string(stream, "\r\n");
/* read the response */
- result = php_get_ftp_result(stream TSRMLS_CC);
+ result = GET_FTP_RESULT(stream);
+
+ if (result > 299 || result < 200) {
+ php_stream_notify_error(context, PHP_STREAM_NOTIFY_AUTH_RESULT, tmp_line, result);
+ } else {
+ php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_RESULT, tmp_line, result);
+ }
}
if (result > 299 || result < 200)
goto errexit;
/* set the connection to be binary */
php_stream_write_string(stream, "TYPE I\r\n");
- result = php_get_ftp_result(stream TSRMLS_CC);
+ result = GET_FTP_RESULT(stream);
if (result > 299 || result < 200)
goto errexit;
@@ -179,13 +193,22 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
php_stream_write_string(stream, "\r\n");
/* read the response */
- result = php_get_ftp_result(stream TSRMLS_CC);
+ result = GET_FTP_RESULT(stream);
if (mode[0] == 'r') {
+ char *sizestr;
+
/* when reading file, it must exist */
if (result > 299 || result < 200) {
errno = ENOENT;
goto errexit;
}
+
+ sizestr = strchr(tmp_line, ' ');
+ if (sizestr) {
+ sizestr++;
+ file_size = atoi(sizestr);
+ php_stream_notify_file_size(context, file_size, tmp_line, result);
+ }
} else {
/* when writing file, it must NOT exist */
if (result <= 299 && result >= 200) {
@@ -193,25 +216,23 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
goto errexit;
}
}
-
+
/* set up the passive connection */
/* We try EPSV first, needed for IPv6 and works on some IPv4 servers */
php_stream_write_string(stream, "EPSV\r\n");
- while (php_stream_gets(stream, tmp_line, sizeof(tmp_line)-1) &&
- !(isdigit((int) tmp_line[0]) && isdigit((int) tmp_line[1]) &&
- isdigit((int) tmp_line[2]) && tmp_line[3] == ' '));
+ result = GET_FTP_RESULT(stream);
/* check if we got a 229 response */
- if (strncmp(tmp_line, "229", 3)) {
+ if (result != 229) {
/* EPSV failed, let's try PASV */
php_stream_write_string(stream, "PASV\r\n");
- while (php_stream_gets(stream, tmp_line, sizeof(tmp_line)-1) &&
- !(isdigit((int) tmp_line[0]) && isdigit((int) tmp_line[1]) &&
- isdigit((int) tmp_line[2]) && tmp_line[3] == ' '));
+ result = GET_FTP_RESULT(stream);
+
/* make sure we got a 227 response */
- if (strncmp(tmp_line, "227", 3))
+ if (result != 227)
goto errexit;
+
/* parse pasv command (129, 80, 95, 25, 13, 221) */
tpath = tmp_line;
/* skip over the "227 Some message " part */
@@ -279,13 +300,20 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
if (stream == NULL)
goto errexit;
+ php_stream_context_set(stream, context);
+ php_stream_notify_progress_init(context, 0, file_size);
+
php_url_free(resource);
return stream;
errexit:
php_url_free(resource);
- if (stream)
+ if (stream) {
+ php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE, tmp_line, result);
php_stream_close(stream);
+ }
+ if (tmp_line[0] != '\0')
+ zend_error(E_WARNING, "FTP server reports %s", tmp_line);
return NULL;
}
/* }}} */
diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c
index c96f43ddff..994e60d719 100644
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -70,7 +70,7 @@
#define HTTP_HEADER_BLOCK_SIZE 1024
-php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC)
+php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
{
php_stream *stream = NULL;
php_url *resource = NULL;
@@ -84,6 +84,8 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
int reqok = 0;
char *http_header_line = NULL;
char tmp_line[128];
+ size_t chunk_size, file_size = 0;
+ int redirected = 0;
resource = php_url_parse(path);
if (resource == NULL)
@@ -101,6 +103,13 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
if (stream == NULL)
goto out;
+ /* avoid buffering issues while reading header */
+ chunk_size = php_stream_sock_set_chunk_size(stream, 1 TSRMLS_CC);
+
+ php_stream_context_set(stream, context);
+
+ php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0);
+
#if HAVE_OPENSSL_EXT
if (use_ssl) {
if (php_stream_sock_ssl_activate(stream, 1) == FAILURE) {
@@ -146,8 +155,10 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
tmp = php_base64_encode((unsigned char*)scratch, strlen(scratch), NULL);
- if (snprintf(scratch, scratch_len, "Authorization: Basic %s\r\n", tmp) > 0)
+ if (snprintf(scratch, scratch_len, "Authorization: Basic %s\r\n", tmp) > 0) {
php_stream_write(stream, scratch, strlen(scratch));
+ php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, NULL, 0);
+ }
efree(tmp);
tmp = NULL;
@@ -179,10 +190,22 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
if (php_stream_gets(stream, tmp_line, sizeof(tmp_line)-1) != NULL) {
zval *http_response;
+ int response_code;
MAKE_STD_ZVAL(http_response);
- if (strncmp(tmp_line + 8, " 200 ", 5) == 0)
+ response_code = atoi(tmp_line + 9);
+ if (response_code == 200) {
reqok = 1;
+ } else {
+ switch(response_code) {
+ case 403:
+ php_stream_notify_error(context, PHP_STREAM_NOTIFY_AUTH_RESULT, tmp_line, response_code);
+ break;
+ default:
+ php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE, tmp_line, response_code);
+ }
+ }
+
Z_STRLEN_P(http_response) = strlen(tmp_line);
Z_STRVAL_P(http_response) = estrndup(tmp_line, Z_STRLEN_P(http_response));
if (Z_STRVAL_P(http_response)[Z_STRLEN_P(http_response)-1]=='\n') {
@@ -223,8 +246,15 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
}
http_header_line_length = p-http_header_line+1;
- if (!strncasecmp(http_header_line, "Location: ", 10))
+ if (!strncasecmp(http_header_line, "Location: ", 10)) {
strlcpy(location, http_header_line + 10, sizeof(location));
+ } else if (!strncasecmp(http_header_line, "Content-Type: ", 14)) {
+ php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_line + 14, 0);
+ } else if (!strncasecmp(http_header_line, "Content-Length: ", 16)) {
+ file_size = atoi(http_header_line + 16);
+ php_stream_notify_file_size(context, file_size, http_header_line, 0);
+ }
+
if (http_header_line[0] == '\0')
body = 1;
@@ -243,6 +273,10 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
}
if (!reqok) {
+
+ if (location[0] != '\0')
+ php_stream_notify_info(context, PHP_STREAM_NOTIFY_REDIRECTED, location, 0);
+
php_stream_close(stream);
stream = NULL;
@@ -267,8 +301,9 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
else {
strlcpy(new_path, location, sizeof(new_path));
}
- stream = php_stream_url_wrap_http(NULL, new_path, mode, options, opened_path STREAMS_CC TSRMLS_CC);
- if (stream->wrapperdata) {
+ redirected = 1;
+ stream = php_stream_url_wrap_http(NULL, new_path, mode, options, opened_path, context STREAMS_CC TSRMLS_CC);
+ if (stream && stream->wrapperdata) {
entryp = &entry;
MAKE_STD_ZVAL(entry);
ZVAL_EMPTY_STRING(entry);
@@ -282,9 +317,10 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
zval_dtor(stream->wrapperdata);
FREE_ZVAL(stream->wrapperdata);
}
+ } else {
+ if (options & REPORT_ERRORS)
+ zend_error(E_WARNING, "HTTP request failed! %s", tmp_line);
}
- else if (options & REPORT_ERRORS)
- zend_error(E_WARNING, "HTTP request failed! %s", tmp_line);
}
out:
if (http_header_line)
@@ -293,8 +329,11 @@ out:
efree(scratch);
php_url_free(resource);
- if (stream)
+ if (stream) {
stream->wrapperdata = response_header;
+ php_stream_notify_progress_init(context, 0, file_size);
+ php_stream_sock_set_chunk_size(stream, chunk_size TSRMLS_CC);
+ }
if (response_header) {
zval *sym;
diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c
index e7f07a9e9b..fcca4fce2d 100644
--- a/ext/standard/php_fopen_wrapper.c
+++ b/ext/standard/php_fopen_wrapper.c
@@ -30,7 +30,7 @@
#include "php_standard.h"
#include "php_fopen_wrappers.h"
-php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC)
+php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_wrapper_options *exoptions STREAMS_DC TSRMLS_DC)
{
FILE * fp = NULL;
php_stream * stream = NULL;
diff --git a/ext/standard/php_fopen_wrappers.h b/ext/standard/php_fopen_wrappers.h
index 7c82937d05..392b88d063 100644
--- a/ext/standard/php_fopen_wrappers.h
+++ b/ext/standard/php_fopen_wrappers.h
@@ -23,8 +23,8 @@
#ifndef PHP_FOPEN_WRAPPERS_H
#define PHP_FOPEN_WRAPPERS_H
-php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC);
-php_stream *php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC);
+php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
+php_stream *php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
php_stream_wrapper php_stream_http_wrapper;
php_stream_wrapper php_stream_ftp_wrapper;
php_stream_wrapper php_stream_php_wrapper;