]> granicus.if.org Git - php/commitdiff
Add sapi_header_op interface which supersedes the sapi_add_header and _ex
authorSascha Schumann <sas@php.net>
Wed, 3 Jul 2002 10:42:31 +0000 (10:42 +0000)
committerSascha Schumann <sas@php.net>
Wed, 3 Jul 2002 10:42:31 +0000 (10:42 +0000)
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");

ext/standard/head.c
main/SAPI.c
main/SAPI.h
sapi/pi3web/pi3web_sapi.c
sapi/tux/php_tux.c
sapi/webjames/webjames.c

index 4e4e74c9148965e2c65ad83147311a7b0675f891..d8cc5345c0a41c7ec966382c1e52a23e0328f0ec 100644 (file)
    Sends a raw HTTP header */
 PHP_FUNCTION(header)
 {
-       char *header;
-       int header_len;
-       zend_bool replace = 1;
-       int http_code = 0;
+       zend_bool rep = 1;
+       sapi_header_line ctr = {0};
        
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &header,
-                                                         &header_len, &replace, &http_code) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
+                               &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
                return;
-       }
-       sapi_add_header_ex(header, header_len, 1, replace, http_code TSRMLS_CC);
+       
+       sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
 }
 /* }}} */
 
@@ -70,7 +68,8 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t
        int len=sizeof("Set-Cookie: ");
        time_t t;
        char *dt;
-
+       sapi_header_line ctr = {0};
+       
        len += name_len;
        if (value) {
                int encoded_value_len;
@@ -122,7 +121,10 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t
                strcat(cookie, "; secure");
        }
 
-       return sapi_add_header_ex(cookie, strlen(cookie), 0, 0, 0 TSRMLS_CC);
+       ctr.line = cookie;
+       ctr.line_len = strlen(cookie);
+
+       return sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC);
 }
 
 
index 0077e277fa7452a414f69b8fe731e64ede974afb..6ac801ebb73a11d7ea07f6d948bc04102dc0b72c 100644 (file)
@@ -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);
index c335b327952adc9917ab910e6e271e5aeb13e0e7..dd2753d9cd6fc95ff2d068c809885a9b63eb6135 100644 (file)
@@ -133,9 +133,37 @@ SAPI_API void sapi_activate(TSRMLS_D);
 SAPI_API void sapi_deactivate(TSRMLS_D);
 SAPI_API void sapi_initialize_empty_request(TSRMLS_D);
 
-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);
-#define sapi_add_header(header_line, header_line_len, duplicate) \
-       sapi_add_header_ex((header_line), (header_line_len), (duplicate), 1, 0 TSRMLS_CC)
+/*
+ * This is the preferred and maintained API for 
+ * operating on HTTP headers.
+ */
+
+/*
+ * Always specify a sapi_header_line this way:
+ *
+ *     sapi_header_line ctr = {0};
+ */
+typedef struct {
+       char *line; /* If you allocated this, you need to free it yourself */
+       uint line_len;
+       long response_code; /* long due to zend_parse_parameters compatibility */
+} sapi_header_line;
+
+typedef enum {                                 /* Parameter:                   */
+       SAPI_HEADER_REPLACE,            /* sapi_header_line*    */
+       SAPI_HEADER_ADD,                        /* sapi_header_line*    */
+       SAPI_HEADER_SET_STATUS          /* int                                  */
+} sapi_header_op_enum;
+
+SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC);
+
+
+/* Deprecated functions. Use sapi_header_op instead. */
+SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bool duplicate, zend_bool replace TSRMLS_DC);
+#define sapi_add_header(a, b, c) sapi_add_header_ex((a),(b),(c),1 TSRMLS_CC)
+
+
 SAPI_API int sapi_send_headers(TSRMLS_D);
 SAPI_API void sapi_free_header(sapi_header_struct *sapi_header);
 SAPI_API void sapi_handle_post(void *arg TSRMLS_DC);
index a7176a1b2a084ac25d8173ac430c354e1b343318..83fe5fdef7ebf32510fa2895c7d7a4e2a6a15c5c 100644 (file)
@@ -422,9 +422,14 @@ DWORD PHP4_wrapper(LPCONTROL_BLOCK lpCB)
                                        };
                                };
                                break;
-                       case PHP_MODE_INDENT:
-                               header_line = (char *)estrdup("Content-Type: text/plain");
-                               sapi_add_header_ex(header_line, strlen(header_line), 1, 1, 0 TSRMLS_CC);
+                       case PHP_MODE_INDENT: {
+                               sapi_header_line ctr = {0};
+
+                               ctr.line = "Content-Type: text/plain";
+                               ctr.line_len = strlen(ctr.line);
+                               
+                               sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
+                         }
                                if ( open_file_for_scanning( &file_handle TSRMLS_CC ) == SUCCESS )
                                        {
                                        zend_indent();
@@ -433,7 +438,6 @@ DWORD PHP4_wrapper(LPCONTROL_BLOCK lpCB)
                                        {
                                        iRet = PIAPI_ERROR;
                                        };
-                               efree(header_line);
                                break;
                        case PHP_MODE_LINT:
                                iRet = (php_lint_script(&file_handle TSRMLS_CC) == SUCCESS) ?
index d2da64882a876326cb1f07e33588b063f93a506d..4f0b6e17db8b4c6c6f009eb559d42335102e039d 100644 (file)
@@ -192,10 +192,12 @@ static void sapi_tux_register_variables(zval *track_vars_array TSRMLS_DC)
 {
        char buf[BUF_SIZE + 1];
        char *p;
-
+       sapi_header_line ctr = {0};
+       
+       ctr.line = buf;
+       ctr.line_len = sprintf(buf, "Server: %s", TUXAPI_version);
+       sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
        
-       sprintf(buf, "Server: %s", TUXAPI_version);
-       sapi_add_header_ex(buf, strlen(buf), 1, 0, 0 TSRMLS_CC);
        php_register_variable("PHP_SELF", SG(request_info).request_uri, track_vars_array TSRMLS_CC);
        php_register_variable("SERVER_SOFTWARE", TUXAPI_version, track_vars_array TSRMLS_CC);
        php_register_variable("GATEWAY_INTERFACE", "CGI/1.1", track_vars_array TSRMLS_CC);
index 1aba413dee04adeda60fad743a21852030880cf7..3bea3457e48fc141e65badaf38058c3f4c3a0ebd 100644 (file)
@@ -54,22 +54,6 @@ static int sapi_webjames_ub_write(const char *str, uint str_length TSRMLS_DC)
        return bytes;
 }
 
-static int sapi_webjames_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
-/*send the HTTP response line*/
-{
-       char buf[256];
-
-       if (WG(conn)->flags.outputheaders) {
-               if (!SG(sapi_headers).http_status_line) {
-                       int code=SG(sapi_headers).http_response_code;
-                       snprintf(buf, 255, "HTTP/1.0 %d %s\r\n", code, code==200 ? "OK" : code==302 ? "Moved temporarily" : "Something");
-                       webjames_writestring(WG(conn), buf);
-               }
-       }
-       
-       return SAPI_HEADER_DO_SEND;
-}
-
 static void sapi_webjames_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC)
 /*send an HTTP header*/
 {
@@ -286,7 +270,7 @@ static sapi_module_struct sapi_module = {
        php_error,                              /* error handler */
 
        NULL,                                   /* header handler */
-       sapi_webjames_send_headers,             /* send headers handler */
+       NULL,                                                           /* send headers handler */
        sapi_webjames_send_header,              /* send header handler */
        sapi_webjames_read_post,                /* read POST data */
        sapi_webjames_read_cookies,             /* read Cookies */