You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_python-commits@quetz.apache.org by gr...@apache.org on 2006/08/14 14:07:47 UTC

svn commit: r431327 - in /httpd/mod_python/trunk: Doc/ lib/python/mod_python/ src/ src/include/

Author: grahamd
Date: Mon Aug 14 05:07:46 2006
New Revision: 431327

URL: http://svn.apache.org/viewvc?rev=431327&view=rev
Log:
When handler directives are used within Directory or DirectoryMatch
directives where wildcards or regular expressions are used, the handler
directory will now be correctly set to the shortest directory matched by
the directory pattern, whereas previously it was being left as the
pattern which meant that modules located with that directory weren't
able to be loaded.


Modified:
    httpd/mod_python/trunk/Doc/appendixc.tex
    httpd/mod_python/trunk/lib/python/mod_python/__init__.py
    httpd/mod_python/trunk/src/filterobject.c
    httpd/mod_python/trunk/src/hlist.c
    httpd/mod_python/trunk/src/hlistobject.c
    httpd/mod_python/trunk/src/include/hlist.h
    httpd/mod_python/trunk/src/include/hlistobject.h
    httpd/mod_python/trunk/src/include/mod_python.h
    httpd/mod_python/trunk/src/include/mod_python.h.in
    httpd/mod_python/trunk/src/include/mpversion.h
    httpd/mod_python/trunk/src/mod_python.c
    httpd/mod_python/trunk/src/requestobject.c

Modified: httpd/mod_python/trunk/Doc/appendixc.tex
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/Doc/appendixc.tex?rev=431327&r1=431326&r2=431327&view=diff
==============================================================================
--- httpd/mod_python/trunk/Doc/appendixc.tex (original)
+++ httpd/mod_python/trunk/Doc/appendixc.tex Mon Aug 14 05:07:46 2006
@@ -381,6 +381,17 @@
       The original change to fix the symlink issue for \code{req.sendfile()}
       was causing problems on Win32, plus code needed to be changed to work
       with APR 1.2.7.
