summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--ext/standard/basic_functions.c10
-rw-r--r--ext/standard/fsock.c3
-rw-r--r--ext/standard/http_fopen_wrapper.c94
-rw-r--r--main/fopen_wrappers.c14
5 files changed, 97 insertions, 26 deletions
diff --git a/NEWS b/NEWS
index ef0a3ce29d..c3f479ff8c 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ PHP 4.0 NEWS
?? ??? 2000, Version 4.0.4
+- URL-opened files now store the HTTP response header in $http_response_header
+ (Zeev)
- Fixed array_rand() to shuffle results when the number of requested
elements is the same as the number of elements in the array. (Andrei)
- Added replace parameter to header() (Sascha)
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 880f6b63f0..0ee9ae0012 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -724,14 +724,14 @@ PHP_MINIT_FUNCTION(basic)
#endif
if(PG(allow_url_fopen)) {
- if(FAILURE==php_register_url_wrapper("http",php_fopen_url_wrap_http)) {
+ if (FAILURE==php_register_url_wrapper("http", php_fopen_url_wrap_http)) {
return FAILURE;
}
- if(FAILURE==php_register_url_wrapper("ftp",php_fopen_url_wrap_ftp)) {
- return FAILURE;
+ if (FAILURE==php_register_url_wrapper("ftp", php_fopen_url_wrap_ftp)) {
+ return FAILURE;
}
- if(FAILURE==php_register_url_wrapper("php",php_fopen_url_wrap_php)) {
- return FAILURE;
+ if (FAILURE==php_register_url_wrapper("php", php_fopen_url_wrap_php)) {
+ return FAILURE;
}
}
diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c
index fa5fb96d02..dd273a4e1d 100644
--- a/ext/standard/fsock.c
+++ b/ext/standard/fsock.c
@@ -649,8 +649,9 @@ char *php_sock_fgets(char *buf, size_t maxlen, int socket)
/* signal error only, if we don't return data from this call and
if there is no data to read and if the eof flag is set */
- if(amount || TOREAD(sock) || !sock->eof)
+ if(amount || TOREAD(sock) || !sock->eof) {
ret = buf;
+ }
return ret;
}
diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c
index 400695f2f1..8dab72a0c1 100644
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -64,11 +64,13 @@
#include "php_fopen_wrappers.h"
+#define HTTP_HEADER_BLOCK_SIZE 128
+
FILE *php_fopen_url_wrap_http(char *path, char *mode, int options, int *issock, int *socketd, char **opened_path)
{
FILE *fp=NULL;
php_url *resource=NULL;
- char tmp_line[512];
+ char tmp_line[128];
char location[512];
char hdr_line[8192];
int body = 0;
@@ -76,6 +78,9 @@ FILE *php_fopen_url_wrap_http(char *path, char *mode, int options, int *issock,
unsigned char *tmp;
int len;
int reqok = 0;
+ zval *response_header;
+ char *http_header_line;
+ int http_header_line_length, http_header_line_size;
resource = url_parse((char *) path);
if (resource == NULL) {
@@ -84,8 +89,9 @@ FILE *php_fopen_url_wrap_http(char *path, char *mode, int options, int *issock,
return NULL;
}
/* use port 80 if one wasn't specified */
- if (resource->port == 0)
+ if (resource->port == 0) {
resource->port = 80;
+ }
*socketd = php_hostconnect(resource->host, resource->port, SOCK_STREAM, 0);
if (*socketd == -1) {
@@ -171,37 +177,97 @@ FILE *php_fopen_url_wrap_http(char *path, char *mode, int options, int *issock,
body = 0;
location[0] = '\0';
+
+ MAKE_STD_ZVAL(response_header);
+ array_init(response_header);
+
if (!SOCK_FEOF(*socketd)) {
/* get response header */
if (SOCK_FGETS(tmp_line, sizeof(tmp_line)-1, *socketd) != NULL) {
+ zval *http_response;
+
+ MAKE_STD_ZVAL(http_response);
if (strncmp(tmp_line + 8, " 200 ", 5) == 0) {
reqok = 1;
}
+ 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') {
+ Z_STRVAL_P(http_response)[Z_STRLEN_P(http_response)-1]=0;
+ Z_STRLEN_P(http_response)--;
+ if (Z_STRVAL_P(http_response)[Z_STRLEN_P(http_response)-1]=='\r') {
+ Z_STRVAL_P(http_response)[Z_STRLEN_P(http_response)-1]=0;
+ Z_STRLEN_P(http_response)--;
+ }
+ }
+ Z_TYPE_P(http_response) = IS_STRING;
+ zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_response, sizeof(zval *), NULL);
}
}
+
+
/* Read past HTTP headers */
while (!body && !SOCK_FEOF(*socketd)) {
- if (SOCK_FGETS(tmp_line, sizeof(tmp_line)-1, *socketd) != NULL) {
- char *p = tmp_line;
+ http_header_line = emalloc(HTTP_HEADER_BLOCK_SIZE);
+ http_header_line_size = HTTP_HEADER_BLOCK_SIZE;
+ http_header_line_length = 0;
+ if (SOCK_FGETS(http_header_line, HTTP_HEADER_BLOCK_SIZE-1, *socketd) != NULL) {
+ char *p;
+ zend_bool found_eol=0;
+ zval *http_header;
- tmp_line[sizeof(tmp_line)-1] = '\0';
+ http_header_line[HTTP_HEADER_BLOCK_SIZE-1] = '\0';
- while (*p) {
- if (*p == '\n' || *p == '\r') {
- *p = '\0';
+ do {
+ p = http_header_line+http_header_line_length;
+ while (*p) {
+ while (*p == '\n' || *p == '\r') {
+ *p = '\0';
+ p--;
+ found_eol=1;
+ }
+ if (found_eol) {
+ break;
+ }
+ p++;
}
- p++;
- }
+ if (!found_eol) {
+ http_header_line_size += HTTP_HEADER_BLOCK_SIZE;
+ http_header_line_length += HTTP_HEADER_BLOCK_SIZE-1;
+ http_header_line = erealloc(http_header_line, http_header_line_size);
+ if (SOCK_FGETS(http_header_line+http_header_line_length, HTTP_HEADER_BLOCK_SIZE-1, *socketd)==NULL) {
+ http_header_line[http_header_line_length] = 0;
+ break;
+ }
+ } else {
+ http_header_line_length = p-http_header_line+1;
+ }
+ } while (!found_eol);
- if (!strncasecmp(tmp_line, "Location: ", 10)) {
- strlcpy(location, tmp_line + 10, sizeof(location));
+ if (!strncasecmp(http_header_line, "Location: ", 10)) {
+ strlcpy(location, http_header_line + 10, sizeof(location));
}
- if (tmp_line[0] == '\0') {
- body = 1;
+ if (http_header_line[0] == '\0') {
+ body = 1;
+ }
+
+ if (http_header_line_length>0) {
+ MAKE_STD_ZVAL(http_header);
+ Z_STRVAL_P(http_header) = http_header_line;
+ Z_STRLEN_P(http_header) = http_header_line_length;
+ Z_TYPE_P(http_header) = IS_STRING;
+ zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_header, sizeof(zval *), NULL);
+ } else {
+ efree(http_header_line);
}
}
}
+ {
+ ELS_FETCH();
+
+ zend_hash_update(EG(active_symbol_table), "http_response_header", sizeof("http_response_header"), (void **) &response_header, sizeof(zval *), NULL);
+ }
if (!reqok) {
SOCK_FCLOSE(*socketd);
*socketd = 0;
diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c
index 6aaa1bd5ad..0ec968d887 100644
--- a/main/fopen_wrappers.c
+++ b/main/fopen_wrappers.c
@@ -431,24 +431,26 @@ static FILE *php_fopen_url_wrapper(const char *path, char *mode, int options, in
int n=0;
- for(p=path;isalnum((int)*p);p++)
+ for (p=path; isalnum((int)*p); p++) {
n++;
- if((*p==':')&&(n>1)) {
+ }
+ if ((*p==':')&&(n>1)) {
protocol=path;
}
- if(protocol) {
+ if (protocol) {
php_fopen_url_wrapper_t *wrapper=NULL;
- if(FAILURE==zend_hash_find(&fopen_url_wrappers_hash, (char *)protocol, n, (void **)&wrapper)) {
+ if (FAILURE==zend_hash_find(&fopen_url_wrappers_hash, (char *) protocol, n, (void **)&wrapper)) {
wrapper=NULL;
protocol=NULL;
}
- if(wrapper)
+ if (wrapper) {
return (*wrapper)(path, mode, options, issock, socketd, opened_path);
+ }
}
- if( !protocol || !strncasecmp(protocol, "file",n)){
+ if (!protocol || !strncasecmp(protocol, "file",n)){
PLS_FETCH();
*issock = 0;