Permalink
Browse files

An Apache 2.0 Filter for PHP, completely from scratch.

TODO:

	POST, cookies, "flushing", finalizing config framework (it works),
	http auth, PHP Hooks (apache_sub_req is there).

Note that this code depends on some other commits which are pending.
  • Loading branch information...
Sascha Schumann
Sascha Schumann committed Oct 26, 2000
1 parent 26f5fe6 commit d504de0f789a390545fd219b8eebc951012cfa61
@@ -0,0 +1,7 @@
LTLIBRARY_NAME = libsapi.la
LTLIBRARY_SOURCES = sapi_apache2.c apache_config.c
EXTRA_INCLUDES = $(APACHE_INCLUDE)
include $(top_srcdir)/build/ltlib.mk
@@ -0,0 +1,134 @@
#include "php.h"
#include "php_ini.h"
#include "apr_strings.h"
#include "ap_config.h"
#include "util_filter.h"
#include "httpd.h"
#include "http_config.h"
#include "http_request.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_log.h"
#include "http_main.h"
#include "util_script.h"
#include "http_core.h"
typedef struct {
HashTable config;
} php_conf_rec;
typedef struct {
char *value;
size_t value_len;
char status;
} php_dir_entry;
static const char *real_value_hnd(cmd_parms *cmd, void *dummy, const char *name, const char *value, int status)
{
php_conf_rec *d = dummy;
php_dir_entry e;
php_dir_entry *pe;
size_t str_len;
fprintf(stderr, "Getting %s=%s for %p (%d)\n", name, value, dummy, zend_hash_num_elements(&d->config));
e.value = apr_pstrdup(cmd->pool, value);
e.value_len = strlen(value);
e.status = status;
str_len = strlen(name);
if (zend_hash_find(&d->config, name, str_len + 1, &pe) == SUCCESS) {
if (pe->status > status)
return NULL;
}
zend_hash_update(&d->config, name, strlen(name) + 1, &e, sizeof(e),
NULL);
return NULL;
}
static const char *php_apache_value_handler(cmd_parms *cmd, void *dummy, const char *name, const char *value)
{
return real_value_hnd(cmd, dummy, name, value, PHP_INI_USER);
}
static const char *php_apache_admin_value_handler(cmd_parms *cmd, void *dummy, const char *name, const char *value)
{
return real_value_hnd(cmd, dummy, name, value, PHP_INI_SYSTEM);
}
void *merge_php_config(apr_pool_t *p, void *base_conf, void *new_conf)
{
php_conf_rec *d = base_conf, *e = new_conf;
php_dir_entry *pe;
php_dir_entry *data;
char *str;
ulong str_len;
ulong num_index;
char buf[256];
fprintf(stderr, "Merge dir (%p) (%p)\n", base_conf, new_conf);
for (zend_hash_internal_pointer_reset(&d->config);
zend_hash_get_current_key_ex(&d->config, &str, &str_len, &num_index, NULL) == HASH_KEY_IS_STRING;
zend_hash_move_forward(&d->config)) {
pe = NULL;
zend_hash_get_current_data(&d->config, &data);
if (zend_hash_find(&e->config, str, str_len, &pe) == SUCCESS) {
if (pe->status >= data->status) continue;
}
zend_hash_update(&e->config, str, str_len, data, sizeof(*data), NULL);
sprintf(buf, "ADDING/OVERWRITING %%%lds (%d vs. %d)\n", str_len, data->status, pe?pe->status:-1);
fprintf(stderr, buf, str);
}
return new_conf;
}
void apply_config(void *dummy)
{
php_conf_rec *d = dummy;
char *str;
ulong str_len;
php_dir_entry *data;
for (zend_hash_internal_pointer_reset(&d->config);
zend_hash_get_current_key_ex(&d->config, &str, &str_len, NULL, NULL) == HASH_KEY_IS_STRING;
zend_hash_move_forward(&d->config)) {
zend_hash_get_current_data(&d->config, &data);
fprintf(stderr, "APPLYING (%s)(%s)\n", str, data->value);
if (php_alter_ini_entry(str, str_len, data->value, data->value_len + 1,
data->status, PHP_INI_STAGE_RUNTIME) == FAILURE)
fprintf(stderr, "..FAILED\n");
}
}
const command_rec dir_cmds[] =
{
AP_INIT_TAKE2("php_value", php_apache_value_handler, NULL, OR_OPTIONS,
"PHP Value Modifier"),
AP_INIT_TAKE2("php_admin_value", php_apache_admin_value_handler, NULL, OR_OPTIONS,
"PHP Value Modifier"),
{NULL}
};
static apr_status_t destroy_php_config(void *data)
{
php_conf_rec *d = data;
fprintf(stderr, "Destroying config %p\n", data);
zend_hash_destroy(&d->config);
return APR_SUCCESS;
}
void *create_php_config(apr_pool_t *p, char *dummy)
{
php_conf_rec *newx =
(php_conf_rec *) apr_pcalloc(p, sizeof(*newx));
fprintf(stderr, "Creating new config (%p) for %s\n", newx, dummy);
zend_hash_init(&newx->config, 0, NULL, NULL, 1);
apr_register_cleanup(p, newx, destroy_php_config, NULL);
return (void *) newx;
}
@@ -0,0 +1,51 @@
dnl ## -*- sh -*-
AC_MSG_CHECKING(for Apache 2.0 module support via DSO through APXS)
AC_ARG_WITH(apxs2,
[ --with-apxs2[=FILE] Build shared Apache 2.0 module. FILE is the optional
pathname to the Apache apxs tool; defaults to "apxs".],[
if test "$withval" = "yes"; then
APXS=apxs
if $APXS -q CFLAGS >/dev/null 2>&1; then
:
else
if test -x /usr/sbin/apxs ; then #SUSE 6.x
APXS=/usr/sbin/apxs
fi
fi
else
AC_EXPAND_PATH($withval, APXS)
fi
if $APXS -q CFLAGS >/dev/null 2>&1; then
:
else
AC_MSG_RESULT()
$APXS
AC_MSG_ERROR([Sorry, I cannot run apxs. Either you need to install Perl or you need to pass the absolute path of apxs by using --with-apxs2=/absolute/path/to/apxs])
fi
APXS_INCLUDEDIR=`$APXS -q INCLUDEDIR`
APXS_CFLAGS=`$APXS -q CFLAGS`
AC_ADD_INCLUDE($APXS_INCLUDEDIR)
AC_ADD_INCLUDE($APXS_INCLUDEDIR/apr)
if `echo $APXS_CFLAGS|grep USE_HSREGEX>/dev/null`; then
APACHE_HAS_REGEX=yes
fi
if `echo $APXS_CFLAGS|grep EAPI>/dev/null`; then
CPPFLAGS="$CPPFLAGS -DEAPI"
fi
PHP_SAPI=apache2filter
INSTALL_IT="$APXS -i -a -n php4 $SAPI_LIBTOOL"
PHP_BUILD_SHARED
PHP_BUILD_THREAD_SAFE
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
])
PHP_SUBST(APXS)
dnl ## Local Variables:
dnl ## tab-width: 4
dnl ## End:
@@ -0,0 +1 @@
php4_module
@@ -0,0 +1,15 @@
#ifndef PHP_APACHE_H
#define PHP_APACHE_H
typedef struct php_struct {
int state;
ap_bucket_brigade *bb;
ap_filter_t *f;
} php_struct;
void *merge_php_config(apr_pool_t *p, void *base_conf, void *new_conf);
void *create_php_config(apr_pool_t *p, char *dummy);
void apply_config(void *);
extern const command_rec dir_cmds[];
#endif /* PHP_APACHE_H */
@@ -0,0 +1,23 @@
#include "php_apache.h"
PHP_FUNCTION(apache_sub_req)
{
zval **p1;
request_req *rr;
php_struct *ctx;
SLS_FETCH();
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &p1) == FAILURE)
WRONG_NUM_ARGS;
convert_to_string_ex(p1);
ctx = SG(server_context);
rr = ap_sub_req_lookup_uri(Z_STRVAL_PP(p1), ctx->f->r);
if (rr->status == HTTP_OK) {
ap_run_sub_req(rr);
RETURN_TRUE;
}
RETURN_FALSE;
}
Oops, something went wrong.

0 comments on commit d504de0

Please sign in to comment.