hi,

attached is a first request for comment for an update to the
apache_hooks code.


a php-handler for uri translation looks like this ($request is of type
ApacheRequest).

<?php

  $request->uri('/s.html');
  return DECLINED;
?>


a php-handler for uri-to-filename translation would look like this.

<?php

  $request->filename('/tmp/foo.html');
  return OK;
?>


the patch is intended for peer review only.



regards,
  -lukas

Index: sapi/apache/mod_php4.c
===================================================================
RCS file: /repository/php4/sapi/apache/mod_php4.c,v
retrieving revision 1.138
diff -u -r1.138 mod_php4.c
--- sapi/apache/mod_php4.c      19 Aug 2002 15:52:21 -0000      1.138
+++ sapi/apache/mod_php4.c      22 Aug 2002 11:55:48 -0000
@@ -34,6 +34,7 @@
 /* {{{ Prototypes
  */
 int apache_php_module_main(request_rec *r, int display_source_mode TSRMLS_DC);
+int apache_php_module_hook(request_rec *r, char *filename, zval **ret TSRMLS_DC);
 void php_save_umask(void);
 void php_restore_umask(void);
 int sapi_apache_read_post(char *buffer, uint count_bytes TSRMLS_DC);
@@ -835,6 +836,40 @@
 }
 /* }}} */
 
+static int php_uri_translation(request_rec *r)
+{
+       char *handler = NULL;
+       zval *ret = NULL;
+       HashTable *conf;
+       TSRMLS_FETCH();
+
+       if (!AP(apache_config_loaded)) {
+               conf = (HashTable *) get_module_config(r->per_dir_config, 
+&php4_module);
+               if (conf)
+                       zend_hash_apply((HashTable *)conf, (apply_func_t) 
+php_apache_alter_ini_entries TSRMLS_CC);
+               AP(apache_config_loaded) = 1;
+       }
+
+       handler = AP(uri_handler);
+
+       if (!handler)
+               return DECLINED;
+
+       hard_timeout("send", r);
+       SG(server_context) = r;
+       php_save_umask();
+       add_common_vars(r);
+       add_cgi_vars(r);
+       init_request_info(TSRMLS_C);
+       apache_php_module_hook(r, handler, &ret TSRMLS_CC);
+       php_restore_umask();
+       kill_timeout(r);
+
+       convert_to_long(ret);
+       fprintf(stderr, "%s() %d\n", __FUNCTION__, Z_LVAL_P(ret));
+       return Z_LVAL_P(ret);
+}
+
 /* {{{ handler_rec php_handlers[]
  */
 handler_rec php_handlers[] =
@@ -870,7 +905,7 @@
        NULL,                                           /* merge server config */
        php_commands,                           /* command table */
        php_handlers,                           /* handlers */
-       NULL,                                           /* filename translation */
+       php_uri_translation,            /* filename translation */
        NULL,                                           /* check_user_id */
        NULL,                                           /* check auth */
        NULL,                                           /* check access */
Index: sapi/apache/mod_php4.h
===================================================================
RCS file: /repository/php4/sapi/apache/mod_php4.h,v
retrieving revision 1.17
diff -u -r1.17 mod_php4.h
--- sapi/apache/mod_php4.h      28 Feb 2002 08:27:19 -0000      1.17
+++ sapi/apache/mod_php4.h      22 Aug 2002 11:55:48 -0000
@@ -32,6 +32,8 @@
        long xbithack;
        long terminate_child;
        zend_bool in_request;
+       zend_bool apache_config_loaded;
+       char *uri_handler;
 } php_apache_info_struct;
 
 extern zend_module_entry apache_module_entry;
Index: sapi/apache/php_apache.c
===================================================================
RCS file: /repository/php4/sapi/apache/php_apache.c,v
retrieving revision 1.66
diff -u -r1.66 php_apache.c
--- sapi/apache/php_apache.c    13 Aug 2002 04:03:20 -0000      1.66
+++ sapi/apache/php_apache.c    22 Aug 2002 11:55:48 -0000
@@ -37,6 +37,11 @@
 #define SECTION(name)  PUTS("<H2 align=\"center\">" name "</H2>\n")
 
 extern module *top_module;
+static int le_apachereq;
+static zend_class_entry *apacherequest_class_entry;
+
+#define SLOT_URI 0
+#define SLOT_FILENAME 1
 
 PHP_FUNCTION(virtual);
 PHP_FUNCTION(apache_request_headers);
@@ -49,6 +54,7 @@
 
 PHP_MINFO_FUNCTION(apache);
 
+
 function_entry apache_functions[] = {
        PHP_FE(virtual,                                                                
 NULL)
        PHP_FE(apache_request_headers,                                  NULL)
@@ -61,15 +67,17 @@
        {NULL, NULL, NULL}
 };
 
