This is the updated patch.
* Remove check for SECURITY_HOLE_PASS_AUTHORIZATION, since we are
not CGI and can always skip these headers.
* The optimization is only done for main request now. We check for
r->main (sub-request) and r->prev (internal redirect, like on
ErrorDocument). If either one of those is set, we call Apache
functions to populate the subprocess environment.
-Andrei
? sapi/apache/.libs
Index: sapi/apache/mod_php5.c
===================================================================
RCS file: /repository/php-src/sapi/apache/mod_php5.c,v
retrieving revision 1.19.2.6
diff -p -u -r1.19.2.6 mod_php5.c
--- sapi/apache/mod_php5.c 15 Feb 2006 11:09:05 -0000 1.19.2.6
+++ sapi/apache/mod_php5.c 18 Mar 2006 00:34:47 -0000
@@ -93,6 +93,207 @@ static void php_save_umask(void)
}
/* }}} */
+static char *php_http2env(pool *a, char *w)
+{
+ char *res = ap_pstrcat(a, "HTTP_", w, NULL);
+ char *cp = res;
+
+ while (*++cp) {
+ if (!ap_isalnum(*cp) && *cp != '_') {
+ *cp = '_';
+ }
+ else {
+ *cp = ap_toupper(*cp);
+ }
+ }
+
+ return res;
+}
+
+static char *php_original_uri(request_rec *r)
+{
+ char *first, *last;
+
+ if (r->the_request == NULL) {
+ return (char *) ap_pcalloc(r->pool, 1);
+ }
+
+ first = r->the_request; /* use the request-line */
+
+ while (*first && !ap_isspace(*first)) {
+ ++first; /* skip over the method */
+ }
+ while (ap_isspace(*first)) {
+ ++first; /* and the space(s) */
+ }
+
+ last = first;
+ while (*last && !ap_isspace(*last)) {
+ ++last; /* end at next whitespace */
+ }
+
+ return ap_pstrndup(r->pool, first, last - first);
+}
+
+static void php_populate_subprocess_env(request_rec *r)
+{
+ table *e;
+ server_rec *s = r->server;
+ conn_rec *c = r->connection;
+ const char *rem_logname;
+ char *env_path;
+#if defined(PHP_WIN32) || defined(OS2)
+ char *env_temp;
+#endif
+ const char *host;
+ array_header *hdrs_arr = ap_table_elts(r->headers_in);
+ table_entry *hdrs = (table_entry *) hdrs_arr->elts;
+ int i;
+
+ e = r->subprocess_env;
+
+ /* First, add environment vars from headers... this is as per
+ * CGI specs, though other sorts of scripting interfaces see
+ * the same vars...
+ */
+
+ ap_table_setn(e, "REQUEST_METHOD", r->method);
+
+ for (i = 0; i < hdrs_arr->nelts; ++i) {
+ if (!hdrs[i].key) {
+ continue;
+ }
+
+ /* A few headers are special cased --- Authorization to prevent
+ * rogue scripts from capturing passwords; content-type and
-length
+ * for no particular reason.
+ */
+
+ if (!strcasecmp(hdrs[i].key, "Content-type")) {
+ ap_table_addn(e, "CONTENT_TYPE", hdrs[i].val);
+ }
+ else if (!strcasecmp(hdrs[i].key, "Content-length")) {
+ ap_table_addn(e, "CONTENT_LENGTH", hdrs[i].val);
+ }
+ /*
+ * You really don't want to disable this check, since it leaves
you
+ * wide open to CGIs stealing passwords and people viewing them
+ * in the environment with "ps -e". But, if you must...
+ */
+ else if (!strcasecmp(hdrs[i].key, "Authorization")
+ || !strcasecmp(hdrs[i].key,
"Proxy-Authorization")) {
+ continue;
+ }
+ else {
+ ap_table_addn(e, php_http2env(r->pool, hdrs[i].key),
hdrs[i].val);
+ }
+ }
+
+ if (!(env_path = ap_pstrdup(r->pool, getenv("PATH")))) {
+ env_path = DEFAULT_PATH;
+ }
+
+#ifdef PHP_WIN32
+ if (env_temp = getenv("SystemRoot")) {
+ ap_table_addn(e, "SystemRoot", env_temp);
+ }
+ if (env_temp = getenv("COMSPEC")) {
+ ap_table_addn(e, "COMSPEC", env_temp);
+ }
+ if (env_temp = getenv("WINDIR")) {
+ ap_table_addn(e, "WINDIR", env_temp);
+ }
+#endif
+
+#ifdef OS2
+ if ((env_temp = getenv("COMSPEC")) != NULL) {
+ ap_table_addn(e, "COMSPEC", env_temp);
+ }
+ if ((env_temp = getenv("ETC")) != NULL) {
+ ap_table_addn(e, "ETC", env_temp);
+ }
+ if ((env_temp = getenv("DPATH")) != NULL) {
+ ap_table_addn(e, "DPATH", env_temp);
+ }
+ if ((env_temp = getenv("PERLLIB_PREFIX")) != NULL) {
+ ap_table_addn(e, "PERLLIB_PREFIX", env_temp);
+ }
+#endif
+
+ ap_table_addn(e, "PATH", env_path);
+ ap_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
+ ap_table_addn(e, "SERVER_SOFTWARE", ap_get_server_version());
+ ap_table_addn(e, "SERVER_NAME",
+
ap_escape_html(r->pool,ap_get_server_name(r)));
+ ap_table_addn(e, "SERVER_ADDR", r->connection->local_ip); /*
Apache */
+ ap_table_addn(e, "SERVER_PORT",
+ ap_psprintf(r->pool, "%u",
ap_get_server_port(r)));
+ host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST);
+ if (host) {
+ ap_table_addn(e, "REMOTE_HOST", host);
+ }
+ ap_table_addn(e, "REMOTE_ADDR", c->remote_ip);
+ ap_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r)); /* Apache */
+ ap_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
+ ap_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */
+
+ ap_table_addn(e, "REMOTE_PORT",
+ ap_psprintf(r->pool, "%d",
ntohs(c->remote_addr.sin_port)));
+
+ if (c->user) {
+ ap_table_addn(e, "REMOTE_USER", c->user);
+ }
+ if (c->ap_auth_type) {
+ ap_table_addn(e, "AUTH_TYPE", c->ap_auth_type);
+ }
+ rem_logname = ap_get_remote_logname(r);
+ if (rem_logname) {
+ ap_table_addn(e, "REMOTE_IDENT", ap_pstrdup(r->pool,
rem_logname));
+ }
+
+ /* Apache custom error responses. If we have redirected set two new
vars */
+
+ if (r->prev) {
+ if (r->prev->args) {
+ ap_table_addn(e, "REDIRECT_QUERY_STRING",
r->prev->args);
+ }
+ if (r->prev->uri) {
+ ap_table_addn(e, "REDIRECT_URL", r->prev->uri);
+ }
+ }
+
+ ap_table_addn(e, "GATEWAY_INTERFACE", "CGI/1.1");
+ ap_table_addn(e, "SERVER_PROTOCOL", r->protocol);
+ ap_table_addn(e, "QUERY_STRING", r->args ? r->args : "");
+ ap_table_addn(e, "REQUEST_URI", php_original_uri(r));
+
+ /* Note that the code below special-cases scripts run from includes,
+ * because it "knows" that the sub_request has been hacked to have the
+ * args and path_info of the original request, and not any that may have
+ * come with the script URI in the include command. Ugh.
+ */
+
+ if (!strcmp(r->protocol, "INCLUDED")) {
+ ap_table_addn(e, "SCRIPT_NAME", r->uri);
+ if (r->path_info && *r->path_info) {
+ ap_table_setn(e, "PATH_INFO", r->path_info);
+ }
+ }
+ else if (!r->path_info || !*r->path_info) {
+ ap_table_addn(e, "SCRIPT_NAME", r->uri);
+ }
+ else {
+ int path_info_start = ap_find_path_info(r->uri, r->path_info);
+
+ ap_table_addn(e, "SCRIPT_NAME",
+ ap_pstrndup(r->pool, r->uri,
path_info_start));
+
+ ap_table_addn(e, "PATH_INFO", r->path_info);
+ }
+
+ ap_table_addn(e, "PATH_TRANSLATED", r->filename);
+}
+
/* {{{ sapi_apache_ub_write
*/
static int sapi_apache_ub_write(const char *str, uint str_length TSRMLS_DC)
@@ -263,6 +464,7 @@ static void sapi_apache_register_server_
php_register_variable(elts[i].key, val, track_vars_array
TSRMLS_CC);
}
+#if 0
/* If PATH_TRANSLATED doesn't exist, copy it from SCRIPT_FILENAME */
if (track_vars_array) {
symbol_table = track_vars_array->value.ht;
@@ -277,6 +479,7 @@ static void sapi_apache_register_server_
&& zend_hash_find(symbol_table, "SCRIPT_FILENAME",
sizeof("SCRIPT_FILENAME"), (void **) &path_translated)==SUCCESS) {
php_register_variable("PATH_TRANSLATED",
Z_STRVAL_PP(path_translated), track_vars_array TSRMLS_CC);
}
+#endif
php_register_variable("PHP_SELF", ((request_rec *)
SG(server_context))->uri, track_vars_array TSRMLS_CC);
}
@@ -655,8 +858,18 @@ static int send_php(request_rec *r, int
SG(server_context) = r;
php_save_umask();
- add_common_vars(r);
- add_cgi_vars(r);
+
+ /*
+ * If this is a sub-request, or an internal redirect, the
+ * r->subprocess_env is already populated, so we cannot rely on
it being
+ * empty and need to call original Apache functions to add
stuff.
+ */
+ if (r->main || r->prev) {
+ add_common_vars(r);
+ add_cgi_vars(r);
+ } else {
+ php_populate_subprocess_env(r);
+ }
init_request_info(TSRMLS_C);
apache_php_module_main(r, display_source_mode TSRMLS_CC);
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php