diff options
-rw-r--r-- | README.STREAMS | 4 | ||||
-rw-r--r-- | ext/standard/ftp_fopen_wrapper.c | 7 | ||||
-rw-r--r-- | ext/standard/http_fopen_wrapper.c | 14 | ||||
-rwxr-xr-x | main/php_streams.h | 7 | ||||
-rwxr-xr-x | main/streams.c | 79 |
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; } /* }}} */ |