-
+/* {{{ php_apache ini entries
+ */
 PHP_INI_BEGIN()
        STD_PHP_INI_ENTRY("xbithack",                   "0",                           
 PHP_INI_ALL,            OnUpdateInt,            xbithack, php_apache_info_struct, 
php_apache_info)
        STD_PHP_INI_ENTRY("engine",                             "1",                   
         PHP_INI_ALL,            OnUpdateInt,            engine, 
php_apache_info_struct, php_apache_info)
        STD_PHP_INI_ENTRY("last_modified",              "0",                           
 PHP_INI_ALL,            OnUpdateInt,            last_modified, 
php_apache_info_struct, php_apache_info)
        STD_PHP_INI_ENTRY("child_terminate",    "0",                            
PHP_INI_ALL,            OnUpdateInt,            terminate_child, 
php_apache_info_struct, php_apache_info)
-PHP_INI_END()
-
+       STD_PHP_INI_ENTRY("uri_handler",                NULL,                          
+ PHP_INI_ALL,            OnUpdateString,         uri_handler, php_apache_info_struct, 
+php_apache_info)
 
+PHP_INI_END()
+/* }}} */
 
 static void php_apache_globals_ctor(php_apache_info_struct *apache_globals TSRMLS_DC)
 {
@@ -77,14 +85,175 @@
 }
 
 
