Skip to content
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

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

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
Labels

Comments

@ghost
Copy link

@ghost 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 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 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 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

@gustaebel gustaebel commented Sep 26, 2016

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

@webknjaz webknjaz commented Sep 26, 2016

@gustaebel feel free to send a PR along with tests

@jaraco
Copy link
Member

@jaraco jaraco commented Sep 28, 2016

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

@jaraco jaraco closed this in 6efc7ac Sep 28, 2016
jaraco referenced this issue Mar 12, 2017
@jaraco
Copy link
Member

@jaraco 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
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.