source: indico/indico/web/wsgi/indico_wsgi_url_parser.py @ 83dcd49

hello-world-walkthroughipv6v0.98-seriesv0.98.2v0.98.3v0.99v1.0v1.1
Last change on this file since 83dcd49 was 83dcd49, checked in by Pedro Ferreira <jose.pedro.ferreira@…>, 18 months ago

[FIX] debugging http api handlers.py using PDB

  • Property mode set to 100644
File size: 5.9 KB
Line 
1# -*- coding: utf-8 -*-
2##
3##
4## This file is part of CDS Indico.
5## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 CERN.
6##
7## CDS Indico is free software; you can redistribute it and/or
8## modify it under the terms of the GNU General Public License as
9## published by the Free Software Foundation; either version 2 of the
10## License, or (at your option) any later version.
11##
12## CDS Indico is distributed in the hope that it will be useful, but
13## WITHOUT ANY WARRANTY; without even the implied warranty of
14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15## General Public License for more details.
16##
17## You should have received a copy of the GNU General Public License
18## along with CDS Indico; if not, write to the Free Software Foundation, Inc.,
19## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20"""
21Some apache rewrites managed with mod_wsgi.
22"""
23
24import os
25from MaKaC.common import Config
26from MaKaC.services import handler
27
28from indico.web.http_api import handlers as export_handlers
29
30DIR_HTDOCS = Config.getInstance().getHtdocsDir()
31DIR_SERVICES = os.path.dirname(handler.__file__)
32DIR_MODULES = os.path.dirname(export_handlers.__file__)
33
34"""
35urlMapping stores the modules and handlers for every page we want,
36in the form (hash, tuple)
37@hash: matching directory
38@tuple[0]: module, a pair in the form "(containingDir, file)"
39@tuple[1]: handler
40@tuple[2]: preprocessing function (if there's no function, '')
41@tuple[3]: parameters for the preprocessing function (dictionary)
42
43Add pages that need url parsing here.
44"""
45urlMapping = {'':   ((DIR_HTDOCS, 'index.py'), 'index', '', None), \
46    'services':     ((DIR_SERVICES, 'handler.py'), 'handler', '', None), \
47    'event':        ((DIR_HTDOCS, 'events.py'), 'index', 'genericRewrite', \
48                        {'queryReplacement': 'tag'}), \
49    'categ':        ((DIR_HTDOCS, 'categoryDisplay.py'), 'index', 'genericRewrite', \
50                        {'queryReplacement': 'categId'}),
51    'export':       ((DIR_MODULES, 'wsgi_handler.py'), 'handler', '', None),
52    'api':          ((DIR_MODULES, 'wsgi_handler.py'), 'handler', '', None)
53}
54
55def is_static_path(path):
56    """
57    Returns True if path corresponds to an existing file under DIR_HTDOCS.
58    @param path: the path.
59    @type path: string
60    @return: True if path corresponds to an existing file under DIR_HTDOCS.
61    @rtype: bool
62    """
63    path = os.path.abspath(DIR_HTDOCS + path)
64    if path.startswith(DIR_HTDOCS) and os.path.isfile(path):
65        return path
66    return None
67
68def is_mp_legacy_publisher_path(req):
69    """
70    Finds the corresponding module and handler for the path given.
71    Checks path corresponds to an existing Python file under DIR_HTDOCS.
72    @param path: the path.
73    @type path: string
74    @return: the path of the module to load and the function to call there.
75    @rtype: tuple
76    """
77    path = req.URLFields['PATH_INFO'].split('/')
78    startingDir = ''
79    if len(path) > 1:
80        startingDir = path[1]
81
82    # First, we try to assign an existing redirection
83    if urlMapping.has_key(startingDir):
84        module, handler, function, params = urlMapping[startingDir]
85        if callable(getattr(WSGIRedirection, function, None)):
86            rwPage = WSGIRedirection(req, module, handler, startingDir)
87            getattr(rwPage, function)(params)
88        return (os.path.join(module[0], module[1]), handler)
89
90    # Else, we try to find the called module
91    for index, component in enumerate(path):
92        if component.endswith('.py'):
93            possible_module = os.path.abspath(DIR_HTDOCS + os.path.sep + \
94                                              os.path.sep.join(path[:index + 1]))
95            possible_handler = '/'.join(path[index + 1:]).strip()
96            if not possible_handler:
97                possible_handler = 'index'
98            if os.path.exists(possible_module):
99                return (possible_module, possible_handler)
100
101    # If all fails, then we will load a static resource
102    else:
103        return None, None
104
105class WSGIRedirection(object):
106    """
107    Redirections that need special treatment are handled by this class.
108    """
109    def __init__(self, req, module, handler, dir):
110        self._dir = dir
111        self._module = module
112        self._handler = handler
113        self._req = req
114        # These two lines locate DIR in the PATH_INFO
115        self._path = self._req.URLFields['PATH_INFO'].split('/')
116        self._index = self._path.index(self._dir)
117
118    def _pathRewrite(self, fileName):
119        """
120        Obtain the web base directory from the PATH_INFO,
121        and then add the module to the path:
122        '/indico/DIR/...' => '/indico' => '/indico/fileName'
123        """
124        newPathInfo = os.path.sep.join(self._path[:self._index]) + '/' + fileName
125        self._req.URLFields['PATH_INFO'] = newPathInfo
126
127    def _queryRewrite(self, query):
128        """
129        Rewrites the QUERY_STRING, putting everything after DIR in it
130        Example of URL:
131        http://indico.cern.ch/DIR/index.py?my=messy/short.py?tag=true
132         =>
133        http://indico.cern.ch/fileName?query=index.py?my=messy/short.py?tag=true
134        """
135        newQueryString = query + '='
136
137        # remove trailing slashes
138        filteredPath = self._path[self._index + 1:]
139        if filteredPath[-1] == '':
140            filteredPath = filteredPath[:-1]
141
142        newQueryString += '/'.join(filteredPath)
143
144        if self._req.URLFields['QUERY_STRING']:
145            newQueryString += '?' + self._req.URLFields['QUERY_STRING']
146        self._req.URLFields['QUERY_STRING'] = newQueryString
147
148    # Add the preprocessing functions for rewriting here.
149    def genericRewrite(self, params):
150        """
151        Rewrites a /DIR/ directory tag with queryReplacement
152        Example:
153        http://indico.cern.ch/DIR/108?my=messy/short.py?tag=true
154         =>
155        http://indico.cern.ch/MODULE[1]?queryReplacement=108?my=messy/short.py?tag=true
156        """
157        self._pathRewrite(self._module[1])
158        self._queryRewrite(params['queryReplacement'])
159
Note: See TracBrowser for help on using the repository browser.