]> granicus.if.org Git - php/commitdiff
Added initial headers support in SAPI
authorAndi Gutmans <andi@php.net>
Wed, 5 May 1999 18:25:20 +0000 (18:25 +0000)
committerAndi Gutmans <andi@php.net>
Wed, 5 May 1999 18:25:20 +0000 (18:25 +0000)
*untested*
It definitely broke the thread-safe CGI, it may have broken other stuff as well.

ext/standard/head.c
ext/standard/head.h
main/SAPI.c
main/SAPI.h
main/logos.h
main/main.c
output.c

index ad21e993541763682d6c77c7870bbc183f7602e5..d2cd7eeb07cb667ace1c4e6c48ce57619c56b23b 100644 (file)
@@ -76,8 +76,9 @@ PHPAPI void php3_noheader(void)
 }
 
 
+#ifndef ZTS
 /* Adds header information */
-void php4i_add_header_information(char *header_information)
+void php4i_add_header_information(char *header_information, uint header_length)
 {
        char *r;
 #if APACHE
@@ -202,6 +203,12 @@ void php4i_add_header_information(char *header_information)
        }
 #endif
 }
+#else
+void php4i_add_header_information(char *header_information, uint header_length)
+{
+       sapi_add_header(header_information, header_length);
+}
+#endif
 
 
 /* Implementation of the language Header() function */
@@ -213,12 +220,14 @@ void php3_Header(INTERNAL_FUNCTION_PARAMETERS)
                WRONG_PARAM_COUNT;
        }
        convert_to_string(arg1);
-       php4i_add_header_information(arg1->value.str.val);
+       php4i_add_header_information(arg1->value.str.val, arg1->value.str.len);
 }
 
 
 
 
