Skip to content

Path is always set to "/" using unicode wsgi protocol under Python 3 #1350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ghost opened this issue Dec 29, 2014 · 7 comments
Closed

Path is always set to "/" using unicode wsgi protocol under Python 3 #1350

ghost opened this issue Dec 29, 2014 · 7 comments

Comments

@ghost
Copy link

ghost commented Dec 29, 2014

Originally reported by: Lars Gustäbel (Bitbucket: gustaebel, GitHub: gustaebel)


I am using a cherrypy server with wsgi_version = ("u", 0) under Python 3, and found a bug in _cherrypy.cptree.Tree.call().

The problematic code is the following:

#!python

env1x = environ
if environ.get(ntou('wsgi.version')) == (ntou('u'), 0):
    env1x = _cpwsgi.downgrade_wsgi_ux_to_1x(environ)
path = httputil.urljoin(env1x.get('SCRIPT_NAME', ''),
                        env1x.get('PATH_INFO', ''))
sn = self.script_name(path or "/")

The unicode environment is converted to bytes (in Python 3) in order to assemble the path from SCRIPT_NAME and PATH_INFO. The problem is that after this conversion all keys are bytes objects, so both env1x.get() calls fail and return the empty string. This in turn leads to httputil.urljoin() returning the empty string which is then replaced by "/" in the script_name() call.

So, whatever url you pass to Tree.call() they all get converted to "/". My solution to this problem is to test for py3k before downgrade_wsgi_ux_to_1x(). A patch is attached.

#!python

if py3k:
    if environ.get(ntou('wsgi.version')) == (ntou('u'), 0):
        env1x = _cpwsgi.downgrade_wsgi_ux_to_1x(environ)

@ghost
Copy link
Author

ghost commented Mar 29, 2016

Original comment by David Eriksson (Bitbucket: softhousedae, GitHub: Unknown):


Not fixed in over a year even when there is a patch? :-(

Runtime workaround:

#!python

cherrypy._cpwsgi.downgrade_wsgi_ux_to_1x = lambda env: env

@ghost ghost added major bug labels Apr 30, 2016
@webknjaz
Copy link
Member

webknjaz commented Sep 23, 2016

@gustaebel @twogood could you please confirm that the issue still exists for the latest version of CherryPy?

@twogood
Copy link

twogood commented Sep 23, 2016

@webknjaz For various reasons I'm still stuck on an old version of CherryPy, thanks for reminding me of upgrading. I did try a newer version at some point, but my application broke down, so there will be Work involved... :-)

@gustaebel
Copy link

I tried the version 8.1.0 of cherrypy but got the following traceback:

Traceback (most recent call last):
  File "/usr/lib/python3.5/site-packages/cherrypy/wsgiserver/__init__.py", line 1406, in communicate
    req.respond()
  File "/usr/lib/python3.5/site-packages/cherrypy/wsgiserver/__init__.py", line 860, in respond
    self.server.gateway(self).respond()
  File "/usr/lib/python3.5/site-packages/cherrypy/wsgiserver/__init__.py", line 2310, in __init__
    self.env = self.get_environ()
  File "/usr/lib/python3.5/site-packages/cherrypy/wsgiserver/__init__.py", line 2498, in get_environ
    env = dict(map(self._decode_key, self.items()))
AttributeError: 'WSGIGateway_u0' object has no attribute 'items'

With the following patch applied, all seems to work well :-)

diff --git a/cherrypy/wsgiserver/__init__.py b/cherrypy/wsgiserver/__init__.py
index 77fb361..98607e4 100644
--- a/cherrypy/wsgiserver/__init__.py
+++ b/cherrypy/wsgiserver/__init__.py
@@ -2497,7 +2497,7 @@ class WSGIGateway_u0(WSGIGateway_10):
         """Return a new environ dict targeting the given wsgi.version"""
         req = self.req
         env_10 = WSGIGateway_10.get_environ(self)
-        env = dict(map(self._decode_key, self.items()))
+        env = dict(self._decode_key(k, v) for k, v in env_10.items())
         env[six.u('wsgi.version')] = ('u', 0)

         # Request-URI
@@ -2511,7 +2511,7 @@ class WSGIGateway_u0(WSGIGateway_10):
             env['PATH_INFO'] = env_10['PATH_INFO']
             env['QUERY_STRING'] = env_10['QUERY_STRING']

-        env.update(map(self._decode_value, self.items()))
+        env.update(dict(self._decode_value(k, v) for k, v in env_10.items()))

         return env

@webknjaz
Copy link
Member

@gustaebel feel free to send a PR along with tests

@jaraco
Copy link
Member

jaraco commented Sep 28, 2016

It seems like the use of self.items is a bug going back to f2ec506.

@jaraco
Copy link
Member

jaraco commented Mar 12, 2017

Meant to mention this ticket in 481b6f9, but mistakenly mentioned another.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants