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/10/24 05:41:55 UTC
svn commit: r467228 - in /httpd/mod_python/trunk: Doc/
lib/python/mod_python/ src/ src/include/
Author: grahamd
Date: Mon Oct 23 20:41:54 2006
New Revision: 467228
URL: http://svn.apache.org/viewvc?view=rev&rev=467228
Log:
(MODPYTHON-193) Added new req.hlist.location attribute so that value to a
Location/LocationMatch directive can be determined. Also fixed crash when
req.hlist is accessed from inside a filter and do some restructuring of how
errors are logged and displayed back to browser.
Modified:
httpd/mod_python/trunk/Doc/appendixc.tex
httpd/mod_python/trunk/lib/python/mod_python/apache.py
httpd/mod_python/trunk/lib/python/mod_python/importer.py
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/mod_python.h
httpd/mod_python/trunk/src/include/mod_python.h.in
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?view=diff&rev=467228&r1=467227&r2=467228
==============================================================================
--- httpd/mod_python/trunk/Doc/appendixc.tex (original)
+++ httpd/mod_python/trunk/Doc/appendixc.tex Mon Oct 23 20:41:54 2006
@@ -75,6 +75,14 @@
those other modules to access the mechanics of how mod_python creates
interpreters, thereby allowing other modules to also embed Python
and for there not to be a conflict with mod_python.
+ \item
+ (\citetitle[http://issues.apache.org/jira/browse/MODPYTHON-193]{MODPYTHON-193})
+ Added new attribute available as \code{req.hlist.location}. For a
+ handler executed directly as the result of a handler directive
+ within a \code{Location} directive, this will be set to the value
+ of the \code{Location} directive. If \code{LocationMatch}, or
+ wildcards or regular expressions are used with \code{Location},
+ the value will be the matched value in the URL and not the pattern.
\end{itemize}
Improvements
Modified: httpd/mod_python/trunk/lib/python/mod_python/apache.py
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/lib/python/mod_python/apache.py?view=diff&rev=467228&r1=467227&r2=467228
==============================================================================
--- httpd/mod_python/trunk/lib/python/mod_python/apache.py (original)
+++ httpd/mod_python/trunk/lib/python/mod_python/apache.py Mon Oct 23 20:41:54 2006
@@ -564,6 +564,7 @@
except:
# last try
traceback.print_exc()
+ sys.stderr.flush()
finally:
# erase the traceback
Modified: httpd/mod_python/trunk/lib/python/mod_python/importer.py
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/lib/python/mod_python/importer.py?view=diff&rev=467228&r1=467227&r2=467228
==============================================================================
--- httpd/mod_python/trunk/lib/python/mod_python/importer.py (original)
+++ httpd/mod_python/trunk/lib/python/mod_python/importer.py Mon Oct 23 20:41:54 2006
@@ -337,29 +337,27 @@
def _log_notice(self, msg):
pid = os.getpid()
name = apache.interpreter
- server = apache.main_server
flags = apache.APLOG_NOERRNO|apache.APLOG_NOTICE
- text = "mod_python (pid=%d,interpreter=%s): %s" % (pid, `name`, msg)
- apache.log_error(text, flags, server)
+ text = "mod_python (pid=%d, interpreter=%s): %s" % (pid, `name`, msg)
+ apache.main_server.log_error(text, flags)
def _log_warning(self, msg):
pid = os.getpid()
name = apache.interpreter
- server = apache.main_server
flags = apache.APLOG_NOERRNO|apache.APLOG_WARNING
- text = "mod_python (pid=%d,interpreter=%s): %s" % (pid, `name`, msg)
- apache.log_error(text, flags, server)
+ text = "mod_python (pid=%d, interpreter=%s): %s" % (pid, `name`, msg)
+ apache.main_server.log_error(text, flags)
def _log_exception(self):
pid = os.getpid()
name = apache.interpreter
- server = apache.main_server
flags = apache.APLOG_NOERRNO|apache.APLOG_ERR
- prefix = "mod_python (pid=%d,interpreter=%s)" % (pid, `name`)
+ msg = 'Application error'
+ text = "mod_python (pid=%d, interpreter=%s): %s" % (pid, `name`, msg)
+ apache.main_server.log_error(text, flags)
etype, evalue, etb = sys.exc_info()
- for msg in traceback.format_exception(etype, evalue, etb):
- text = "%s: %s" % (prefix, msg[:-1])
- apache.log_error(text, flags, server)
+ for text in traceback.format_exception(etype, evalue, etb):
+ apache.main_server.log_error(text[:-1], flags)
etb = None
def cached_modules(self):
@@ -1264,7 +1262,7 @@
try:
(exc_type, exc_value, exc_traceback) = traceblock
result = self.ReportError(exc_type, exc_value, exc_traceback,
- srv=conn.base_server, phase="ConnectionHandler",
+ conn=conn, phase="ConnectionHandler",
hname=conn.hlist.handler, debug=debug)
finally:
@@ -1279,7 +1277,7 @@
try:
exc_type, exc_value, exc_traceback = sys.exc_info()
result = self.ReportError(exc_type, exc_value, exc_traceback,
- srv=conn.base_server, phase="ConnectionHandler",
+ conn=conn, phase="ConnectionHandler",
hname=conn.hlist.handler, debug=debug)
finally:
exc_traceback = None
@@ -1425,13 +1423,28 @@
options = req.get_options()
try:
+ (aborted, hlist) = False, req.hlist
+
+ # The actual handler root is the directory
+ # associated with the handler first in the
+ # chain. This may be a handler which was called
+ # in an earlier phase if the req.add_handler()
+ # method was used. The directory for those that
+ # follow the first may have been overridden by
+ # directory supplied to the req.add_handler()
+ # method.
+
+ root = hlist.directory
+ parent = hlist.parent
+ while parent is not None:
+ root = parent.directory
+ parent = parent.parent
+
# Iterate over the handlers defined for the
# current phase and execute each in turn
# until the last is reached or prematurely
# aborted.
- (aborted, hlist) = False, req.hlist
-
while not aborted and hlist.handler is not None:
try:
@@ -1443,6 +1456,11 @@
# If directory for handler is not set,
# then search back through parents and
# inherit value from parent if found.
+ # This directory is that where modules
+ # are searched for first and may not be
+ # the same as the handler root if it
+ # was supplied explicitly to the method
+ # req.add_handler().
if directory is None:
parent = hlist.parent
@@ -1468,7 +1486,7 @@
# current request so that it will be
# available from within 'import_module()'.
- cache = _setup_current_cache(config, options, directory)
+ cache = _setup_current_cache(config, options, root)
(aborted, result) = _process_target(config=config, req=req,
directory=directory, handler=handler,
@@ -1583,8 +1601,7 @@
exc_type, exc_value, exc_traceback = sys.exc_info()
result = self.ReportError(exc_type, exc_value, exc_traceback,
filter=filter, phase=filter.name,
- hname=filter.req.filename,
- debug=debug)
+ hname=filter.req.filename, debug=debug)
finally:
exc_traceback = None
@@ -1647,8 +1664,8 @@
_callback.ImportDispatch = new.instancemethod(
ImportDispatch, _callback, apache.CallBack)
-def ReportError(self, etype, evalue, etb, req=None, filter=None,
- srv=None, phase="N/A", hname="N/A", debug=0):
+def ReportError(self, etype, evalue, etb, conn=None, req=None, filter=None,
+ phase="N/A", hname="N/A", debug=0):
try:
try:
@@ -1668,22 +1685,54 @@
debug = 0
+ # Determine which log function we are going
+ # to use to output any messages.
+
+ if filter and not req:
+ req = filter.req
+
+ if req:
+ log_error = req.log_error
+ elif conn:
+ log_error = conn.log_error
+ else:
+ log_error = apache.main_server.log_error
+
# Always log the details of any exception.
pid = os.getpid()
iname = apache.interpreter
flags = apache.APLOG_NOERRNO|apache.APLOG_ERR
- details = "(pid=%d,interpreter=%s,phase=%s,handler=%s)" % \
- (pid, `iname`, `phase`, `hname`)
+
+ text = "mod_python (pid=%d, interpreter=%s, " % (pid, `iname`)
+ text = text + "phase=%s, handler=%s)" % (`phase`, `hname`)
+ text = text + ": Application error"
+
+ log_error(text, flags)
+
+ if req:
+ location = None
+ directory = None
+
+ context = req.hlist
+
+ if context:
+ while context.parent != None:
+ context = context.parent
+
+ location = context.location
+ directory = context.directory
+
+ log_error('URI: %s' % `req.uri`, flags)
+ log_error('Location: %s' % `location`, flags)
+ log_error('Directory: %s' % `directory`, flags)
+ log_error('Filename: %s' % `req.filename`, flags)
+ log_error('PathInfo: %s' % `req.path_info`, flags)
tb = traceback.format_exception(etype, evalue, etb)
for line in tb:
- text = "mod_python %s: %s" % (details, line[:-1])
- if req:
- req.log_error(text, flags)
- else:
- apache.log_error(text, flags, srv)
+ log_error(line[:-1], flags)
if not debug or not req:
return apache.HTTP_INTERNAL_SERVER_ERROR
@@ -1695,12 +1744,16 @@
text = text + 'PID: %s\n' % pid
text = text + 'Interpreter: %s\n' % `iname`
text = text + 'Phase: %s\n' % `phase`
+
if req:
- context = req.hlist
- while context.parent != None:
- context = context.parent
- text = text + 'HandlerRoot: %s\n' % `context.directory`
- text = text + 'HandlerPath: %s\n' % `req.hlist.directory`
+ text = text + '\n'
+ text = text + 'URI: %s\n' % `req.uri`
+ text = text + 'Location: %s\n' % `location`
+ text = text + 'Directory: %s\n' % `directory`
+ text = text + 'Filename: %s\n' % `req.filename`
+ text = text + 'PathInfo: %s\n' % `req.path_info`
+
+ text = text + '\n'
text = text + 'Handler: %s\n' % cgi.escape(repr(hname))
text = text + '\n'
Modified: httpd/mod_python/trunk/src/hlist.c
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/hlist.c?view=diff&rev=467228&r1=467227&r2=467228
==============================================================================
--- httpd/mod_python/trunk/src/hlist.c (original)
+++ httpd/mod_python/trunk/src/hlist.c Mon Oct 23 20:41:54 2006
@@ -33,9 +33,10 @@
* Start a new list.
*/
-hl_entry *hlist_new(apr_pool_t *p, 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_new(apr_pool_t *p, const char *h, PyObject *o,
+ const char *d, int d_is_fnmatch, ap_regex_t *d_regex,
+ const char *l, int l_is_fnmatch, ap_regex_t *l_regex,
+ const int s, hl_entry* parent)
{
hl_entry *hle;
@@ -45,7 +46,10 @@
hle->callable = o;
hle->directory = d;
hle->d_is_fnmatch = d_is_fnmatch;
- hle->regex = regex;
+ hle->d_regex = d_regex;
+ hle->location = l;
+ hle->l_is_fnmatch = l_is_fnmatch;
+ hle->l_regex = l_regex;
hle->silent = s;
hle->parent = parent;
@@ -61,9 +65,10 @@
* If hle is NULL, a new list is created.
*/
-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_append(apr_pool_t *p, hl_entry *hle, const char * h, PyObject *o,
+ const char *d, int d_is_fnmatch, ap_regex_t *d_regex,
+ const char *l, int l_is_fnmatch, ap_regex_t *l_regex,
+ const int s, hl_entry *parent)
{
hl_entry *nhle;
@@ -77,7 +82,10 @@
nhle->callable = o;
nhle->directory = d;
nhle->d_is_fnmatch = d_is_fnmatch;
- nhle->regex = regex;
+ nhle->d_regex = d_regex;
+ nhle->location = l;
+ nhle->l_is_fnmatch = l_is_fnmatch;
+ nhle->l_regex = l_regex;
nhle->silent = s;
nhle->parent = parent;
@@ -102,7 +110,10 @@
head->callable = hle->callable;
head->directory = hle->directory;
head->d_is_fnmatch = hle->d_is_fnmatch;
- head->regex = hle->regex;
+ head->d_regex = hle->d_regex;
+ head->location = hle->location;
+ head->l_is_fnmatch = hle->l_is_fnmatch;
+ head->l_regex = hle->l_regex;
head->silent = hle->silent;
head->parent = hle->parent;
@@ -115,7 +126,10 @@
nhle->callable = hle->callable;
nhle->directory = hle->directory;
nhle->d_is_fnmatch = hle->d_is_fnmatch;
- nhle->regex = hle->regex;
+ nhle->d_regex = hle->d_regex;
+ nhle->location = hle->location;
+ nhle->l_is_fnmatch = hle->l_is_fnmatch;
+ nhle->l_regex = hle->l_regex;
nhle->silent = hle->silent;
nhle->parent = hle->parent;
hle = hle->next;
@@ -146,7 +160,10 @@
hle1->callable = hle2->callable;
hle1->directory = hle2->directory;
hle1->d_is_fnmatch = hle2->d_is_fnmatch;
- hle1->regex = hle2->regex;
+ hle1->d_regex = hle2->d_regex;
+ hle1->location = hle2->location;
+ hle1->l_is_fnmatch = hle2->l_is_fnmatch;
+ hle1->l_regex = hle2->l_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?view=diff&rev=467228&r1=467227&r2=467228
==============================================================================
--- httpd/mod_python/trunk/src/hlistobject.c (original)
+++ httpd/mod_python/trunk/src/hlistobject.c Mon Oct 23 20:41:54 2006
@@ -53,6 +53,11 @@
static PyObject *hlist_next(hlistobject *self, PyObject *args)
{
+ if (! self->head) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
self->head = self->head->next;
Py_INCREF(Py_None);
@@ -68,6 +73,7 @@
static struct memberlist hlist_memberlist[] = {
{"directory", T_STRING, OFF(directory), RO},
+ {"location", T_STRING, OFF(location), RO},
{"silent", T_INT, OFF(silent), RO},
{NULL} /* Sentinel */
};
@@ -137,7 +143,14 @@
static PyObject *hlist_repr(hlistobject *self)
{
PyObject *t;
- PyObject *s = PyString_FromString("{");
+ PyObject *s;
+
+ if (! self->head) {
+ s = PyString_FromString("None");
+ return s;
+ }
+
+ s = PyString_FromString("{");
if (self->head->handler) {
PyString_ConcatAndDel(&s, PyString_FromString("'handler':"));
t = PyString_FromString(self->head->handler);
@@ -150,6 +163,12 @@
if (self->head->directory) {
PyString_ConcatAndDel(&s, PyString_FromString(",'directory':"));
t = PyString_FromString(self->head->directory);
+ PyString_ConcatAndDel(&s, PyObject_Repr(t));
+ Py_XDECREF(t);
+ }
+ if (self->head->location) {
+ PyString_ConcatAndDel(&s, PyString_FromString(",'location':"));
+ t = PyString_FromString(self->head->location);
PyString_ConcatAndDel(&s, PyObject_Repr(t));
Py_XDECREF(t);
}
Modified: httpd/mod_python/trunk/src/include/hlist.h
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/include/hlist.h?view=diff&rev=467228&r1=467227&r2=467228
==============================================================================
--- httpd/mod_python/trunk/src/include/hlist.h (original)
+++ httpd/mod_python/trunk/src/include/hlist.h Mon Oct 23 20:41:54 2006
@@ -37,7 +37,10 @@
PyObject *callable;
const char *directory;
int d_is_fnmatch;
- ap_regex_t *regex;
+ ap_regex_t *d_regex;
+ const char *location;
+ int l_is_fnmatch;
+ ap_regex_t *l_regex;
int silent; /* 1 for PythonHandlerModule, where
if a handler is not found in a module,
no error should be reported */
@@ -46,11 +49,13 @@
} hl_entry;
hl_entry *hlist_new(apr_pool_t *p, const char *h, PyObject* o,
- const char *d, int d_is_fnmatch, ap_regex_t *regex,
+ const char *d, int d_is_fnmatch, ap_regex_t *d_regex,
+ const char *l, int l_is_fnmatch, ap_regex_t *l_regex,
const int s, hl_entry* parent);
- 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_append(apr_pool_t *p, hl_entry *hle, const char * h, PyObject* o,
+ const char *d, int d_is_fnmatch, ap_regex_t *d_regex,
+ const char *l, int l_is_fnmatch, ap_regex_t *l_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);
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?view=diff&rev=467228&r1=467227&r2=467228
==============================================================================
--- httpd/mod_python/trunk/src/include/mod_python.h (original)
+++ httpd/mod_python/trunk/src/include/mod_python.h Mon Oct 23 20:41:54 2006
@@ -200,7 +200,10 @@
PyObject *callable;
char *directory;
int d_is_fnmatch;
- ap_regex_t *regex;
+ ap_regex_t *d_regex;
+ char *location;
+ int l_is_fnmatch;
+ ap_regex_t *l_regex;
hl_entry *parent;
} py_handler;
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?view=diff&rev=467228&r1=467227&r2=467228
==============================================================================
--- httpd/mod_python/trunk/src/include/mod_python.h.in (original)
+++ httpd/mod_python/trunk/src/include/mod_python.h.in Mon Oct 23 20:41:54 2006
@@ -200,7 +200,10 @@
PyObject *callable;
char *directory;
int d_is_fnmatch;
- ap_regex_t *regex;
+ ap_regex_t *d_regex;
+ char *location;
+ int l_is_fnmatch;
+ ap_regex_t *l_regex;
hl_entry *parent;
} py_handler;
Modified: httpd/mod_python/trunk/src/mod_python.c
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/mod_python.c?view=diff&rev=467228&r1=467227&r2=467228
==============================================================================
--- httpd/mod_python/trunk/src/mod_python.c (original)
+++ httpd/mod_python/trunk/src/mod_python.c Mon Oct 23 20:41:54 2006
@@ -1012,7 +1012,8 @@
#endif
static void determine_context(apr_pool_t *p, const cmd_parms* cmd,
- char **dp, int *gx, ap_regex_t **rx)
+ char **d, int *d_gx, ap_regex_t **d_rx,
+ char **l, int *l_gx, ap_regex_t **l_rx)
{
const ap_directive_t *context = 0;
const ap_directive_t *directive = 0;
@@ -1020,7 +1021,11 @@
char *directory = 0;
int d_is_fnmatch = 0;
- ap_regex_t *regex = 0;
+ ap_regex_t *d_regex = 0;
+
+ char *location = 0;
+ int l_is_fnmatch = 0;
+ ap_regex_t *l_regex = 0;
directive = cmd->directive;
@@ -1041,7 +1046,7 @@
if (!strcmp(directory, "~")) {
directory = ap_getword_conf(p, &arg);
- regex = ap_pregcomp(p, cmd->path, AP_REG_EXTENDED|USE_ICASE);
+ d_regex = ap_pregcomp(p, cmd->path, AP_REG_EXTENDED|USE_ICASE);
} else if (ap_is_matchexp(directory)) {
d_is_fnmatch = 1;
}
@@ -1051,9 +1056,28 @@
arg = apr_pstrndup(p, arg, endp - arg);
directory = ap_getword_conf(p, &arg);
- regex = ap_pregcomp(p, directory, AP_REG_EXTENDED|USE_ICASE);
- }
- else if (cmd->config_file != NULL) {
+ d_regex = ap_pregcomp(p, directory, AP_REG_EXTENDED|USE_ICASE);
+ } else if ((context = find_parent(directive, "<Location"))) {
+ arg = context->args;
+ endp = ap_strrchr_c(arg, '>');
+ arg = apr_pstrndup(p, arg, endp - arg);
+
+ location = ap_getword_conf(p, &arg);
+
+ if (!strcmp(location, "~")) {
+ location = ap_getword_conf(p, &arg);
+ l_regex = ap_pregcomp(p, cmd->path, AP_REG_EXTENDED|USE_ICASE);
+ } else if (ap_is_matchexp(location)) {
+ l_is_fnmatch = 1;
+ }
+ } else if ((context = find_parent(directive, "<LocationMatch"))) {
+ arg = context->args;
+ endp = ap_strrchr_c(arg, '>');
+ arg = apr_pstrndup(p, arg, endp - arg);
+
+ location = ap_getword_conf(p, &arg);
+ l_regex = ap_pregcomp(p, location, AP_REG_EXTENDED|USE_ICASE);
+ } else if (cmd->config_file != NULL) {
/* cmd->config_file is NULL when in main Apache
* configuration file as the file is completely
* read in before the directive is processed as
@@ -1068,7 +1092,7 @@
* this point if no pattern matching to be done at
* a later time. */
- if (!d_is_fnmatch && !regex) {
+ if (directory && !d_is_fnmatch && !d_regex) {
char *newpath = 0;
apr_status_t rv;
@@ -1088,9 +1112,13 @@
}
}
- *dp = directory;
- *gx = d_is_fnmatch;
- *rx = regex;
+ *d = directory;
+ *d_gx = d_is_fnmatch;
+ *d_rx = d_regex;
+
+ *l = location;
+ *l_gx = l_is_fnmatch;
+ *l_rx = l_regex;
}
static void python_directive_hl_add(apr_pool_t *p, apr_hash_t *hlists,
@@ -1102,9 +1130,14 @@
char *directory = 0;
int d_is_fnmatch = 0;
- ap_regex_t *regex = 0;
+ ap_regex_t *d_regex = 0;
- determine_context(p, cmd, &directory, &d_is_fnmatch, ®ex);
+ char *location = 0;
+ int l_is_fnmatch = 0;
+ ap_regex_t *l_regex = 0;
+
+ determine_context(p, cmd, &directory, &d_is_fnmatch, &d_regex,
+ &location, &l_is_fnmatch, &l_regex);
head = (hl_entry *)apr_hash_get(hlists, phase, APR_HASH_KEY_STRING);
@@ -1113,11 +1146,13 @@
while (*(h = ap_getword_white(p, &handler)) != '\0') {
if (!head) {
- head = hlist_new(p, h, 0, directory, d_is_fnmatch, regex, silent, 0);
+ head = hlist_new(p, h, 0, directory, d_is_fnmatch, d_regex,
+ location, l_is_fnmatch, l_regex, silent, 0);
apr_hash_set(hlists, phase, APR_HASH_KEY_STRING, head);
}
else {
- hlist_append(p, head, h, 0, directory, d_is_fnmatch, regex, silent, 0);
+ hlist_append(p, head, h, 0, directory, d_is_fnmatch, d_regex,
+ location, l_is_fnmatch, l_regex, silent, 0);
}
}
}
@@ -1283,20 +1318,22 @@
*/
static const char *resolve_directory(request_rec *req, const char *directory,
- int d_is_fnmatch, ap_regex_t *regex)
+ int d_is_fnmatch, ap_regex_t *d_regex)
{
char *prefix;
int len, dirs, i;
- if (!req || !req->filename || (!d_is_fnmatch && !regex))
+ if (!req || !req->filename || (!d_is_fnmatch && !d_regex))
return directory;
dirs = ap_count_dirs(req->filename) + 1;
len = strlen(req->filename);
- prefix = (char*)apr_palloc(req->pool, len+1);
+ prefix = (char*)apr_palloc(req->pool, len+2);
for (i=0; i<=dirs; i++) {
ap_make_dirstr_prefix(prefix, req->filename, i);
+
+ /* Match with trailing slash first. */
#ifdef WIN32
if (d_is_fnmatch && apr_fnmatch(directory, prefix,
APR_FNM_PATHNAME|APR_FNM_CASE_BLIND) == 0) {
@@ -1306,12 +1343,14 @@
#endif
return prefix;
}
- else if (regex && ap_regexec(regex, prefix, 0, NULL, 0) == 0) {
+ else if (d_regex && ap_regexec(d_regex, prefix, 0, NULL, 0) == 0) {
return prefix;
}
if (strcmp(prefix, "/") != 0) {
prefix[strlen(prefix)-1] = '\0';
+
+ /* Match without trailing slash. */
#ifdef WIN32
if (d_is_fnmatch && apr_fnmatch(directory, prefix,
APR_FNM_PATHNAME|APR_FNM_CASE_BLIND) == 0) {
@@ -1322,7 +1361,7 @@
prefix[strlen(prefix)] = '/';
return prefix;
}
- else if (regex && ap_regexec(regex, prefix, 0, NULL, 0) == 0) {
+ else if (d_regex && ap_regexec(d_regex, prefix, 0, NULL, 0) == 0) {
prefix[strlen(prefix)] = '/';
return prefix;
}
@@ -1333,6 +1372,60 @@
}
/**
+ ** resolve_location
+ **
+ * resolve any location match returning the matched location
+ */
+
+static const char *resolve_location(request_rec *req, const char *location,
+ int l_is_fnmatch, ap_regex_t *l_regex)
+{
+ char *prefix;
+ int len, dirs, i;
+
+ if (!req || !req->uri || (!l_is_fnmatch && !l_regex))
+ return location;
+
+ dirs = ap_count_dirs(req->uri) + 1;
+ len = strlen(req->uri);
+ prefix = (char*)apr_palloc(req->pool, len+2);
+
+ for (i=0; i<=dirs; i++) {
+ int match = 0;
+ ap_make_dirstr_prefix(prefix, req->uri, i);
+
+ /* Match with trailing slash first. */
+ if (l_is_fnmatch && apr_fnmatch(location, prefix,
+ APR_FNM_PATHNAME) == 0) {
+ match = 1;
+ }
+ else if (l_regex && ap_regexec(l_regex, prefix, 0, NULL, 0) == 0) {
+ match = 1;
+ }
+
+ if (strcmp(prefix, "/") != 0) {
+ prefix[strlen(prefix)-1] = '\0';
+
+ /* Match without trailing slash. */
+ if (l_is_fnmatch && apr_fnmatch(location, prefix,
+ APR_FNM_PATHNAME) == 0) {
+ return prefix;
+ }
+ else if (l_regex && ap_regexec(l_regex, prefix, 0, NULL, 0) == 0) {
+ return prefix;
+ }
+
+ if (match) {
+ prefix[strlen(prefix)] = '/';
+ return prefix;
+ }
+ }
+ }
+
+ return location;
+}
+
+/**
** select_interp_name
**
* (internal)
@@ -1498,11 +1591,17 @@
/* resolve wildcard or regex directory patterns */
hle = hlohle;
while (hle) {
- if (hle->d_is_fnmatch || hle->regex) {
+ if (hle->d_is_fnmatch || hle->d_regex) {
hle->directory = resolve_directory(req, hle->directory,
- hle->d_is_fnmatch, hle->regex);
+ hle->d_is_fnmatch, hle->d_regex);
hle->d_is_fnmatch = 0;
- hle->regex = NULL;
+ hle->d_regex = NULL;
+ }
+ if (hle->l_is_fnmatch || hle->l_regex) {
+ hle->location = resolve_location(req, hle->location,
+ hle->l_is_fnmatch, hle->l_regex);
+ hle->l_is_fnmatch = 0;
+ hle->l_regex = NULL;
}
hle = hle->next;
@@ -2505,7 +2604,11 @@
char *directory = 0;
int d_is_fnmatch = 0;
- ap_regex_t *regex = 0;
+ ap_regex_t *d_regex = 0;
+
+ char *location = 0;
+ int l_is_fnmatch = 0;
+ ap_regex_t *l_regex = 0;
if (!name)
name = apr_pstrdup(cmd->pool, handler);
@@ -2517,13 +2620,19 @@
conf = (py_config *) mconfig;
- determine_context(cmd->pool, cmd, &directory, &d_is_fnmatch, ®ex);
+ determine_context(cmd->pool, cmd, &directory, &d_is_fnmatch, &d_regex,
+ &location, &l_is_fnmatch, &l_regex);
fh = (py_handler *) apr_pcalloc(cmd->pool, sizeof(py_handler));
fh->handler = (char *)handler;
+
fh->directory = directory;
fh->d_is_fnmatch = d_is_fnmatch;
- fh->regex = regex;
+ fh->d_regex = d_regex;
+
+ fh->location = location;
+ fh->l_is_fnmatch = l_is_fnmatch;
+ fh->l_regex = l_regex;
apr_hash_set(conf->in_filters, frec->name, APR_HASH_KEY_STRING, fh);
@@ -2538,8 +2647,12 @@
char *directory = 0;
int d_is_fnmatch = 0;
- ap_regex_t *regex = 0;
-
+ ap_regex_t *d_regex = 0;
+
+ char *location = 0;
+ int l_is_fnmatch = 0;
+ ap_regex_t *l_regex = 0;
+
if (!name)
name = apr_pstrdup(cmd->pool, handler);
@@ -2548,15 +2661,21 @@
would have to make sure not to duplicate this */
frec = ap_register_output_filter(name, python_output_filter, NULL, AP_FTYPE_RESOURCE);
- determine_context(cmd->pool, cmd, &directory, &d_is_fnmatch, ®ex);
+ determine_context(cmd->pool, cmd, &directory, &d_is_fnmatch, &d_regex,
+ &location, &l_is_fnmatch, &l_regex);
conf = (py_config *) mconfig;
fh = (py_handler *) apr_pcalloc(cmd->pool, sizeof(py_handler));
fh->handler = (char *)handler;
+
fh->directory = directory;
fh->d_is_fnmatch = d_is_fnmatch;
- fh->regex = regex;
+ fh->d_regex = d_regex;
+
+ fh->location = location;
+ fh->l_is_fnmatch = l_is_fnmatch;
+ fh->l_regex = l_regex;
apr_hash_set(conf->out_filters, frec->name, APR_HASH_KEY_STRING, fh);
Modified: httpd/mod_python/trunk/src/requestobject.c
URL: http://svn.apache.org/viewvc/httpd/mod_python/trunk/src/requestobject.c?view=diff&rev=467228&r1=467227&r2=467228
==============================================================================
--- httpd/mod_python/trunk/src/requestobject.c (original)
+++ httpd/mod_python/trunk/src/requestobject.c Mon Oct 23 20:41:54 2006
@@ -214,7 +214,7 @@
/* then just append to hlist */
hlist_append(self->request_rec->pool, self->hlo->head,
- handler, callable, dir, 0, NULL, NOTSILENT,
+ handler, callable, dir, 0, NULL, NULL, 0, NULL, NOTSILENT,
self->hlo->head);
}
else {
@@ -232,12 +232,12 @@
if (! hle) {
hle = hlist_new(self->request_rec->pool, handler, callable, dir,
- 0, NULL, NOTSILENT, self->hlo->head);
+ 0, NULL, NULL, 0, NULL, NOTSILENT, self->hlo->head);
apr_hash_set(req_config->dynhls, phase, APR_HASH_KEY_STRING, hle);
}
else {
hlist_append(self->request_rec->pool, hle, handler, callable, dir,
- 0, NULL, NOTSILENT, self->hlo->head);
+ 0, NULL, NULL, 0, NULL, NOTSILENT, self->hlo->head);
}
}