have in the future now obey to the variables_order directive, and there's a real way modular
way to handle POST content.
This is all untested, BEFORE_SAPI_POST_PATCH_17_FEB_2000 tagged before submission
@- Made multipart/form-data content obey to the variables_order directive (Zeev)
#undef THREAD_SAFE
#endif
+
+#if 0
+ if((NULL != SG(request_info).content_type) && (0 == strcmp(SG(request_info).content_type, "application/vnd.fdf"))) {
+ pval *tmp;
+
+ ALLOC_ZVAL(tmp);
+ tmp->value.str.len = SG(request_info).post_data_length;
+ tmp->value.str.val = estrndup(SG(request_info).post_data, SG(request_info).post_data_length);
+ tmp->type = IS_STRING;
+ INIT_PZVAL(tmp);
+ zend_hash_add(&EG(symbol_table), "HTTP_FDF_DATA", sizeof("HTTP_FDF_DATA"), &tmp, sizeof(pval *),NULL);
+
+ } else {
+#endif
+
+
#include "php.h"
#include "ext/standard/head.h"
#include <math.h>
SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
-#define DEFAULT_POST_CONTENT_TYPE "application/x-www-form-urlencoded"
-
-static sapi_post_content_type_reader supported_post_content_types[] = {
- { DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data },
+static sapi_post_entry supported_post_entries[] = {
#if HAVE_FDFLIB
{ "application/vnd.fdf", sizeof("application/vnd.fdf")-1, sapi_read_standard_form_data },
#endif
sapi_module = *sf;
zend_hash_init(&known_post_content_types, 5, NULL, NULL, 1);
- sapi_register_post_readers(supported_post_content_types);
+ sapi_register_post_entries(supported_post_entries);
#ifdef ZTS
sapi_globals_id = ts_allocate_id(sizeof(sapi_globals_struct), NULL, NULL);
}
+SAPI_API void sapi_handle_post(void *arg SLS_DC)
+{
+ if (SG(request_info).post_entry) {
+ SG(request_info).post_entry->post_handler(SG(request_info).content_type_dup, arg SLS_CC);
+ efree(SG(request_info).post_data);
+ efree(SG(request_info).content_type_dup);
+ SG(request_info).content_type_dup = NULL;
+ }
+}
+
static void sapi_read_post_data(SLS_D)
{
- sapi_post_content_type_reader *post_content_type_reader;
+ sapi_post_entry *post_entry;
uint content_type_length = strlen(SG(request_info).content_type);
char *content_type = estrndup(SG(request_info).content_type, content_type_length);
char *p;
char oldchar=0;
- void (*post_reader_func)(char *content_type_dup SLS_DC);
+ void (*post_reader_func)(SLS_D);
/* dedicated implementation for increased performance:
}
}
- if (zend_hash_find(&known_post_content_types, content_type, content_type_length+1, (void **) &post_content_type_reader)==SUCCESS) {
- post_reader_func = post_content_type_reader->post_reader;
+ if (zend_hash_find(&known_post_content_types, content_type, content_type_length+1, (void **) &post_entry)==SUCCESS) {
+ SG(request_info).post_entry = post_entry;
+ post_reader_func = post_entry->post_reader;
} else {
if (!sapi_module.default_post_reader) {
sapi_module.sapi_error(E_COMPILE_ERROR, "Unsupported content type: '%s'", content_type);
return;
}
+ SG(request_info).post_entry = NULL;
post_reader_func = sapi_module.default_post_reader;
}
if (oldchar) {
*(p-1) = oldchar;
}
- post_reader_func(content_type SLS_CC);
- efree(content_type);
+ post_reader_func(SLS_C);
+ SG(request_info).content_type_dup = content_type;
}
if (SG(request_info).auth_password) {
efree(SG(request_info).auth_password);
}
+ if (SG(request_info).content_type_dup) {
+ efree(SG(request_info).content_type_dup);
+ }
if (SG(request_info).current_user) {
efree(SG(request_info).current_user);
}
}
}
+
+SAPI_API void sapi_initialize_empty_request(SLS_D)
+{
+ SG(server_context) = NULL;
+ SG(request_info).request_method = NULL;
+ SG(request_info).auth_user = SG(request_info).auth_password = NULL;
+ SG(request_info).content_type_dup = NULL;
+}
+
+
static int sapi_extract_response_code(const char *header_line)
{
int code = 200;
}
-SAPI_API int sapi_register_post_readers(sapi_post_content_type_reader *post_content_type_readers)
+SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entries)
{
- sapi_post_content_type_reader *p=post_content_type_readers;
+ sapi_post_entry *p=post_entries;
while (p->content_type) {
- if (sapi_register_post_reader(p)==FAILURE) {
+ if (sapi_register_post_entry(p)==FAILURE) {
return FAILURE;
}
p++;
}
-SAPI_API int sapi_register_post_reader(sapi_post_content_type_reader *post_content_type_reader)
+SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry)
{
- return zend_hash_add(&known_post_content_types, post_content_type_reader->content_type, post_content_type_reader->content_type_len+1, (void *) post_content_type_reader, sizeof(sapi_post_content_type_reader), NULL);
+ return zend_hash_add(&known_post_content_types, post_entry->content_type, post_entry->content_type_len+1, (void *) post_entry, sizeof(sapi_post_entry), NULL);
}
-SAPI_API void sapi_unregister_post_reader(sapi_post_content_type_reader *post_content_type_reader)
+SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry)
{
- zend_hash_del(&known_post_content_types, post_content_type_reader->content_type, post_content_type_reader->content_type_len+1);
+ zend_hash_del(&known_post_content_types, post_entry->content_type, post_entry->content_type_len+1);
}
-SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(char *content_type_dup SLS_DC))
+SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(SLS_D))
{
sapi_module.default_post_reader = default_post_reader;
return SUCCESS;
} sapi_headers_struct;
+typedef struct _sapi_post_entry sapi_post_entry;
typedef struct _sapi_module_struct sapi_module_struct;
unsigned char headers_only;
+ sapi_post_entry *post_entry;
+
+ char *content_type_dup;
+
/* for HTTP authentication */
char *auth_user;
char *auth_password;
extern SAPI_API sapi_globals_struct sapi_globals;
#endif
-typedef struct _sapi_post_content_type_reader {
- char *content_type;
- uint content_type_len;
- void (*post_reader)(char *content_type_dup SLS_DC);
-} sapi_post_content_type_reader;
-
SAPI_API void sapi_startup(sapi_module_struct *sf);
SAPI_API void sapi_shutdown(void);
SAPI_API void sapi_activate(SLS_D);
SAPI_API void sapi_deactivate(SLS_D);
+SAPI_API void sapi_initialize_empty_request(SLS_D);
SAPI_API int sapi_add_header(char *header_line, uint header_line_len);
SAPI_API int sapi_send_headers(void);
SAPI_API void sapi_free_header(sapi_header_struct *sapi_header);
+SAPI_API void sapi_handle_post(void *arg SLS_DC);
-SAPI_API int sapi_register_post_readers(sapi_post_content_type_reader *post_content_type_readers);
-SAPI_API int sapi_register_post_reader(sapi_post_content_type_reader *post_content_type_reader);
-SAPI_API void sapi_unregister_post_reader(sapi_post_content_type_reader *post_content_type_reader);
-SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(char *content_type_dup SLS_DC));
+SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entry);
+SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry);
+SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
+SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(SLS_D));
SAPI_API int sapi_flush();
SAPI_API struct stat *sapi_get_stat();
void (*block_interruptions)(void);
void (*unblock_interruptions)(void);
- void (*default_post_reader)(char *content_type_dup SLS_DC);
+ void (*default_post_reader)(SLS_D);
};
+struct _sapi_post_entry {
+ char *content_type;
+ uint content_type_len;
+ void (*post_reader)(SLS_D);
+ void (*post_handler)(char *content_type_dup, void *arg SLS_DC);
+};
+
/* header_handler() constants */
#define SAPI_HEADER_ADD (1<<0)
#define SAPI_HEADER_DELETE_ALL (1<<1)
#define SAPI_DEFAULT_CONTENT_TYPE "Content-Type: text/html"
#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
-#define SAPI_POST_READER_FUNC(post_reader) void post_reader(char *content_type_dup SLS_DC)
+#define SAPI_POST_READER_FUNC(post_reader) void post_reader(SLS_D)
+#define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg SLS_DC)
SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
#endif
global_lock_init();
- SG(server_context) = NULL;
- SG(request_info).request_method = NULL;
- SG(request_info).auth_user = SG(request_info).auth_password = NULL;
+ sapi_initialize_empty_request(SLS_C);
sapi_activate(SLS_C);
if (module_initialized) {
zuv.allow_call_time_pass_reference = PG(allow_call_time_pass_reference);
zuv.import_use_extension = ".php";
zend_set_utility_values(&zuv);
- php_startup_SAPI_content_types();
+ php_startup_sapi_content_types();
REGISTER_MAIN_STRINGL_CONSTANT("PHP_VERSION", PHP_VERSION, sizeof(PHP_VERSION)-1, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_STRINGL_CONSTANT("PHP_OS", php_os, strlen(php_os), CONST_PERSISTENT | CONST_CS);
#include "php_content_types.h"
-static sapi_post_content_type_reader php_post_content_types[] = {
- { MULTIPART_CONTENT_TYPE, sizeof(MULTIPART_CONTENT_TYPE)-1, rfc1867_post_reader },
+static sapi_post_entry php_post_entries[] = {
+ { DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data, php_std_post_handler },
+ { MULTIPART_CONTENT_TYPE, sizeof(MULTIPART_CONTENT_TYPE)-1, sapi_read_standard_form_data, rfc1867_post_handler },
{ NULL, 0, NULL }
};
char *data;
ELS_FETCH();
- sapi_read_standard_form_data(content_type_dup SLS_CC);
+ sapi_read_standard_form_data(SLS_C);
data = estrndup(SG(request_info).post_data,SG(request_info).post_data_length);
SET_VAR_STRINGL("HTTP_RAW_POST_DATA", data, SG(request_info).post_data_length);
}
-int php_startup_SAPI_content_types(void)
+int php_startup_sapi_content_types(void)
{
- sapi_register_post_readers(php_post_content_types);
+ sapi_register_post_entries(php_post_entries);
sapi_register_default_post_reader(php_default_post_reader);
return SUCCESS;
}
#ifndef _PHP_CONTENT_TYPES_H
#define _PHP_CONTENT_TYPES_H
+#define DEFAULT_POST_CONTENT_TYPE "application/x-www-form-urlencoded"
+
SAPI_POST_READER_FUNC(php_default_post_reader);
-int php_startup_SAPI_content_types(void);
+SAPI_POST_HANDLER_FUNC(php_std_post_handler);
+int php_startup_sapi_content_types(void);
#endif /* _PHP_CONTENT_TYPES_H */
}
+SAPI_POST_HANDLER_FUNC(php_std_post_handler)
+{
+ char *var, *val;
+ char *strtok_buf = NULL;
+ zval *array_ptr = (zval *) arg;
+ ELS_FETCH();
+ PLS_FETCH();
+
+ var = strtok_r(SG(request_info).post_data, "&", &strtok_buf);
+
+ while (var) {
+ val = strchr(var, '=');
+ if (val) { /* have a value */
+ *val++ = '\0';
+ /* FIXME: XXX: not binary safe, discards returned length */
+ php_url_decode(var, strlen(var));
+ php_url_decode(val, strlen(val));
+ php_register_variable(var, val, array_ptr ELS_CC PLS_CC);
+ }
+ var = strtok_r(NULL, "&", &strtok_buf);
+ }
+}
+
+
void php_treat_data(int arg, char *str ELS_DC PLS_DC SLS_DC)
{
char *res = NULL, *var, *val;
INIT_PZVAL(array_ptr);
switch (arg) {
case PARSE_POST:
- if (zend_hash_add_ptr(&EG(symbol_table), "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), array_ptr, sizeof(pval *),NULL)==FAILURE) {
- zval **p;
-
- /* This could happen if we're in RFC 1867 file upload */
- /* The parsing portion of the POST reader should actually move
- * to this function - Zeev
- */
- zval_dtor(array_ptr);
- FREE_ZVAL(array_ptr);
- zend_hash_find(&EG(symbol_table), "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), (void **) &p);
- array_ptr = *p;
- }
+ zend_hash_add_ptr(&EG(symbol_table), "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), array_ptr, sizeof(pval *),NULL);
break;
case PARSE_GET:
zend_hash_add_ptr(&EG(symbol_table), "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), array_ptr, sizeof(pval *),NULL);
break;
}
- if (arg == PARSE_POST) { /* POST data */
- res = SG(request_info).post_data;
- free_buffer = 0;
- } else if (arg == PARSE_GET) { /* GET data */
+ if (arg==PARSE_POST) {
+ sapi_handle_post(array_ptr SLS_CC);
+ return;
+ }
+
+ if (arg == PARSE_GET) { /* GET data */
var = SG(request_info).query_string;
if (var && *var) {
res = (char *) estrdup(var);
res = str;
free_buffer = 1;
}
+
if (!res) {
return;
}
-#if HAVE_FDFLIB
- if((NULL != SG(request_info).content_type) && (0 == strcmp(SG(request_info).content_type, "application/vnd.fdf"))) {
- pval *tmp;
-
- ALLOC_ZVAL(tmp);
- tmp->value.str.len = SG(request_info).post_data_length;
- tmp->value.str.val = estrndup(SG(request_info).post_data, SG(request_info).post_data_length);
- tmp->type = IS_STRING;
- INIT_PZVAL(tmp);
- zend_hash_add(&EG(symbol_table), "HTTP_FDF_DATA", sizeof("HTTP_FDF_DATA"), &tmp, sizeof(pval *),NULL);
-
+ if (arg == PARSE_COOKIE) {
+ var = strtok_r(res, ";", &strtok_buf);
+ } else if (arg == PARSE_POST) {
+ var = strtok_r(res, "&", &strtok_buf);
} else {
-#endif
+ var = strtok_r(res, PG(arg_separator), &strtok_buf);
+ }
+
+ while (var) {
+ val = strchr(var, '=');
+ if (val) { /* have a value */
+ *val++ = '\0';
+ /* FIXME: XXX: not binary safe, discards returned length */
+ php_url_decode(var, strlen(var));
+ php_url_decode(val, strlen(val));
+ php_register_variable(var, val, array_ptr ELS_CC PLS_CC);
+ }
if (arg == PARSE_COOKIE) {
- var = strtok_r(res, ";", &strtok_buf);
- } else if (arg == PARSE_POST) {
- var = strtok_r(res, "&", &strtok_buf);
+ var = strtok_r(NULL, ";", &strtok_buf);
} else {
- var = strtok_r(res, PG(arg_separator), &strtok_buf);
- }
-
- while (var) {
- val = strchr(var, '=');
- if (val) { /* have a value */
- *val++ = '\0';
- /* FIXME: XXX: not binary safe, discards returned length */
- php_url_decode(var, strlen(var));
- php_url_decode(val, strlen(val));
- php_register_variable(var, val, array_ptr ELS_CC PLS_CC);
- }
- if (arg == PARSE_COOKIE) {
- var = strtok_r(NULL, ";", &strtok_buf);
- } else if (arg == PARSE_POST) {
- var = strtok_r(NULL, "&", &strtok_buf);
- } else {
- var = strtok_r(NULL, PG(arg_separator), &strtok_buf);
- }
+ var = strtok_r(NULL, PG(arg_separator), &strtok_buf);
}
-#if HAVE_FDFLIB
}
-#endif
if (free_buffer) {
efree(res);
}
void php_import_environment_variables(ELS_D PLS_DC);
PHPAPI void php_register_variable(char *var, char *val, pval *track_vars_array ELS_DC PLS_DC);
+
#endif /* _PHP_VARIABLES_H */
/*
* Split raw mime stream up into appropriate components
*/
-static void php_mime_split(char *buf, int cnt, char *boundary)
+static void php_mime_split(char *buf, int cnt, char *boundary, zval *array_ptr)
{
char *ptr, *loc, *loc2, *s, *name, *filename, *u, *fn;
int len, state = 0, Done = 0, rem, urem;
char *namebuf=NULL, *filenamebuf=NULL, *lbuf=NULL;
FILE *fp;
int itype;
- zval *http_post_vars=NULL;
ELS_FETCH();
PLS_FETCH();
- if (PG(track_vars)) {
- ALLOC_ZVAL(http_post_vars);
- array_init(http_post_vars);
- INIT_PZVAL(http_post_vars);
-
- zend_hash_add(&EG(symbol_table), "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), &http_post_vars, sizeof(pval *), NULL);
- }
-
ptr = buf;
rem = cnt;
len = strlen(boundary);
*(loc - 4) = '\0';
/* Magic function that figures everything out */
- php_register_variable(namebuf, ptr, http_post_vars ELS_CC PLS_CC);
+ php_register_variable(namebuf, ptr, array_ptr ELS_CC PLS_CC);
/* And a little kludge to pick out special MAX_FILE_SIZE */
itype = php_check_ident_type(namebuf);
}
-SAPI_POST_READER_FUNC(rfc1867_post_reader)
+SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)
{
char *boundary;
uint boundary_len;
+ zval *array_ptr = (zval *) arg;
boundary = strstr(content_type_dup, "boundary");
if (!boundary || !(boundary=strchr(boundary, '='))) {
boundary++;
boundary_len = strlen(boundary);
- sapi_read_standard_form_data(content_type_dup SLS_CC);
if (SG(request_info).post_data) {
- php_mime_split(SG(request_info).post_data, SG(request_info).post_data_length, boundary);
- efree(SG(request_info).post_data);
- SG(request_info).post_data = NULL;
+ php_mime_split(SG(request_info).post_data, SG(request_info).post_data_length, boundary, array_ptr);
}
}
#define MULTIPART_CONTENT_TYPE "multipart/form-data"
SAPI_POST_READER_FUNC(rfc1867_post_reader);
+SAPI_POST_HANDLER_FUNC(rfc1867_post_handler);
#define FILE_UPLOAD_INPUT_BUFFER_SIZE 8192