Ticket #285: script_name_path_info4.diff

File script_name_path_info4.diff, 20.1 KB (added by jmelesky, 8 years ago)

Another revision, against [6316]. This one actually passes the test suite.

  • django/http/__init__.py

     
    2626    def __init__(self):
    2727        self.GET, self.POST, self.COOKIES, self.META, self.FILES = {}, {}, {}, {}, {}
    2828        self.path = ''
     29        self.full_path = ''
    2930        self.method = None
    3031
    3132    def __repr__(self):
     
    7172            location = self.get_full_path()
    7273        if not ':' in location:
    7374            current_uri = '%s://%s%s' % (self.is_secure() and 'https' or 'http',
    74                                          self.get_host(), self.path)
     75                                         self.get_host(), self.full_path)
    7576            location = urljoin(current_uri, location)
    7677        return location
    7778
  • django/test/client.py

     
    151151            'PATH_INFO':         '/',
    152152            'QUERY_STRING':      '',
    153153            'REQUEST_METHOD':    'GET',
    154             'SCRIPT_NAME':       None,
     154            'SCRIPT_NAME':       '',
    155155            'SERVER_NAME':       'testserver',
    156156            'SERVER_PORT':       80,
    157157            'SERVER_PROTOCOL':   'HTTP/1.1',
  • django/core/handlers/wsgi.py

     
    7575class WSGIRequest(http.HttpRequest):
    7676    def __init__(self, environ):
    7777        self.environ = environ
    78         self.path = force_unicode(environ['PATH_INFO'])
     78        self.path = force_unicode(environ.get('PATH_INFO', '/'))
     79        self.full_path = (force_unicode(environ.get('SCRIPT_NAME', ''))
     80                          + force_unicode(environ.get('PATH_INFO', '/')))
    7981        self.META = environ
     82        self.META['PATH_INFO'] = self.path
     83        self.META['SCRIPT_NAME'] = force_unicode(environ.get('SCRIPT_NAME', ''))
    8084        self.method = environ['REQUEST_METHOD'].upper()
    8185
    8286    def __repr__(self):
     
    102106            (get, post, cookies, meta)
    103107
    104108    def get_full_path(self):
    105         return '%s%s' % (self.path, self.environ.get('QUERY_STRING', '') and ('?' + self.environ.get('QUERY_STRING', '')) or '')
     109        return '%s%s' % (self.full_path, self.environ.get('QUERY_STRING', '') and ('?' + self.environ.get('QUERY_STRING', '')) or '')
    106110
    107111    def is_secure(self):
    108112        return 'HTTPS' in self.environ and self.environ['HTTPS'] == 'on'
  • django/core/handlers/modpython.py

     
    1414class ModPythonRequest(http.HttpRequest):
    1515    def __init__(self, req):
    1616        self._req = req
    17         self.path = force_unicode(req.uri)
     17        self.full_path = force_unicode(req.uri)
     18        root = req.get_options().get('django.root', '')
     19        self._django_root = force_unicode(root)
     20        if root and req.uri.startswith(root):
     21            self.path = force_unicode(req.uri[len(root):])
     22        else:
     23            self.path = self.full_path
    1824
    1925    def __repr__(self):
    2026        # Since this is called as part of error handling, we need to be very
     
    3945            (self.path, get, post, cookies, meta)
    4046
    4147    def get_full_path(self):
    42         return '%s%s' % (self.path, self._req.args and ('?' + self._req.args) or '')
     48        return '%s%s' % (self.full_path, self._req.args and ('?' + self._req.args) or '')
    4349
    4450    def is_secure(self):
    4551        # Note: modpython 3.2.10+ has req.is_https(), but we need to support previous versions
     
    94100                'CONTENT_LENGTH':    self._req.clength, # This may be wrong
    95101                'CONTENT_TYPE':      self._req.content_type, # This may be wrong
    96102                'GATEWAY_INTERFACE': 'CGI/1.1',
    97                 'PATH_INFO':         self._req.path_info,
     103                'PATH_INFO':         self.path,
    98104                'PATH_TRANSLATED':   None, # Not supported
    99105                'QUERY_STRING':      self._req.args,
    100106                'REMOTE_ADDR':       self._req.connection.remote_ip,
     
    102108                'REMOTE_IDENT':      self._req.connection.remote_logname,
    103109                'REMOTE_USER':       self._req.user,
    104110                'REQUEST_METHOD':    self._req.method,
    105                 'SCRIPT_NAME':       None, # Not supported
     111                'SCRIPT_NAME':       self._django_root,
    106112                'SERVER_NAME':       self._req.server.server_hostname,
    107113                'SERVER_PORT':       self._req.server.port,
    108114                'SERVER_PROTOCOL':   self._req.protocol,
  • django/views/generic/create_update.py

     
    2121    """
    2222    if extra_context is None: extra_context = {}
    2323    if login_required and not request.user.is_authenticated():
    24         return redirect_to_login(request.path)
     24        return redirect_to_login(request.full_path)
    2525
    2626    manipulator = model.AddManipulator(follow=follow)
    2727    if request.POST:
     
    8787    """
    8888    if extra_context is None: extra_context = {}
    8989    if login_required and not request.user.is_authenticated():
    90         return redirect_to_login(request.path)
     90        return redirect_to_login(request.full_path)
    9191
    9292    # Look up the object to be edited
    9393    lookup_kwargs = {}
     
    163163    """
    164164    if extra_context is None: extra_context = {}
    165165    if login_required and not request.user.is_authenticated():
    166         return redirect_to_login(request.path)
     166        return redirect_to_login(request.full_path)
    167167
    168168    # Look up the object to be edited
    169169    lookup_kwargs = {}
  • django/views/debug.py

     
    345345    </tr>
    346346    <tr>
    347347      <th>Request URL:</th>
    348       <td>{{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path|escape }}</td>
     348      <td>{{ request_protocol }}://{{ request.get_host }}{{ request.full_path|escape }}</td>
    349349    </tr>
    350350    <tr>
    351351      <th>Exception Type:</th>
     
    634634      </tr>
    635635      <tr>
    636636        <th>Request URL:</th>
    637       <td>{{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path|escape }}</td>
     637      <td>{{ request_protocol }}://{{ request.get_host }}{{ request.full_path|escape }}</td>
    638638      </tr>
    639639    </table>
    640640  </div>
  • django/contrib/syndication/feeds.py

     
    2525    def __init__(self, slug, request):
    2626        self.slug = slug
    2727        self.request = request
    28         self.feed_url = request.path
     28        self.feed_url = request.full_path
    2929        self.title_template_name = self.title_template or ('feeds/%s_title.html' % slug)
    3030        self.description_template_name = self.description_template or ('feeds/%s_description.html' % slug)
    3131
  • django/contrib/comments/views/userflags.py

     
    1919    comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
    2020    if request.POST:
    2121        UserFlag.objects.flag(comment, request.user)
    22         return HttpResponseRedirect('%sdone/' % request.path)
     22        return HttpResponseRedirect('%sdone/' % request.full_path)
    2323    return render_to_response('comments/flag_verify.html', {'comment': comment},
    2424        context_instance=RequestContext(request, extra_context, context_processors))
    2525flag = login_required(flag)
     
    5050            comment.save()
    5151            m = ModeratorDeletion(None, request.user.id, comment.id, None)
    5252            m.save()
    53         return HttpResponseRedirect('%sdone/' % request.path)
     53        return HttpResponseRedirect('%sdone/' % request.full_path)
    5454    return render_to_response('comments/delete_verify.html', {'comment': comment},
    5555        context_instance=RequestContext(request, extra_context, context_processors))
    5656delete = login_required(delete)
  • django/contrib/admin/views/auth.py

     
    2020            msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': 'user', 'obj': new_user}
    2121            if "_addanother" in request.POST:
    2222                request.user.message_set.create(message=msg)
    23                 return HttpResponseRedirect(request.path)
     23                return HttpResponseRedirect(request.full_path)
    2424            else:
    2525                request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
    2626                return HttpResponseRedirect('../%s/' % new_user.id)
  • django/contrib/admin/views/main.py

     
    276276                    (pk_value, force_unicode(new_object).replace('"', '\\"')))
    277277            elif "_addanother" in request.POST:
    278278                request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
    279                 return HttpResponseRedirect(request.path)
     279                return HttpResponseRedirect(request.full_path)
    280280            else:
    281281                request.user.message_set.create(message=msg)
    282282                return HttpResponseRedirect(post_url)
     
    353353            if "_continue" in request.POST:
    354354                request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
    355355                if '_popup' in request.REQUEST:
    356                     return HttpResponseRedirect(request.path + "?_popup=1")
     356                    return HttpResponseRedirect(request.full_path + "?_popup=1")
    357357                else:
    358                     return HttpResponseRedirect(request.path)
     358                    return HttpResponseRedirect(request.full_path)
    359359            elif "_saveasnew" in request.POST:
    360360                request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)})
    361361                return HttpResponseRedirect("../%s/" % pk_value)
     
    778778        # is screwed up with the database, so display an error page.
    779779        if ERROR_FLAG in request.GET.keys():
    780780            return render_to_response('admin/invalid_setup.html', {'title': _('Database error')})
    781         return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1')
     781        return HttpResponseRedirect(request.full_path + '?' + ERROR_FLAG + '=1')
    782782    c = template.RequestContext(request, {
    783783        'title': cl.title,
    784784        'is_popup': cl.is_popup,
  • django/contrib/admin/views/decorators.py

     
    2222        post_data = _encode_post_data({})
    2323    return render_to_response('admin/login.html', {
    2424        'title': _('Log in'),
    25         'app_path': request.path,
     25        'app_path': request.full_path,
    2626        'post_data': post_data,
    2727        'error_message': error_message
    2828    }, context_instance=template.RequestContext(request))
     
    9999                        return view_func(request, *args, **kwargs)
    100100                    else:
    101101                        request.session.delete_test_cookie()
    102                         return http.HttpResponseRedirect(request.path)
     102                        return http.HttpResponseRedirect(request.full_path)
    103103            else:
    104104                return _display_login_form(request, ERROR_MESSAGE)
    105105
  • django/contrib/admin/views/doc.py

     
    2727
    2828def bookmarklets(request):
    2929    # Hack! This couples this view to the URL it lives at.
    30     admin_root = request.path[:-len('doc/bookmarklets/')]
     30    admin_root = request.full_path[:-len('doc/bookmarklets/')]
    3131    return render_to_response('admin_doc/bookmarklets.html', {
    3232        'admin_url': "%s://%s%s" % (request.is_secure() and 'https' or 'http', request.get_host(), admin_root),
    3333    }, context_instance=RequestContext(request))
  • django/contrib/databrowse/plugins/objects.py

     
    88    def model_view(self, request, model_databrowse, url):
    99        # If the object ID wasn't provided, redirect to the model page, which is one level up.
    1010        if url is None:
    11             return http.HttpResponseRedirect(urlparse.urljoin(request.path, '../'))
     11            return http.HttpResponseRedirect(urlparse.urljoin(request.full_path, '../'))
    1212        easy_model = EasyModel(model_databrowse.site, model_databrowse.model)
    1313        obj = easy_model.object_by_pk(url)
    1414        return render_to_response('databrowse/object_detail.html', {'object': obj, 'root_url': model_databrowse.site.root_url})
  • django/contrib/databrowse/sites.py

     
    110110
    111111        `url` is the remainder of the URL -- e.g. 'comments/comment/'.
    112112        """
    113         self.root_url = request.path[:len(request.path) - len(url)]
     113        self.root_url = request.full_path[:len(request.full_path) - len(url)]
    114114        url = url.rstrip('/') # Trim trailing slash, if it exists.
    115115
    116116        if url == '':
  • django/contrib/auth/views.py

     
    4747        return render_to_response(template_name, {'title': _('Logged out')}, context_instance=RequestContext(request))
    4848    else:
    4949        # Redirect to this page until the session has been cleared.
    50         return HttpResponseRedirect(next_page or request.path)
     50        return HttpResponseRedirect(next_page or request.full_path)
    5151
    5252def logout_then_login(request, login_url=None):
    5353    "Logs out the user if he is logged in. Then redirects to the log-in page."
     
    7575                form.save(domain_override=request.META['HTTP_HOST'])
    7676            else:
    7777                form.save(email_template_name=email_template_name)
    78             return HttpResponseRedirect('%sdone/' % request.path)
     78            return HttpResponseRedirect('%sdone/' % request.full_path)
    7979    return render_to_response(template_name, {'form': oldforms.FormWrapper(form, new_data, errors)},
    8080        context_instance=RequestContext(request))
    8181
     
    9090        errors = form.get_validation_errors(new_data)
    9191        if not errors:
    9292            form.save(new_data)
    93             return HttpResponseRedirect('%sdone/' % request.path)
     93            return HttpResponseRedirect('%sdone/' % request.full_path)
    9494    return render_to_response(template_name, {'form': oldforms.FormWrapper(form, new_data, errors)},
    9595        context_instance=RequestContext(request))
    9696password_change = login_required(password_change)
  • django/contrib/flatpages/views.py

     
    2525    # logged in, redirect to the login page.
    2626    if f.registration_required and not request.user.is_authenticated():
    2727        from django.contrib.auth.views import redirect_to_login
    28         return redirect_to_login(request.path)
     28        return redirect_to_login(request.full_path)
    2929    if f.template_name:
    3030        t = loader.select_template((f.template_name, DEFAULT_TEMPLATE))
    3131    else:
  • django/middleware/common.py

     
    3333
    3434        # Check for a redirect based on settings.APPEND_SLASH and settings.PREPEND_WWW
    3535        host = request.get_host()
    36         old_url = [host, request.path]
     36        old_url = [host, request.full_path]
    3737        new_url = old_url[:]
    3838        if settings.PREPEND_WWW and old_url[0] and not old_url[0].startswith('www.'):
    3939            new_url[0] = 'www.' + old_url[0]
  • AUTHORS

     
    319319    ymasuda@ethercube.com
    320320    Jarek Zgoda <jarek.zgoda@gmail.com>
    321321    Cheng Zhang
     322    John Melesky
    322323
    323324A big THANK YOU goes to:
    324325
  • docs/request_response.txt

     
    2424All attributes except ``session`` should be considered read-only.
    2525
    2626``path``
     27    A string representing the path to the requested page relative to
     28    the Django root, not including the domain. For WSGI servers, this
     29    means it does not include SCRIPT_NAME. For mod_python servers,
     30    this does not include the user-configurable django.root
     31    PythonOption.
     32
     33    Example: ``"/bands/the_beatles/"``
     34
     35``full_path``
    2736    A string representing the full path to the requested page, not including
    2837    the domain.
    2938
     
    112121        * ``REQUEST_METHOD`` -- A string such as ``"GET"`` or ``"POST"``.
    113122        * ``SERVER_NAME`` -- The hostname of the server.
    114123        * ``SERVER_PORT`` -- The port of the server.
     124        * ``SCRIPT_NAME`` -- The location of the Django app (e.g. "/mysite")
    115125
    116126``user``
    117127    A ``django.contrib.auth.models.User`` object representing the currently
     
    157167   ``request.POST`` has the given key.
    158168
    159169``get_full_path()``
    160    Returns the ``path``, plus an appended query string, if applicable.
     170   Returns the ``full_path``, plus an appended query string, if applicable.
    161171
    162172   Example: ``"/music/bands/the_beatles/?print=true"``
    163173
  • docs/modpython.txt

     
    3636        PythonHandler django.core.handlers.modpython
    3737        SetEnv DJANGO_SETTINGS_MODULE mysite.settings
    3838        PythonDebug On
     39        PythonOption django.root /mysite
    3940    </Location>
    4041
    4142...and replace ``mysite.settings`` with the Python import path to your Django
     
    4546Django mod_python handler." It passes the value of ``DJANGO_SETTINGS_MODULE``
    4647so mod_python knows which settings to use.
    4748
     49The PythonOption tells Django: "Pass all requests through to the application as
     50if they were rooted at '/', but generate absolute URLs under '/mysite'." This
     51way, Django applications can be installed in any subdirectory URL without
     52having the full path hardwired in.
     53
    4854Note that we're using the ``<Location>`` directive, not the ``<Directory>``
    4955directive. The latter is used for pointing at places on your filesystem,
    5056whereas ``<Location>`` points at places in the URL structure of a Web site.
     
    6066        PythonHandler django.core.handlers.modpython
    6167        SetEnv DJANGO_SETTINGS_MODULE mysite.settings
    6268        PythonDebug On
     69        PythonOption django.root /mysite
    6370        **PythonPath "['/path/to/project'] + sys.path"**
    6471    </Location>
    6572
Back to Top