+#define APREQ_GET_THIS(ZVAL)           if (NULL == (ZVAL = getThis())) { \
+                                                                               
+php_error(E_WARNING, "%s(): underlying ApacheRequest object missing", \
+                                                                                      
+ get_active_function_name(TSRMLS_C)); \
+                                                                               
+RETURN_FALSE; \
+                                                                       }
+#define APREQ_GET_REQUEST(ZVAL, R)     APREQ_GET_THIS(ZVAL); \
+                                                                       R = 
+get_apache_request(ZVAL)
+
+static void php_apache_request_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+       zval *z = (zval *)rsrc->ptr;
+       fprintf(stderr, "%s() %p\n", __FUNCTION__, z);
+       zval_ptr_dtor(&z);
+}
+
+static request_rec *get_apache_request(zval *z)
+{
+       request_rec *r;
+       zval **addr;
+
+       if (NULL == z) {
+               php_error(E_WARNING, "get_apache_request() invalid wrapper passed");
+               return NULL;
+       }
+
+       if (Z_TYPE_P(z) != IS_OBJECT) {
+               php_error(E_WARNING, "%s(): wrapper is not an object", 
+get_active_function_name(TSRMLS_C));
+               return NULL;
+       }
+
+       if (zend_hash_index_find(Z_OBJPROP_P(z), 0, (void **)&addr) == FAILURE) {
+               php_error(E_WARNING, "%s(): underlying object missing", 
+get_active_function_name(TSRMLS_C));
+               return NULL;
+       }
+
+       r = (request_rec *)Z_LVAL_PP(addr);
+       if (!r) {
+               php_error(E_WARNING, "%s(): request_rec invalid", 
+get_active_function_name(TSRMLS_C));
+               return NULL;
+       }
+
+       return r;
+}
+
+/* {{{
+ */
+PHPAPI zval *php_apache_request_new(request_rec *r)
+{
+       zval *req;
+       zval *addr, *handle;
+
+       MAKE_STD_ZVAL(addr);
+       Z_TYPE_P(addr) = IS_LONG;
+       Z_LVAL_P(addr) = (int) r;
+
+       MAKE_STD_ZVAL(req);
+       object_init_ex(req, apacherequest_class_entry);
+       zend_hash_index_update(Z_OBJPROP_P(req), 0, &addr, sizeof(zval *), NULL);
+
+//     MAKE_STD_ZVAL(handle);
+//     Z_TYPE_P(handle) = IS_LONG;
+//     Z_LVAL_P(handle) = zend_list_insert(req, le_apachereq);
+//     zend_hash_index_update(Z_OBJPROP_P(req), 1, &handle, sizeof(zval *), NULL);
+
+       return req;
+}
+/* }}} */
+
+/* {{{ apache_request_string_slot()
+ */
+static void apache_request_string_slot(int type, INTERNAL_FUNCTION_PARAMETERS)
+{
+       zval *id, **new_value;
+       request_rec *r;
+       char *old_value;
+       char **target;
+
+       APREQ_GET_REQUEST(id, r);
+
+       switch (type) {
+               case SLOT_URI:
+                       target = &r->uri;
+                       break;
+               case SLOT_FILENAME:
+               default:
+                       target = &r->filename;
+                       break;
+       }
+
+       old_value = *target;
+
+       switch (ZEND_NUM_ARGS()) {
+               case 0:
+                       break;
+               case 1:
+                       if (zend_get_parameters_ex(1, &new_value) == FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_string_ex(new_value);
+                       *target = ap_pstrdup(r->pool, Z_STRVAL_PP(new_value));
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       if (old_value) {
+               RETURN_STRING(old_value, 1);
+       }
+       else {
+               RETURN_EMPTY_STRING();
+       }
+}
+/* }}} */
+
+/* {{{ proto string $request->filename([string new_filename])
+ */
+PHP_FUNCTION(apache_request_filename)
+{
+       apache_request_string_slot(SLOT_FILENAME, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+/* }}} */
+
+/* {{{ proto string $request->uri([string new_uri])
+ */
+PHP_FUNCTION(apache_request_uri)
+{
+       apache_request_string_slot(SLOT_URI, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+/* }}} */
+
+
+/* {{{ php_apache_request_class_functions
+ */
+static function_entry php_apache_request_class_functions[] = {
+       PHP_FALIAS(filename,                                    
+apache_request_filename,                NULL)
+       PHP_FALIAS(uri,                                                 
+apache_request_uri,                             NULL)
+
+       { NULL, NULL, NULL }
+};
+/* }}} */
+
+
 static PHP_MINIT_FUNCTION(apache)
 {
+       zend_class_entry ce;
+
 #ifdef ZTS
        ts_allocate_id(&php_apache_info_id, sizeof(php_apache_info_struct), 
(ts_allocate_ctor) php_apache_globals_ctor, NULL);
 #else
        php_apache_globals_ctor(&php_apache_info TSRMLS_CC);
 #endif
        REGISTER_INI_ENTRIES();
+
+
+       le_apachereq = zend_register_list_destructors_ex(php_apache_request_free, 
+NULL, "ApacheRequest", module_number);
+       INIT_OVERLOADED_CLASS_ENTRY(ce, "ApacheRequest", 
+php_apache_request_class_functions, NULL, NULL, NULL);
+       apacherequest_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL 
+TSRMLS_CC);
+
+       REGISTER_LONG_CONSTANT("OK",                            OK,                    
+                 CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("DECLINED",                      DECLINED,              
+         CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("DONE",                          DONE,                  
+         CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("SERVER_ERROR",          SERVER_ERROR,           
+CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("REDIRECT",                      REDIRECT,              
+         CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("BAD_REQUEST",           BAD_REQUEST,            
+CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("NOT_FOUND",                     NOT_FOUND,             
+         CONST_CS | CONST_PERSISTENT);
+
        return SUCCESS;
 }
 
Index: sapi/apache/php_apache_http.h
===================================================================
RCS file: /repository/php4/sapi/apache/php_apache_http.h,v
retrieving revision 1.3
diff -u -r1.3 php_apache_http.h
--- sapi/apache/php_apache_http.h       31 May 2002 04:47:19 -0000      1.3
+++ sapi/apache/php_apache_http.h       22 Aug 2002 11:55:48 -0000
@@ -36,3 +36,7 @@
 #include "ext/standard/php_standard.h"
 
 #include "mod_php4.h"
+
+
+PHPAPI zval *php_apache_request_new(request_rec *r);
+
Index: sapi/apache/sapi_apache.c
===================================================================
RCS file: /repository/php4/sapi/apache/sapi_apache.c,v
retrieving revision 1.40
diff -u -r1.40 sapi_apache.c
--- sapi/apache/sapi_apache.c   23 Apr 2002 03:01:30 -0000      1.40
+++ sapi/apache/sapi_apache.c   22 Aug 2002 11:55:48 -0000
@@ -65,6 +65,45 @@
 }
 /* }}} */
 
+/* {{{ apache_php_module_hook
+ */
+int apache_php_module_hook(request_rec *r, char *filename, zval **ret TSRMLS_DC)
+{
+       zend_file_handle file_handle;
+       zval *req;
+
+#if PHP_SIGCHILD
+       signal(SIGCHLD, sigchld_handler);
+#endif
+
+       if (php_request_startup_for_hook(TSRMLS_C) == FAILURE)
+               return FAILURE;
+
+       /* Add PHP_SELF_HOOK - Absolute path */
+       php_register_variable("PHP_SELF_HOOK", filename, 
+PG(http_globals)[TRACK_VARS_SERVER] TSRMLS_CC);
+
+       req = php_apache_request_new(r);
+       php_register_variable_ex("request", req, NULL TSRMLS_CC);
+
+
+       memset(&file_handle, 0, sizeof(file_handle));
+       file_handle.type = ZEND_HANDLE_FILENAME;
+       file_handle.filename = filename;
+
+       (void) php_execute_simple_script(&file_handle, ret TSRMLS_CC);
+
+       AP(in_request) = 0;
+
+       zend_try {
+               php_request_shutdown_for_hook(NULL);
+       } zend_end_try();
+
+       return OK;
+}
+
+/* }}} */
+
+
 /*
  * Local variables:
  * tab-width: 4

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to