+    \item
+      (\citetitle[http://issues.apache.org/jira/browse/MODPYTHON-63]{MODPYTHON-63})
+      When handler directives are used within \code{Directory} or
+      \code{DirectoryMatch} directives where wildcards or regular
+      expressions are used, the handler directory will be set to the
+      shortest directory matched by the directory pattern. Handler
+      directives can now also be used within \code{Files} and
+      \code{FilesMatch} directives and the handler directory will correctly
+      resolve to the directory corresponding to the enclosing
+      \code{Directory} or \code{DirectoryMatch} directive, or the directory
+      the \code{.htaccess} file is contained in.
   \end{itemize}
 
 \chapter{Changes from Version (3.2.7)\label{app-changes-from-3.2.7}}

Modified: httpd/mod_python/trunk/lib/python/mod_python/__init__.py
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/lib/python/mod_python/__init__.py?rev=431327&r1=431326&r2=431327&view=diff
==============================================================================
--- httpd/mod_python/trunk/lib/python/mod_python/__init__.py (original)
+++ httpd/mod_python/trunk/lib/python/mod_python/__init__.py Mon Aug 14 05:07:46 2006
@@ -20,5 +20,5 @@
 __all__ = ["apache", "cgihandler", "psp",
            "publisher", "util", "python22"]
 
-version = "3.3.0-dev-20060813"
+version = "3.3.0-dev-20060814"
 

Modified: httpd/mod_python/trunk/src/filterobject.c
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/filterobject.c?rev=431327&r1=431326&r2=431327&view=diff
==============================================================================
--- httpd/mod_python/trunk/src/filterobject.c (original)
+++ httpd/mod_python/trunk/src/filterobject.c Mon Aug 14 05:07:46 2006
@@ -564,7 +564,7 @@
     }
     else if (strcmp(name, "parent") == 0) {
         if (self->parent) {
-            return MpHList_FromHLEntry(self->parent, 0);
+            return MpHList_FromHLEntry(self->parent);
         }
         else {
             Py_INCREF(Py_None);

Modified: httpd/mod_python/trunk/src/hlist.c
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/hlist.c?rev=431327&r1=431326&r2=431327&view=diff
==============================================================================
--- httpd/mod_python/trunk/src/hlist.c (original)
+++ httpd/mod_python/trunk/src/hlist.c Mon Aug 14 05:07:46 2006
@@ -41,9 +41,9 @@
 
     hle = (hl_entry *)apr_pcalloc(p, sizeof(hl_entry));
 
-    hle->handler = apr_pstrdup(p, h);
+    hle->handler = h;
     hle->callable = o;
-    hle->directory = apr_pstrdup(p, d);
+    hle->directory = d;
     hle->d_is_fnmatch = d_is_fnmatch;
     hle->regex = regex;
     hle->silent = s;
@@ -73,9 +73,9 @@
 
     nhle = (hl_entry *)apr_pcalloc(p, sizeof(hl_entry));
 
-    nhle->handler = apr_pstrdup(p, h);
+    nhle->handler = h;
     nhle->callable = o;
-    nhle->directory = apr_pstrdup(p, d);
+    nhle->directory = d;
     nhle->d_is_fnmatch = d_is_fnmatch;
     nhle->regex = regex;
     nhle->silent = s;
@@ -98,9 +98,9 @@
     hl_entry *head;
 
     head = (hl_entry *)apr_pcalloc(p, sizeof(hl_entry));
-    head->handler = apr_pstrdup(p, hle->handler);
+    head->handler = hle->handler;
     head->callable = hle->callable;
-    head->directory = apr_pstrdup(p, hle->directory);
+    head->directory = hle->directory;
     head->d_is_fnmatch = hle->d_is_fnmatch;
     head->regex = hle->regex;
     head->silent = hle->silent;
@@ -111,9 +111,9 @@
     while (hle) {
         nhle->next = (hl_entry *)apr_pcalloc(p, sizeof(hl_entry));
         nhle = nhle->next;
-        nhle->handler = apr_pstrdup(p, hle->handler);
+        nhle->handler = hle->handler;
         nhle->callable = hle->callable;
-        nhle->directory = apr_pstrdup(p, hle->directory);
+        nhle->directory = hle->directory;
         nhle->d_is_fnmatch = hle->d_is_fnmatch;
         nhle->regex = hle->regex;
         nhle->silent = hle->silent;
@@ -122,5 +122,34 @@
     }
 
     return head;
+}
+
+/**
+ ** hlist_extend
+ **
+ */
+
+void hlist_extend(apr_pool_t *p, hl_entry *hle1,
+                       const hl_entry *hle2)
+{
+    if (!hle2)
+        return;
+
+    /* find tail */
+    while (hle1 && hle1->next)
+        hle1 = hle1->next;
+
+    while (hle2) {
+        hle1->next = (hl_entry *)apr_pcalloc(p, sizeof(hl_entry));
+        hle1 = hle1->next;
+        hle1->handler = hle2->handler;
+        hle1->callable = hle2->callable;
+        hle1->directory = hle2->directory;
+        hle1->d_is_fnmatch = hle2->d_is_fnmatch;
+        hle1->regex = hle2->regex;
+        hle1->silent = hle2->silent;
+        hle1->parent = hle2->parent;
+        hle2 = hle2->next;
+    }
 }
 

Modified: httpd/mod_python/trunk/src/hlistobject.c
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/hlistobject.c?rev=431327&r1=431326&r2=431327&view=diff
==============================================================================
--- httpd/mod_python/trunk/src/hlistobject.c (original)
+++ httpd/mod_python/trunk/src/hlistobject.c Mon Aug 14 05:07:46 2006
@@ -33,74 +33,20 @@
  * new list from hl_entry
  */
 
-PyObject *MpHList_FromHLEntry(hl_entry *hle, int owner) 
+PyObject *MpHList_FromHLEntry(hl_entry *hle)
 {
     hlistobject *result;
-    apr_pool_t *p;
 
     result = PyObject_New(hlistobject, &MpHList_Type);
     if (! result) 
         PyErr_NoMemory();
 
-    if (owner) {
-	/* XXX need second arg abort function to report mem error */
-	apr_pool_create_ex(&p, NULL, NULL, NULL);
-
-	result->pool = p;
-	result->head = hlist_copy(p, hle);
-    }
-    else {
-	result->pool = NULL;
-	result->head = hle;
-    }
+    result->head = hle;
 
     return (PyObject *) result;
 }
 
 /**
- ** MpHlist_Append(hlistobject, hl_entry)
- **
- *  Append hl_entry to hlistobject, copying everything.
- */
-
-void MpHList_Append(hlistobject *self, hl_entry *hle)
-{
-    hl_entry *tail;
-
-    /* this function will never be called on objects
-     * which aren't the owner of the list, but protect
-     * against that case anyway as we don't have a
-     * pool to allocate data from when doing copy */
-    if (!self->pool)
-        return;
-
-    /* find tail */
-    for (tail = self->head; tail->next; tail=tail->next);
-
-    tail->next = hlist_copy(self->pool, hle);
-}
-
-/**
- ** MpHlist_Copy(hlistobject, hl_entry)
- **
- *  Append hl_entry to hlistobject, copying everything.
- */
-
-void MpHList_Copy(hlistobject *self, hl_entry *hle)
-{
-    hl_entry *tail;
-
-    /* this function will never be called on objects
-     * which aren't the owner of the list, but protect
-     * against that case anyway as we don't have a
-     * pool to allocate data from when doing copy */
-    if (!self->pool)
-        return;
-
-    self->head = hlist_copy(self->pool, hle);
-}
-
-/**
  ** hlist_next
  **
  */
@@ -133,8 +79,6 @@
 
 static void hlist_dealloc(hlistobject *self)
 {  
-    if (self->pool)
-        apr_pool_destroy(self->pool);
     PyObject_Del(self);
 }
 
@@ -173,7 +117,7 @@
     }
     else if (strcmp(name, "parent") == 0) {
         if (self->head->parent) {
-            return MpHList_FromHLEntry(self->head->parent, 0);
+            return MpHList_FromHLEntry(self->head->parent);
         } else {
             Py_INCREF(Py_None);
             return Py_None;

Modified: httpd/mod_python/trunk/src/include/hlist.h
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/include/hlist.h?rev=431327&r1=431326&r2=431327&view=diff
==============================================================================
--- httpd/mod_python/trunk/src/include/hlist.h (original)
+++ httpd/mod_python/trunk/src/include/hlist.h Mon Aug 14 05:07:46 2006
@@ -51,7 +51,9 @@
     hl_entry *hlist_append(apr_pool_t *p, hl_entry *hle, const char * h,
                            PyObject* o, const char *d, int d_is_fnmatch,
                            ap_regex_t *regex, const int s, hl_entry* parent);
+
     hl_entry *hlist_copy(apr_pool_t *p, const hl_entry *hle);
+    void hlist_extend(apr_pool_t *p, hl_entry *hle1, const hl_entry *hle2);
 
 #ifdef __cplusplus
 }

Modified: httpd/mod_python/trunk/src/include/hlistobject.h
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/include/hlistobject.h?rev=431327&r1=431326&r2=431327&view=diff
==============================================================================
--- httpd/mod_python/trunk/src/include/hlistobject.h (original)
+++ httpd/mod_python/trunk/src/include/hlistobject.h Mon Aug 14 05:07:46 2006
@@ -34,16 +34,13 @@
     typedef struct hlist {
         PyObject_HEAD
         struct hl_entry *head;
-        apr_pool_t *pool;
     } hlistobject;
 
     extern DL_IMPORT(PyTypeObject) MpHList_Type;
     
 #define MpHList_Check(op) ((op)->ob_type == &MpHList_Type)
 
-    extern DL_IMPORT(PyObject *)MpHList_FromHLEntry Py_PROTO((hl_entry *hle, int owner));
-    extern DL_IMPORT(void)MpHList_Append Py_PROTO((hlistobject *self, hl_entry *hle));
-    extern DL_IMPORT(void)MpHList_Copy Py_PROTO((hlistobject *self, hl_entry *hle));
+    extern DL_IMPORT(PyObject *)MpHList_FromHLEntry Py_PROTO((hl_entry *hle));
     
 #ifdef __cplusplus
 }

Modified: httpd/mod_python/trunk/src/include/mod_python.h
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/include/mod_python.h?rev=431327&r1=431326&r2=431327&view=diff
==============================================================================
--- httpd/mod_python/trunk/src/include/mod_python.h (original)
+++ httpd/mod_python/trunk/src/include/mod_python.h Mon Aug 14 05:07:46 2006
@@ -53,6 +53,7 @@
 #include "apr_strings.h"
 #include "apr_lib.h"
 #include "apr_hash.h"
+#include "apr_fnmatch.h"
 #include "scoreboard.h"
 #include "ap_mpm.h"
 #include "ap_mmn.h"

Modified: httpd/mod_python/trunk/src/include/mod_python.h.in
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/include/mod_python.h.in?rev=431327&r1=431326&r2=431327&view=diff
==============================================================================
--- httpd/mod_python/trunk/src/include/mod_python.h.in (original)
+++ httpd/mod_python/trunk/src/include/mod_python.h.in Mon Aug 14 05:07:46 2006
@@ -53,6 +53,7 @@
 #include "apr_strings.h"
 #include "apr_lib.h"
 #include "apr_hash.h"
+#include "apr_fnmatch.h"
 #include "scoreboard.h"
 #include "ap_mpm.h"
 #include "ap_mmn.h"

Modified: httpd/mod_python/trunk/src/include/mpversion.h
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/include/mpversion.h?rev=431327&r1=431326&r2=431327&view=diff
==============================================================================
--- httpd/mod_python/trunk/src/include/mpversion.h (original)
+++ httpd/mod_python/trunk/src/include/mpversion.h Mon Aug 14 05:07:46 2006
@@ -1,5 +1,5 @@
 #define MPV_MAJOR 3
 #define MPV_MINOR 3
 #define MPV_PATCH 0
-#define MPV_BUILD 20060813
-#define MPV_STRING "3.3.0-dev-20060813"
+#define MPV_BUILD 20060814
+#define MPV_STRING "3.3.0-dev-20060814"

Modified: httpd/mod_python/trunk/src/mod_python.c
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/mod_python.c?rev=431327&r1=431326&r2=431327&view=diff
==============================================================================
--- httpd/mod_python/trunk/src/mod_python.c (original)
+++ httpd/mod_python/trunk/src/mod_python.c Mon Aug 14 05:07:46 2006
@@ -1201,7 +1201,63 @@
 }
 
 /**
- ** select_interpreter_name
+ ** resolve_directory
+ **
+ *      resolve any directory match returning the matched directory
+ */
+
+static const char *resolve_directory(request_rec *req, const char *directory,
+                                     int d_is_fnmatch, ap_regex_t *regex)
+{
+    char *prefix;
+    int len, dirs, i;
+
+    if (!req || !req->filename || (!d_is_fnmatch && !regex))
+        return directory;
+
+    dirs = ap_count_dirs(req->filename) + 1;
+    len = strlen(req->filename);
+    prefix = (char*)apr_palloc(req->pool, len+1);
+
+    for (i=0; i<=dirs; i++) {
+        ap_make_dirstr_prefix(prefix, req->filename, i);
+#ifdef WIN32
+        if (d_is_fnmatch && apr_fnmatch(directory, prefix,
+            APR_FNM_PATHNAME|APR_FNM_CASE_BLIND) == 0) {
+#else
+        if (d_is_fnmatch && apr_fnmatch(directory, prefix,
+            APR_FNM_PATHNAME) == 0) {
+#endif
+            return prefix;
+        }
+        else if (regex && ap_regexec(regex, prefix, 0, NULL, 0) == 0) {
+            return prefix;
+        }
+
+        if (strcmp(prefix, "/") != 0) {
+            prefix[strlen(prefix)-1] = '\0';
+#ifdef WIN32
+            if (d_is_fnmatch && apr_fnmatch(directory, prefix,
+                APR_FNM_PATHNAME|APR_FNM_CASE_BLIND) == 0) {
+#else
+            if (d_is_fnmatch && apr_fnmatch(directory, prefix,
+                APR_FNM_PATHNAME) == 0) {
+#endif
+                prefix[strlen(prefix)] = '/';
+                return prefix;
+            }
+            else if (regex && ap_regexec(regex, prefix, 0, NULL, 0) == 0) {
+                prefix[strlen(prefix)] = '/';
+                return prefix;
+            }
+        }
+    }
+
+    return directory;
+}
+
+/**
+ ** select_interp_name
  **
  *      (internal)
  *      figure out the name of the interpreter we should be using
@@ -1302,6 +1358,7 @@
     char *ext = NULL;
     hl_entry *hle = NULL;
     hl_entry *dynhle = NULL;
+    hl_entry *hlohle = NULL;
 
     py_req_config *req_conf;
 
@@ -1331,7 +1388,8 @@
 
     /* try without extension if we don't match */
     if (!hle) {
-        hle = (hl_entry *)apr_hash_get(conf->hlists, phase, APR_HASH_KEY_STRING);
+        hle = (hl_entry *)apr_hash_get(conf->hlists, phase,
+                                       APR_HASH_KEY_STRING);
 
         /* also blank out ext since we didn't succeed with it. this is tested
            further below */
@@ -1350,11 +1408,32 @@
         return DECLINED;
     }
 
+    /* construct list for the handler list object */
+    if (!hle) {
+        hlohle = hlist_copy(req->pool, dynhle);
+    }
+    else {
+        hlohle = hlist_copy(req->pool, hle);
+
+        if (dynhle)
+            hlist_extend(req->pool, hlohle, dynhle);
+    }
+
+    /* resolve wildcard or regex directory patterns */
+    hle = hlohle;
+    while (hle) {
+        if (hle->d_is_fnmatch || hle->regex) {
+            hle->directory = resolve_directory(req, hle->directory,
+                                               hle->d_is_fnmatch, hle->regex);
+            hle->d_is_fnmatch = 0;
+            hle->regex = NULL;
+        }
+
+        hle = hle->next;
+    }
+
     /* determine interpreter to use */
-    if (hle)
-        interp_name = select_interp_name(req, NULL, conf, hle, NULL);
-    else
-        interp_name = select_interp_name(req, NULL, conf, dynhle, NULL);
+    interp_name = select_interp_name(req, NULL, conf, hlohle, NULL);
 
     /* get/create interpreter */
     idata = get_interpreter(interp_name, req->server);
@@ -1372,37 +1451,17 @@
     if (ext) 
         request_obj->extension = apr_pstrdup(req->pool, ext);
 
-    if (!hle) {
-        if (request_obj->hlo) {
-            MpHList_Copy(request_obj->hlo, dynhle);
-        }
-        else {
-            /* create a handler list object from dynamically registered handlers */
-            request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(dynhle, 1);
-        }
-    }
-    else {
-        if (request_obj->hlo) {
-            MpHList_Copy(request_obj->hlo, hle);
-        }
-        else {
-            /* create a handler list object */
-            request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle, 1);
-        }
-
-        /* add dynamically registered handlers, if any */
-        if (dynhle) {
-            MpHList_Append(request_obj->hlo, dynhle);
-        }
-    }
+    /* construct a new handler list object */
+    Py_XDECREF(request_obj->hlo);
+    request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hlohle);
 
     /* 
      * Here is where we call into Python!
      * This is the C equivalent of
      * >>> resultobject = obCallBack.Dispatch(request_object, phase)
      */
