summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.STREAMS4
-rw-r--r--ext/standard/ftp_fopen_wrapper.c7
-rw-r--r--ext/standard/http_fopen_wrapper.c14
-rwxr-xr-xmain/php_streams.h7
-rwxr-xr-xmain/streams.c79
5 files changed, 97 insertions, 14 deletions
diff --git a/README.STREAMS b/README.STREAMS
index 870888a6bc..91a9245c0a 100644
--- a/README.STREAMS
+++ b/README.STREAMS
@@ -2,6 +2,10 @@ An Overview of the PHP Streams abstraction
==========================================
$Id$
+WARNING: some prototypes in this file are out of date.
+The information contained here is being integrated into
+the php manual - stay tuned...
+
Please send comments to: Wez Furlong <wez@thebrainroom.com>
Why Streams?
diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c
index 9bbdbedee4..b5d3ccdc16 100644
--- a/ext/standard/ftp_fopen_wrapper.c
+++ b/ext/standard/ftp_fopen_wrapper.c
@@ -115,6 +115,11 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
int i;
char *tpath, *ttpath;
size_t file_size = 0;
+
+ if (strchr(mode, 'a') || strchr(mode, '+')) {
+ php_stream_wrapper_log_error(wrapper, options, "FTP does not support simultaneous read/write connections.");
+ return NULL;
+ }
resource = php_url_parse((char *) path);
if (resource == NULL || resource->path == NULL)
@@ -314,7 +319,7 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
php_stream_close(stream);
}
if (tmp_line[0] != '\0')
- zend_error(E_WARNING, "FTP server reports %s", tmp_line);
+ php_stream_wrapper_log_error(wrapper, options, "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 3a2aa8e57e..c06dc6210c 100644
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -86,11 +86,16 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
char tmp_line[128];
size_t chunk_size = 0, file_size = 0;
+ if (strchr(mode, 'a') || strchr(mode, '+') || strchr(mode, 'w')) {
+ php_stream_wrapper_log_error(wrapper, options, "HTTP wrapper does not writeable connections.");
+ return NULL;
+ }
+
resource = php_url_parse(path);
if (resource == NULL)
return NULL;
- use_ssl = resource->scheme && resource->scheme[4] == 's';
+ use_ssl = resource->scheme && (strlen(resource->scheme) > 4) && resource->scheme[4] == 's';
/* choose default ports */
if (use_ssl && resource->port == 0)
@@ -113,9 +118,7 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
#if HAVE_OPENSSL_EXT
if (use_ssl) {
if (php_stream_sock_ssl_activate(stream, 1) == FAILURE) {
- if (options & REPORT_ERRORS) {
- zend_error(E_WARNING, "Unable to activate SSL mode");
- }
+ php_stream_wrapper_log_error(wrapper, options, "Unable to activate SSL mode");
php_stream_close(stream);
stream = NULL;
goto out;
@@ -323,8 +326,7 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch
FREE_ZVAL(stream->wrapperdata);
}
} else {
- if (options & REPORT_ERRORS)
- zend_error(E_WARNING, "HTTP request failed! %s", tmp_line);
+ php_stream_wrapper_log_error(wrapper, options, "HTTP request failed! %s", tmp_line);
}
}
out:
diff --git a/main/php_streams.h b/main/php_streams.h
index d50b8135c4..160d733931 100755
--- a/main/php_streams.h
+++ b/main/php_streams.h
@@ -169,8 +169,15 @@ struct _php_stream_wrapper {
php_stream_wrapper_ops *wops; /* operations the wrapper can perform */
void *abstract; /* context for the wrapper */
int is_url; /* so that PG(allow_url_fopen) can be respected */
+
+ /* support for wrappers to return (multiple) error messages to the stream opener */
+ int err_count;
+ char **err_stack;
};
+/* pushes an error message onto the stack for a wrapper instance */
+PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...);
+
struct _php_stream {
php_stream_ops *ops;
void *abstract; /* convenience pointer for abstraction */
diff --git a/main/streams.c b/main/streams.c
index 318c815bcc..931e331457 100755
--- a/main/streams.c
+++ b/main/streams.c
@@ -1286,6 +1286,26 @@ PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_
return NULL;
}
+PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...)
+{
+ va_list args;
+ char *buffer = NULL;
+
+ va_start(args, fmt);
+ vspprintf(&buffer, 0, fmt, args);
+ va_end(args);
+
+ if (options & REPORT_ERRORS || wrapper == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, buffer);
+ efree(buffer);
+ } else {
+ /* append to stack */
+ wrapper->err_stack = erealloc(wrapper->err_stack, (wrapper->err_count + 1) * sizeof(char *));
+ if (wrapper->err_stack)
+ wrapper->err_stack[wrapper->err_count++] = buffer;
+ }
+}
+
/* {{{ php_stream_open_wrapper_ex */
PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int options,
char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
@@ -1305,8 +1325,13 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
wrapper = locate_url_wrapper(path, &path_to_open, options TSRMLS_CC);
if (wrapper) {
+
+ /* prepare error stack */
+ wrapper->err_count = 0;
+ wrapper->err_stack = NULL;
+
stream = wrapper->wops->stream_opener(wrapper,
- path_to_open, mode, options,
+ path_to_open, mode, options ^ REPORT_ERRORS,
opened_path, context STREAMS_REL_CC TSRMLS_CC);
if (stream)
stream->wrapper = wrapper;
@@ -1326,8 +1351,8 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
if (options & REPORT_ERRORS) {
char *tmp = estrdup(path);
php_strip_url_passwd(tmp);
- zend_error(E_WARNING, "%s(\"%s\") - could not make seekable - %s",
- get_active_function_name(TSRMLS_C), tmp, strerror(errno));
+ php_error_docref1(NULL TSRMLS_CC, tmp, E_WARNING, "could not make seekable - %s",
+ tmp, strerror(errno));
efree(tmp);
options ^= REPORT_ERRORS;
@@ -1338,15 +1363,55 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
char *tmp = estrdup(path);
char *msg;
- if (wrapper)
- msg = strerror(errno);
- else
+ if (wrapper) {
+ if (wrapper->err_count) {
+ int i;
+ size_t l;
+ int brlen;
+ char *br;
+
+ if (PG(html_errors)) {
+ brlen = 7;
+ br = "<br />\n";
+ } else {
+ brlen = 1;
+ br = "\n";
+ }
+
+ for (i = 0, l = 0; i < wrapper->err_count; i++) {
+ l += strlen(wrapper->err_stack[i]);
+ if (i < wrapper->err_count - 1)
+ l += brlen;
+ }
+ msg = emalloc(l + 1);
+ msg[0] = '\0';
+ for (i = 0; i < wrapper->err_count; i++) {
+ strcat(msg, wrapper->err_stack[i]);
+ if (i < wrapper->err_count - 1)
+ strcat(msg, br);
+ }
+
+ } else {
+ msg = strerror(errno);
+ }
+ } else {
msg = "no suitable wrapper could be found";
+ }
php_strip_url_passwd(tmp);
- zend_error(E_WARNING, "%s(\"%s\") - %s", get_active_function_name(TSRMLS_C), tmp, msg);
+ php_error_docref1(NULL TSRMLS_CC, tmp, E_WARNING, "failed to create stream: %s", msg);
efree(tmp);
}
+ if (wrapper) {
+ /* tidy up the error stack */
+ int i;
+
+ for (i = 0; i < wrapper->err_count; i++)
+ efree(wrapper->err_stack[i]);
+ if (wrapper->err_stack)
+ efree(wrapper->err_stack);
+ wrapper->err_stack = NULL;
+ }
return stream;
}
/* }}} */