+
+#ifndef ZTS
 /*
  * php3_header() flushes the header info built up using calls to
  * the Header() function.  If type is 1, a redirect to str is done.
@@ -384,6 +393,20 @@ PHPAPI int php3_header(void)
        PG(header_is_being_sent) = 0;
        return(1);
 }
+#else
+PHPAPI int php3_header()
+{
+       SLS_FETCH();
+
+       if (sapi_send_headers()==FAILURE || SG(request_info).headers_only) {
+               return 0; /* don't allow output */
+       } else {
+               return 1; /* allow output */
+       }
+}
+#endif
+
+
 
 void php3_PushCookieList(char *name, char *value, time_t expires, char *path, char *domain, int secure)
 {
index f7b33d73fd059cdc0357ca2535fa1356ba6ec5cd..3ab12d0d84ef8454d5a523ccc4539822a5137638 100644 (file)
@@ -56,7 +56,7 @@ extern int php3_init_head(INIT_FUNC_ARGS);
 extern void php3_Header(INTERNAL_FUNCTION_PARAMETERS);
 extern void php3_SetCookie(INTERNAL_FUNCTION_PARAMETERS);
 
-void php4i_add_header_information(char *header_information);
+void php4i_add_header_information(char *header_information, uint header_length);
 
 PHPAPI void php3_noheader(void);
 PHPAPI int php3_header(void);
index bdb58baed4448400f0c084345e6ff5ab79411888..c10736536696f5d93d821d7765ac5da5d3dbb0b6 100644 (file)
@@ -3,6 +3,12 @@
 #include "TSRM.h"
 #endif
 
+#if WIN32||WINNT
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
+#endif
+
 
 #ifdef ZTS
 SAPI_API int sapi_globals_id;
@@ -10,13 +16,94 @@ SAPI_API int sapi_globals_id;
 sapi_globals_struct sapi_globals;
 #endif
 
+
 /* A true global (no need for thread safety) */
 sapi_module_struct sapi_module;
 
+
 SAPI_API void sapi_startup(sapi_module_struct *sf)
 {
        sapi_module = *sf;
 #ifdef ZTS
        sapi_globals_id = ts_allocate_id(sizeof(sapi_globals_struct), NULL, NULL);
 #endif
-}
\ No newline at end of file
+}
+
+
+static void sapi_free_header(sapi_header_struct *sapi_header)
+{
+       efree(sapi_header->header);
+}
+
+
+SAPI_API void sapi_activate(SLS_D)
+{
+       zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct), (void (*)(void *)) sapi_free_header, 0);
+       SG(sapi_headers).content_type.header = NULL;
+       SG(sapi_headers).http_response_code = 200;
+}
+
+
+SAPI_API void sapi_deactivate(SLS_D)
+{
+       zend_llist_destroy(&SG(sapi_headers).headers);
+}
+
+
+/* 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(const char *header_line, uint header_line_len)
+{
+       int retval;
+       sapi_header_struct sapi_header;
+       SLS_FETCH();
+
+       sapi_header.header = (char *) header_line;
+       sapi_header.header_len = header_line_len;
+
+       retval = sapi_module.header_handler(&sapi_header, &SG(sapi_headers));
+
+       if (retval & SAPI_HEADER_DELETE_ALL) {
+               zend_llist_clean(&SG(sapi_headers).headers);
+       }
+       if (retval & SAPI_HEADER_ADD) {
+               char *colon_offset = strchr(header_line, ':');
+
+               if (colon_offset) {
+                       *colon_offset = 0;
+                       if (!STRCASECMP(header_line, "Content-Type")) {
+                               if (SG(sapi_headers).content_type.header) {
+                                       efree(SG(sapi_headers).content_type.header);
+                               }
+                               *colon_offset = ':';
+                               SG(sapi_headers).content_type.header = (char *) header_line;
+                               SG(sapi_headers).content_type.header_len = header_line_len;
+                               return SUCCESS;
+                       }
+                       *colon_offset = ':';
+               }
+               zend_llist_add_element(&SG(sapi_headers).headers, (void *) &sapi_header);
+       }
+       return SUCCESS;
+}
+
+
+SAPI_API int sapi_send_headers()
+{
+       SLS_FETCH();
+
+       switch (sapi_module.send_headers(&SG(sapi_headers) SLS_CC)) {
+               case SAPI_HEADER_SENT_SUCCESSFULLY:
+                       return SUCCESS;
+                       break;
+               case SAPI_HEADER_DO_SEND:
+                       zend_llist_apply_with_argument(&SG(sapi_headers).headers, (void (*)(void *, void *)) sapi_module.send_header, SG(server_context));
+                       return SUCCESS;
+                       break;
+               case SAPI_HEADER_SEND_FAILED:
+                       return FAILURE;
+                       break;
+       }
+       return FAILURE;
+}
index 7796fc06348c6424dedb1c3b570d216ec279d7a4..2b76ceae4cc1486c0448dde727c99d9dfd0294ff 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef _NEW_SAPI_H
 #define _NEW_SAPI_H
 
+#include "zend.h"
+#include "zend_llist.h"
+
 
 #if WIN32||WINNT
 #      ifdef SAPI_EXPORTS
 #endif
 
 
-typedef struct _sapi_module_struct {
-       char *name;
+typedef struct {
+       char *header;
+       uint header_len;
+} sapi_header_struct;
 
-       int (*startup)(struct _sapi_module_struct *sapi_module);
-       int (*shutdown)(struct _sapi_module_struct *sapi_module);
 
-       int (*ub_write)(const char *str, unsigned int str_length);
-} sapi_module_struct;
+typedef struct {
+       zend_llist headers;
+       sapi_header_struct content_type;
+       int http_response_code;
+} sapi_headers_struct;
+
+
+typedef struct _sapi_module_struct sapi_module_struct;
 
 
 extern sapi_module_struct sapi_module;  /* true global */
@@ -31,16 +40,24 @@ typedef struct {
 
        char *path_translated;
        char *request_uri;
+
+       unsigned char headers_only;
 } sapi_request_info;
 
 
 typedef struct {
        void *server_context;
        sapi_request_info request_info;
+       sapi_headers_struct sapi_headers;
 } sapi_globals_struct;
 
 
 SAPI_API void sapi_startup(sapi_module_struct *sf);
+SAPI_API void sapi_activate(SLS_D);
+SAPI_API void sapi_deactivate(SLS_D);
+
+SAPI_API int sapi_add_header(const char *header_line, uint header_line_len);
+SAPI_API int sapi_send_headers();
 
 #ifdef ZTS
 # define SLS_D sapi_globals_struct *sapi_globals
@@ -61,4 +78,32 @@ extern SAPI_API sapi_globals_struct sapi_globals;
 #endif
 
 
