Browse Source

Added initial headers support in SAPI

*untested*
It definitely broke the thread-safe CGI, it may have broken other stuff as well.
experimental/newoperator
Andi Gutmans 27 years ago
parent
commit
537cc54acd
  1. 27
      ext/standard/head.c
  2. 2
      ext/standard/head.h
  3. 89
      main/SAPI.c
  4. 57
      main/SAPI.h
  5. 2
      main/logos.h
  6. 8
      main/main.c
  7. 10
      output.c

27
ext/standard/head.c

@ -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)
{

2
ext/standard/head.h

@ -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);

89
main/SAPI.c

@ -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
}
}
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;
}

57
main/SAPI.h

@ -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
@ -13,14 +16,20 @@
#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 */

2
main/logos.h

@ -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,

8
main/main.c

@ -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;

10
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 */
}
Loading…
Cancel
Save