summaryrefslogtreecommitdiff
path: root/ext/standard/http_fopen_wrapper.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/http_fopen_wrapper.c')
-rw-r--r--ext/standard/http_fopen_wrapper.c57
1 files changed, 48 insertions, 9 deletions
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;