+
+struct _sapi_module_struct {
+       char *name;
+
+       int (*startup)(struct _sapi_module_struct *sapi_module);
+       int (*shutdown)(struct _sapi_module_struct *sapi_module);
+
+       int (*ub_write)(const char *str, unsigned int str_length);
+
+       int (*header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers);
+       int (*send_headers)(sapi_headers_struct *sapi_headers SLS_DC);
+       void (*send_header)(void *server_context, sapi_header_struct *sapi_header);
+};
+
+
+
+/* header_handler() constants */
+#define SAPI_HEADER_ADD                        (1<<0)
+#define SAPI_HEADER_DELETE_ALL (1<<1)
+#define SAPI_HEADER_SEND_NOW   (1<<2)
+
+
+#define SAPI_HEADER_SENT_SUCCESSFULLY  1
+#define SAPI_HEADER_DO_SEND                            2
+#define SAPI_HEADER_SEND_FAILED                        3
+
+#define DEFAULT_CONTENT_TYPE "Content-Type: text/html"
+
 #endif /* _NEW_SAPI_H */
\ No newline at end of file
index 6c91b0ae5672339948f74325e14e036e49333b07..2826a66a925514d17bbe28b20b64ce58344b82c4 100644 (file)
@@ -1,3 +1,5 @@
+#define CONTEXT_TYPE_IMAGE_GIF "Content-Type:  image/gif"
+
 unsigned char zendtech_logo[] = {
         71,  73,  70,  56,  57,  97, 100,   0,  89,   0, 
        247, 255,   0, 255, 255, 255,   8,   8,   8,  16, 
index a745601c47feeac649125dafe6c3fe142240c822..cfc39a5a0d7ba48b09db213e3c84b1d27bcfc67d 100644 (file)
@@ -1124,16 +1124,16 @@ PHPAPI void php_execute_script(zend_file_handle *primary_file CLS_DC ELS_DC PLS_
 
        if (SG(request_info).query_string && SG(request_info).query_string[0]=='=') {
                if (!strcmp(SG(request_info).query_string+1, "PHPE9568F34-D428-11d2-A769-00AA001ACF42")) {
-                       char *header_line = estrndup("Content-type:  image/gif", sizeof("Content-type:  image/gif")-1);
+                       char *header_line = estrndup(CONTEXT_TYPE_IMAGE_GIF, sizeof(CONTEXT_TYPE_IMAGE_GIF));
 
-                       php4i_add_header_information(header_line);
+                       php4i_add_header_information(header_line, sizeof(CONTEXT_TYPE_IMAGE_GIF));
                        PHPWRITE(php4_logo, sizeof(php4_logo));
                        efree(header_line);
                        return;
                } else if (!strcmp(SG(request_info).query_string+1, "PHPE9568F35-D428-11d2-A769-00AA001ACF42")) {
-                       char *header_line = estrndup("Content-type:  image/gif", sizeof("Content-type:  image/gif")-1);
+                       char *header_line = estrndup(CONTEXT_TYPE_IMAGE_GIF, sizeof(CONTEXT_TYPE_IMAGE_GIF));
 
-                       php4i_add_header_information(header_line);
+                       php4i_add_header_information(header_line, sizeof(CONTEXT_TYPE_IMAGE_GIF));
                        PHPWRITE(zendtech_logo, sizeof(zendtech_logo));
                        efree(header_line);
                        return;
index fdf55945dcf11b4df362b1f001a1e65d711f4d1d..c18650f2f498e54899fa8db9dfdd2e170b7cf044 100644 (file)
--- a/output.c
+++ b/output.c
@@ -35,9 +35,6 @@ void zend_ob_append(const char *text, uint text_length);
 void zend_ob_prepend(const char *text, uint text_length);
 static inline void zend_ob_send();
 
-/* HEAD support  */
-static int header_request;
-
 
 /*
  * Main
@@ -47,7 +44,6 @@ PHPAPI void zend_output_startup()
 {
        ob_buffer = NULL;
        zend_body_write = zend_ub_body_write;
-       header_request=0;
        zend_header_write = sapi_module.ub_write;
 }
 
@@ -172,7 +168,9 @@ static int zend_b_body_write(const char *str, uint str_length)
 
 static int zend_ub_body_write(const char *str, uint str_length)
 {
-       if (header_request) {
+       SLS_FETCH();
+
+       if (SG(request_info).headers_only) {
                zend_bailout();
        }
        if (php3_header()) {
@@ -189,5 +187,5 @@ static int zend_ub_body_write(const char *str, uint str_length)
 
 void set_header_request(int value)
 {
-       header_request = value;
+       /* deprecated */
 }