-    resultobject = PyObject_CallMethod(idata->obcallback, "HandlerDispatch", "O", 
-                                       request_obj);
+    resultobject = PyObject_CallMethod(idata->obcallback, "HandlerDispatch",
+                                       "O", request_obj);
 
     /* clear phase from request object */
     Py_XDECREF(request_obj->phase);
@@ -1559,7 +1618,7 @@
         /* nothing to do here */
         return DECLINED;
     }
-    
+
     /* determine interpreter to use */
     interp_name = select_interp_name(NULL, con, conf, hle, NULL);
 
@@ -1575,16 +1634,16 @@
     /* create connection object */
     conn_obj = (connobject*) MpConn_FromConn(con);
 
-    /* create a hahdler list object */
-    conn_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle, 1);
+    /* create a handler list object */
+    conn_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle);
 
     /* 
      * Here is where we call into Python!
      * This is the C equivalent of
      * >>> resultobject = obCallBack.Dispatch(request_object, phase)
      */
-    resultobject = PyObject_CallMethod(idata->obcallback, "ConnectionDispatch", "O", 
-                                       conn_obj);
+    resultobject = PyObject_CallMethod(idata->obcallback, "ConnectionDispatch",
+                                       "O", conn_obj);
      
     /* release the lock and destroy tstate*/
     release_interpreter();

Modified: httpd/mod_python/trunk/src/requestobject.c
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/requestobject.c?rev=431327&r1=431326&r2=431327&view=diff
==============================================================================
--- httpd/mod_python/trunk/src/requestobject.c (original)
+++ httpd/mod_python/trunk/src/requestobject.c Mon Aug 14 05:07:46 2006
@@ -194,8 +194,17 @@
                 dir = apr_pstrcat(self->request_rec->pool, dir, "/", NULL);
             }
         }
+        else {
+            /* dir is from Python, so duplicate it */
+
+            dir = apr_pstrdup(self->request_rec->pool, dir);
+        }
     }
-    
+
+    /* handler is from Python, so duplicate it */
+
+    handler = apr_pstrdup(self->request_rec->pool, handler);
+
     /* which phase are we processing? */
     currphase = PyString_AsString(self->phase);
 
@@ -203,7 +212,7 @@
     if (strcmp(currphase, phase) == 0) {
 
         /* then just append to hlist */
-        hlist_append(self->hlo->pool, self->hlo->head,
+        hlist_append(self->request_rec->pool, self->hlo->head,
                      handler, callable, dir, 0, NULL, NOTSILENT,
                      self->hlo->head);
     }