diff options
author | Sascha Schumann <sas@php.net> | 2002-07-03 10:42:31 +0000 |
---|---|---|
committer | Sascha Schumann <sas@php.net> | 2002-07-03 10:42:31 +0000 |
commit | 9c876ea01ad806ae6e345c5dc0cf252c0ebe8864 (patch) | |
tree | 60c5f992ca4a366896c4166747336f79ca7e9164 /main/SAPI.c | |
parent | c73733c59acef49b86af5996cb0ec12b970a7759 (diff) | |
download | php-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.c | 88 |
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); |