Skip to content

Instantly share code, notes, and snippets.

@adsr
Created September 10, 2015 17:06
Show Gist options
  • Select an option

  • Save adsr/7a935428912c0799d083 to your computer and use it in GitHub Desktop.

Select an option

Save adsr/7a935428912c0799d083 to your computer and use it in GitHub Desktop.
diff --git a/sapi/apache2handler/php_apache.h b/sapi/apache2handler/php_apache.h
index d0673e1..6b99703 100644
--- a/sapi/apache2handler/php_apache.h
+++ b/sapi/apache2handler/php_apache.h
@@ -46,6 +46,7 @@ typedef struct php_struct {
int request_processed;
/* final content type */
char *content_type;
+ int request_startup_ran;
} php_struct;
void *merge_php_config(apr_pool_t *p, void *base_conf, void *new_conf);
diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c
index 840c550..cae6aec 100644
--- a/sapi/apache2handler/sapi_apache2.c
+++ b/sapi/apache2handler/sapi_apache2.c
@@ -472,6 +472,7 @@ static int php_apache_request_ctor(request_rec *r, php_struct *ctx TSRMLS_DC)
{
char *content_length;
const char *auth;
+ int rv;
SG(sapi_headers).http_response_code = !r->status ? HTTP_OK : r->status;
SG(request_info).content_type = apr_table_get(r->headers_in, "Content-Type");
@@ -499,7 +500,13 @@ static int php_apache_request_ctor(request_rec *r, php_struct *ctx TSRMLS_DC)
ctx->r->user = apr_pstrdup(ctx->r->pool, SG(request_info).auth_user);
- return php_request_startup(TSRMLS_C);
+ if (ctx->request_startup_ran) {
+ return SUCCESS;
+ }
+
+ rv = php_request_startup(TSRMLS_C);
+ ctx->request_startup_ran = 1;
+ return rv;
}
static void php_apache_request_dtor(request_rec *r TSRMLS_DC)
@@ -541,6 +548,7 @@ static int php_handler(request_rec *r)
apr_bucket *bucket;
apr_status_t rv;
request_rec * volatile parent_req = NULL;
+ int request_startup_ran;
TSRMLS_FETCH();
#define PHPAP_INI_OFF php_apache_ini_dtor(r, parent_req TSRMLS_CC);
@@ -549,9 +557,14 @@ static int php_handler(request_rec *r)
/* apply_config() needs r in some cases, so allocate server_context early */
ctx = SG(server_context);
- if (ctx == NULL || (ctx && ctx->request_processed && !strcmp(r->protocol, "INCLUDED"))) {
+ if (ctx == NULL
+ || (ctx && ctx->request_processed && !strcmp(r->protocol, "INCLUDED"))
+ || (ctx && ctx->request_startup_ran)
+ ) {
normal:
+ request_startup_ran = ctx ? ctx->request_startup_ran : 0;
ctx = SG(server_context) = apr_pcalloc(r->pool, sizeof(*ctx));
+ ctx->request_startup_ran = request_startup_ran;
/* register a cleanup so we clear out the SG(server_context)
* after each request. Note: We pass in the pointer to the
* server_context in case this is handled by a different thread.
@@ -696,9 +709,35 @@ zend_first_try {
return OK;
}
+static request_rec *fake_request_rec(server_rec* s, apr_pool_t* p)
+{
+ request_rec* r = apr_pcalloc(p, sizeof(request_rec));
+ r->pool = p;
+ r->server = s;
+ r->headers_in = apr_table_make(r->pool, 25);
+ r->headers_out = apr_table_make(r->pool, 12);
+ return r;
+}
+
static void php_apache_child_init(apr_pool_t *pchild, server_rec *s)
{
+ php_struct* ctx;
+ zend_file_handle zfd;
apr_pool_cleanup_register(pchild, NULL, php_apache_child_shutdown, apr_pool_cleanup_null);
+
+ TSRMLS_FETCH();
+ ctx = SG(server_context) = apr_pcalloc(pchild, sizeof(*ctx));
+ apr_pool_cleanup_register(pchild, (void *)&SG(server_context), php_server_context_cleanup, apr_pool_cleanup_null);
+
+ ctx->r = fake_request_rec(s, pchild);
+ php_request_startup(TSRMLS_C);
+ ctx->request_startup_ran = 1;
+
+ zfd.type = ZEND_HANDLE_FILENAME;
+ zfd.filename = (char *)"/home/adam/mod_uuid/init.php";
+ zfd.free_filename = 0;
+ zfd.opened_path = NULL;
+ php_execute_script(&zfd TSRMLS_CC);
}
void php_ap2_register_hook(apr_pool_t *p)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment