summaryrefslogtreecommitdiff
path: root/main/SAPI.c
diff options
context:
space:
mode:
authorSascha Schumann <sas@php.net>2002-07-03 10:42:31 +0000
committerSascha Schumann <sas@php.net>2002-07-03 10:42:31 +0000
commit9c876ea01ad806ae6e345c5dc0cf252c0ebe8864 (patch)
tree60c5f992ca4a366896c4166747336f79ca7e9164 /main/SAPI.c
parentc73733c59acef49b86af5996cb0ec12b970a7759 (diff)
downloadphp-git-9c876ea01ad806ae6e345c5dc0cf252c0ebe8864.tar.gz
Add sapi_header_op interface which supersedes the sapi_add_header and _ex
calls. Revert the change to the sapi_add_header_ex interface. Fix various bugs: 1. header("HTTP/1.0 306 foo"); header("Location: absolute-uri"); did not work in combination with several SAPI modules, because http_status_line was never properly reset. And thus, all SAPI modules which looked at http_status_line ignored the changed http_response_code. 2. The CGI SAPI did not send out the HTTP status line at all, if http_status_line had not been set explicitly by calling header("HTTP/1.0 200 foo");
Diffstat (limited to 'main/SAPI.c')
-rw-r--r--main/SAPI.c88
1 files changed, 67 insertions, 21 deletions
diff --git a/main/SAPI.c b/main/SAPI.c
index 0077e277fa..6ac801ebb7 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -385,41 +385,83 @@ static int sapi_extract_response_code(const char *header_line)
return code;
}
+
+static void sapi_update_response_code(int ncode TSRMLS_CC)
+{
+ if (SG(sapi_headers).http_status_line) {
+ efree(SG(sapi_headers).http_status_line);
+ SG(sapi_headers).http_status_line = NULL;
+ }
+ SG(sapi_headers).http_response_code = ncode;
+}
+
static int sapi_find_matching_header(void *element1, void *element2)
{
return strncasecmp(((sapi_header_struct*)element1)->header, (char*)element2, strlen((char*)element2)) == 0;
}
-/* This function expects a *duplicated* string, that was previously emalloc()'d.
- * Pointers sent to this functions will be automatically freed by the framework.
- */
-SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bool duplicate, zend_bool replace, int http_response_code TSRMLS_DC)
+SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bool duplicate, zend_bool replace TSRMLS_DC)
+{
+ sapi_header_line ctr = {0};
+ int r;
+
+ ctr.line = header_line;
+ ctr.line_len = header_line_len;
+
+ r = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD,
+ &ctr TSRMLS_CC);
+
+ if (!duplicate)
+ efree(header_line);
+
+ return r;
+}
+
+SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
{
int retval;
sapi_header_struct sapi_header;
char *colon_offset;
long myuid = 0L;
-
+ char *header_line;
+ uint header_line_len;
+ zend_bool replace;
+ int http_response_code;
+
if (SG(headers_sent) && !SG(request_info).no_headers) {
char *output_start_filename = php_get_output_start_filename(TSRMLS_C);
int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);
if (output_start_filename) {
- sapi_module.sapi_error(E_WARNING, "Cannot add header information - headers already sent by (output started at %s:%d)",
+ sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent by (output started at %s:%d)",
output_start_filename, output_start_lineno);
} else {
- sapi_module.sapi_error(E_WARNING, "Cannot add header information - headers already sent");
- }
- if (!duplicate) {
- efree(header_line);
+ sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent");
}
return FAILURE;
}
- if (duplicate) {
- header_line = estrndup(header_line, header_line_len);
+ switch (op) {
+ case SAPI_HEADER_SET_STATUS:
+ sapi_update_response_code((int) arg TSRMLS_CC);
+ return SUCCESS;
+
+ case SAPI_HEADER_REPLACE:
+ case SAPI_HEADER_ADD: {
+ sapi_header_line *p = arg;
+ header_line = p->line;
+ header_line_len = p->line_len;
+ http_response_code = p->response_code;
+ replace = (op == SAPI_HEADER_REPLACE);
+ break;
+ }
+
+ default:
+ return FAILURE;
}
+ header_line = estrndup(header_line, header_line_len);
+
/* cut of trailing spaces, linefeeds and carriage-returns */
while(isspace(header_line[header_line_len-1]))
header_line[--header_line_len]='\0';
@@ -433,7 +475,7 @@ SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bo
if (header_line_len>=5
&& !strncasecmp(header_line, "HTTP/", 5)) {
/* filter out the response code */
- SG(sapi_headers).http_response_code = sapi_extract_response_code(header_line);
+ sapi_update_response_code(sapi_extract_response_code(header_line) TSRMLS_CC);
SG(sapi_headers).http_status_line = header_line;
return SUCCESS;
} else {
@@ -465,7 +507,7 @@ SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bo
if (SG(sapi_headers).http_response_code < 300 ||
SG(sapi_headers).http_response_code > 307) {
/* Return a Found Redirect if one is not already specified */
- SG(sapi_headers).http_response_code = 302;
+ sapi_update_response_code(302 TSRMLS_CC);
}
} else if (!STRCASECMP(header_line, "WWW-Authenticate")) { /* HTTP Authentication */
int newlen;
@@ -476,7 +518,7 @@ SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bo
int ptr_len=0, result_len = 0;
#endif
- SG(sapi_headers).http_response_code = 401; /* authentication-required */
+ sapi_update_response_code(401 TSRMLS_CC); /* authentication-required */
#if HAVE_PCRE || HAVE_BUNDLED_PCRE
if(PG(safe_mode)) {
myuid = php_getuid();
@@ -546,9 +588,8 @@ SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bo
}
}
}
-
if (http_response_code) {
- SG(sapi_headers).http_response_code = http_response_code;
+ sapi_update_response_code(http_response_code TSRMLS_CC);
}
if (sapi_module.header_handler) {
retval = sapi_module.header_handler(&sapi_header, &SG(sapi_headers) TSRMLS_CC);
@@ -602,12 +643,17 @@ SAPI_API int sapi_send_headers(TSRMLS_D)
case SAPI_HEADER_SENT_SUCCESSFULLY:
ret = SUCCESS;
break;
- case SAPI_HEADER_DO_SEND:
- if (SG(sapi_headers).http_status_line) {
+ case SAPI_HEADER_DO_SEND: {
sapi_header_struct http_status_line;
+ char buf[255];
- http_status_line.header = SG(sapi_headers).http_status_line;
- http_status_line.header_len = strlen(SG(sapi_headers).http_status_line);
+ if (SG(sapi_headers).http_status_line) {
+ http_status_line.header = SG(sapi_headers).http_status_line;
+ http_status_line.header_len = strlen(SG(sapi_headers).http_status_line);
+ } else {
+ http_status_line.header = buf;
+ http_status_line.header_len = sprintf(buf, "HTTP/1.0 %d X", SG(sapi_headers).http_response_code);
+ }
sapi_module.send_header(&http_status_line, SG(server_context) TSRMLS_CC);
}
zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) sapi_module.send_header, SG(server_context) TSRMLS_CC);