- URL-opened files now store the HTTP response header in $http_response_header

- Some layout updates
This commit is contained in:
Zeev Suraski 2000-10-28 01:31:56 +00:00
parent d77aede9a9
commit 3dc7fc54a0
5 changed files with 97 additions and 26 deletions

2
NEWS
View file

@ -3,6 +3,8 @@ PHP 4.0 NEWS
?? ??? 2000, Version 4.0.4 ?? ??? 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 - Fixed array_rand() to shuffle results when the number of requested
elements is the same as the number of elements in the array. (Andrei) elements is the same as the number of elements in the array. (Andrei)
- Added replace parameter to header() (Sascha) - Added replace parameter to header() (Sascha)

View file

@ -724,13 +724,13 @@ PHP_MINIT_FUNCTION(basic)
#endif #endif
if(PG(allow_url_fopen)) { 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; return FAILURE;
} }
if(FAILURE==php_register_url_wrapper("ftp",php_fopen_url_wrap_ftp)) { if (FAILURE==php_register_url_wrapper("ftp", php_fopen_url_wrap_ftp)) {
return FAILURE; return FAILURE;
} }
if(FAILURE==php_register_url_wrapper("php",php_fopen_url_wrap_php)) { if (FAILURE==php_register_url_wrapper("php", php_fopen_url_wrap_php)) {
return FAILURE; return FAILURE;
} }
} }

View file

@ -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 /* 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 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; ret = buf;
}
return ret; return ret;
} }

View file

@ -64,11 +64,13 @@
#include "php_fopen_wrappers.h" #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 *php_fopen_url_wrap_http(char *path, char *mode, int options, int *issock, int *socketd, char **opened_path)
{ {
FILE *fp=NULL; FILE *fp=NULL;
php_url *resource=NULL; php_url *resource=NULL;
char tmp_line[512]; char tmp_line[128];
char location[512]; char location[512];
char hdr_line[8192]; char hdr_line[8192];
int body = 0; int body = 0;
@ -76,6 +78,9 @@ FILE *php_fopen_url_wrap_http(char *path, char *mode, int options, int *issock,
unsigned char *tmp; unsigned char *tmp;
int len; int len;
int reqok = 0; int reqok = 0;
zval *response_header;
char *http_header_line;
int http_header_line_length, http_header_line_size;
resource = url_parse((char *) path); resource = url_parse((char *) path);
if (resource == NULL) { if (resource == NULL) {
@ -84,8 +89,9 @@ FILE *php_fopen_url_wrap_http(char *path, char *mode, int options, int *issock,
return NULL; return NULL;
} }
/* use port 80 if one wasn't specified */ /* use port 80 if one wasn't specified */
if (resource->port == 0) if (resource->port == 0) {
resource->port = 80; resource->port = 80;
}
*socketd = php_hostconnect(resource->host, resource->port, SOCK_STREAM, 0); *socketd = php_hostconnect(resource->host, resource->port, SOCK_STREAM, 0);
if (*socketd == -1) { if (*socketd == -1) {
@ -171,37 +177,97 @@ FILE *php_fopen_url_wrap_http(char *path, char *mode, int options, int *issock,
body = 0; body = 0;
location[0] = '\0'; location[0] = '\0';
MAKE_STD_ZVAL(response_header);
array_init(response_header);
if (!SOCK_FEOF(*socketd)) { if (!SOCK_FEOF(*socketd)) {
/* get response header */ /* get response header */
if (SOCK_FGETS(tmp_line, sizeof(tmp_line)-1, *socketd) != NULL) { 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) { if (strncmp(tmp_line + 8, " 200 ", 5) == 0) {
reqok = 1; 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 */ /* Read past HTTP headers */
while (!body && !SOCK_FEOF(*socketd)) { while (!body && !SOCK_FEOF(*socketd)) {
if (SOCK_FGETS(tmp_line, sizeof(tmp_line)-1, *socketd) != NULL) { http_header_line = emalloc(HTTP_HEADER_BLOCK_SIZE);
char *p = tmp_line; 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';
do {
p = http_header_line+http_header_line_length;
while (*p) { while (*p) {
if (*p == '\n' || *p == '\r') { while (*p == '\n' || *p == '\r') {
*p = '\0'; *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)) { if (!strncasecmp(http_header_line, "Location: ", 10)) {
strlcpy(location, tmp_line + 10, sizeof(location)); strlcpy(location, http_header_line + 10, sizeof(location));
} }
if (tmp_line[0] == '\0') { if (http_header_line[0] == '\0') {
body = 1; 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) { if (!reqok) {
SOCK_FCLOSE(*socketd); SOCK_FCLOSE(*socketd);
*socketd = 0; *socketd = 0;

View file

@ -431,24 +431,26 @@ static FILE *php_fopen_url_wrapper(const char *path, char *mode, int options, in
int n=0; int n=0;
for(p=path;isalnum((int)*p);p++) for (p=path; isalnum((int)*p); p++) {
n++; n++;
if((*p==':')&&(n>1)) { }
if ((*p==':')&&(n>1)) {
protocol=path; protocol=path;
} }
if(protocol) { if (protocol) {
php_fopen_url_wrapper_t *wrapper=NULL; 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; wrapper=NULL;
protocol=NULL; protocol=NULL;
} }
if(wrapper) if (wrapper) {
return (*wrapper)(path, mode, options, issock, socketd, opened_path); return (*wrapper)(path, mode, options, issock, socketd, opened_path);
} }
}
if( !protocol || !strncasecmp(protocol, "file",n)){ if (!protocol || !strncasecmp(protocol, "file",n)){
PLS_FETCH(); PLS_FETCH();
*issock = 0; *issock = 0;