$ ./configure --with-apxs2=/path/to/apache-2.0/bin/apxs
$ make install
- APXS is currently still flaky, so edit conf/httpd.conf and change
- the LoadModule entry from libphp4.la to libphp4.so.
-
At the end of conf/httpd.conf, add:
<Files *.php>
That's it. Now start bin/httpd.
- If you want to debug Apache, set ONE_PROCESS in your environment
- (comparable to -X in Apache 1.3). We recommened the prefork MPM
- for debugging purposes.
-
+DEBUGGING APACHE AND PHP
+
+ To debug Apache, we recommened:
+
+ 1. Use the Prefork MPM (Apache 1.3-like process model) by
+ configuring Apache with '--with-mpm=prefork'.
+ 2. Set the variable "ONE_PROCESS" to 1 and export it before
+ starting Apache/a debugger.
+
+ If you want to debug a part of the PHP startup procedure, set a
+ breakpoint on 'load_module'. Step through it until apr_dso_load() is
+ done. Then you can set a breakpoint on any PHP-related symbol.
+
TODO
- php_*flag config directives
PHP functions like apache_sub_req (see php_functions.c)
Protocol handlers
Passing script data to engine without temporary file
+----------------------------------------------------------------------+
*/
+#include "php.h"
+#include "SAPI.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"
+
#include "php_apache.h"
-static request_rec *php_lookup_uri(INTERNAL_FUNCTION_PARAMETERS)
+static request_rec *php_apache_lookup_uri(INTERNAL_FUNCTION_PARAMETERS)
{
zval **p1;
php_struct *ctx;
{
request_rec *rr;
- rr = php_lookup_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ rr = php_apache_lookup_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU);
if (!rr)
- WRONG_NUM_ARGS;
+ WRONG_PARAM_COUNT;
if (rr->status == HTTP_OK) {
ap_run_sub_req(rr);
#define ADD_LONG(name) \
add_assoc_long(return_value, #name, rr->name)
#define ADD_STRING(name) \
- add_assoc_string(return_value, #name, rr->name, 1)
+ if (rr->name) add_assoc_string(return_value, #name, (char *) rr->name, 1)
PHP_FUNCTION(apache_lookup_uri)
{
rr = php_apache_lookup_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU);
if (!rr)
- WRONG_NUM_ARGS;
+ WRONG_PARAM_COUNT;
if (rr->status == HTTP_OK) {
array_init(return_value);
ADD_LONG(clength);
ADD_STRING(boundary);
ADD_STRING(range);
- ADD_LONG(byterange);
ADD_LONG(chunked);
ADD_STRING(content_type);
ADD_STRING(handler);
}
RETURN_FALSE;
}
+
+PHP_FUNCTION(get_all_headers)
+{
+ php_struct *ctx;
+ apr_array_header_t *arr;
+ char *key, *val;
+ SLS_FETCH();
+
+ if (array_init(return_value) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ ctx = SG(server_context);
+ arr = apr_table_elts(ctx->f->r->headers_in);
+
+ APR_ARRAY_FOREACH_OPEN(arr, key, val)
+ if (!val) val = empty_string;
+ add_assoc_string(return_value, key, val, 1);
+ APR_ARRAY_FOREACH_CLOSE()
+}
+
+PHP_MINFO_FUNCTION(apache)
+{
+}
+
+static function_entry apache_functions[] = {
+ PHP_FE(apache_lookup_uri, NULL)
+ PHP_FE(apache_sub_req, NULL)
+ PHP_FE(get_all_headers, NULL)
+ {0}
+};
+
+static zend_module_entry php_apache_module = {
+ "Apache 2.0",
+ apache_functions,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ PHP_MINFO(apache),
+ STANDARD_MODULE_PROPERTIES
+};
+
+int php_apache_register_module(void)
+{
+ return zend_startup_module(&php_apache_module);
+}
ctx = SG(server_context);
+ if (!str_length) return 0;
+
bb = ap_brigade_create(ctx->f->r->pool);
while (str_length > 0) {
now = MIN(str_length, 4096);
{
php_struct *ctx = SG(server_context);
apr_array_header_t *arr = apr_table_elts(ctx->f->r->subprocess_env);
- apr_table_entry_t *elts = (apr_table_entry_t *) arr->elts;
- int i;
- char *val;
-
- for (i = 0; i < arr->nelts; i++) {
- if (!(val = elts[i].val))
- val = empty_string;
-
- php_register_variable(elts[i].key, val, track_vars_array ELS_CC PLS_CC);
- }
+ char *key, *val;
+ APR_ARRAY_FOREACH_OPEN(arr, key, val)
+ if (!val) val = empty_string;
+ php_register_variable(key, val, track_vars_array ELS_CC PLS_CC);
+ APR_ARRAY_FOREACH_CLOSE()
+
php_register_variable("PHP_SELF", ctx->f->r->uri, track_vars_array ELS_CC PLS_CC);
}
return APR_SUCCESS;
}
+static void php_apache_request_ctor(ap_filter_t *f, php_struct *ctx SLS_DC)
+{
+ char *content_type;
+ const char *auth;
+ CLS_FETCH();
+ ELS_FETCH();
+ PLS_FETCH();
+
+ PG(during_request_startup) = 0;
+ SG(sapi_headers).http_response_code = 200;
+ SG(request_info).content_type = apr_table_get(f->r->headers_in, "Content-Type");
+#undef safe_strdup
+#define safe_strdup(x) ((x)?strdup((x)):NULL)
+ SG(request_info).query_string = safe_strdup(f->r->args);
+ SG(request_info).request_method = f->r->method;
+ SG(request_info).request_uri = safe_strdup(f->r->uri);
+ f->r->no_local_copy = 1;
+ content_type = sapi_get_default_content_type(SLS_C);
+ f->r->content_type = apr_pstrdup(f->r->pool, content_type);
+ SG(request_info).post_data = ctx->post_data;
+ SG(request_info).post_data_length = ctx->post_len;
+ efree(content_type);
+ apr_table_unset(f->r->headers_out, "Content-Length");
+ apr_table_unset(f->r->headers_out, "Last-Modified");
+ apr_table_unset(f->r->headers_out, "Expires");
+ apr_table_unset(f->r->headers_out, "ETag");
+ apr_table_unset(f->r->headers_in, "Connection");
+ auth = apr_table_get(f->r->headers_in, "Authorization");
+ php_handle_auth_data(auth SLS_CC);
+
+ php_request_startup(CLS_C ELS_CC PLS_CC SLS_CC);
+}
+
+static void php_apache_request_dtor(ap_filter_t *f SLS_DC)
+{
+ php_request_shutdown(NULL);
+
+#undef safe_free
+#define safe_free(x) ((x)?free((x)):0)
+ safe_free(SG(request_info).query_string);
+ safe_free(SG(request_info).request_uri);
+}
+
static int php_output_filter(ap_filter_t *f, ap_bucket_brigade *bb)
{
php_struct *ctx;
* 2: script execution and request shutdown
*/
if (ctx->state == 0) {
- char *content_type;
- const char *auth;
- CLS_FETCH();
- ELS_FETCH();
- PLS_FETCH();
- SLS_FETCH();
apply_config(conf);
ctx->state++;
- /* XXX: Lots of startup crap. Should be moved into its own func */
- PG(during_request_startup) = 0;
- SG(sapi_headers).http_response_code = 200;
- SG(request_info).content_type = apr_table_get(f->r->headers_in, "Content-Type");
- SG(request_info).query_string = f->r->args;
- SG(request_info).request_method = f->r->method;
- SG(request_info).request_uri = f->r->uri;
- f->r->no_local_copy = 1;
- content_type = sapi_get_default_content_type(SLS_C);
- f->r->content_type = apr_pstrdup(f->r->pool, content_type);
- efree(content_type);
- apr_table_unset(f->r->headers_out, "Content-Length");
- apr_table_unset(f->r->headers_out, "Last-Modified");
- apr_table_unset(f->r->headers_out, "Expires");
- apr_table_unset(f->r->headers_out, "ETag");
- apr_table_unset(f->r->headers_in, "Connection");
- auth = apr_table_get(f->r->headers_in, "Authorization");
- php_handle_auth_data(auth SLS_CC);
-
- php_request_startup(CLS_C ELS_CC PLS_CC SLS_CC);
+ php_apache_request_ctor(f, ctx SLS_CC);
}
/* moves all buckets from bb to ctx->bb */
eos = ap_bucket_create_transient(NO_DATA, sizeof(NO_DATA)-1);
AP_BRIGADE_INSERT_HEAD(bb, eos);
ok:
- php_request_shutdown(NULL);
+ php_apache_request_dtor(f SLS_CC);
SG(server_context) = 0;
/* Pass EOS bucket to next filter to signal end of request */
sapi_startup(&sapi_module);
sapi_module.startup(&sapi_module);
apr_register_cleanup(pchild, NULL, php_apache_server_shutdown, NULL);
+ php_apache_register_module();
}
static void php_register_hook(void)