URLs having issues with PATH_INFO when using twod.wsgi

Asked by George Marshall on 2011-08-15

Currently I'm having difficulty with Ladon and the URLs it's returning in both JSON and SOAP interfaces. Ladon is setup with twod.wsgi which allows for using WSGI apps as a view in Django. Ladon is working except for the URLs it is returning in all the interfaces.

The URL returned in Ladon looks like http://localhost:8000/WebService/soap/ when it should be http://localhost:8000/api/rpc/WebService/soap/.

Is there something I'm missing for having Ladon work under a path like the above?

Question information

English Edit question
ladon Edit question
jsgaarde Edit question
Solved by:
George Marshall
Last query:
Last reply:
jsgaarde (jakob-simon-gaarde) said : #1

Hi George.

That sounds odd. I don't know twod.wsgi. I need som more information to go on - it seems like the wsgi implementation is passing request uri path-information to the Ladon WSGI application in an unsupported manner (unsupported by Ladon at least :-) )

Could you create a very simple test WSGI application that can store the WSGI environ variable. Replace it temporarly with the Ladon handler and post the content of environ in this answer thread.

something like this:

def application(environ, start_response):

   response_body = str(environ)

   status = '200 OK'

   # Now content type is text/html
   response_headers = [('Content-Type', 'text/plain'),
                  ('Content-Length', str(len(response_body)))]
   start_response(status, response_headers)

   return [response_body]

Best Regards
Jakob Simon-Gaarde

Hey Jakob,

Here are the environment variables.
    'ARCHFLAGS': '-arch i386 -arch x86_64',
    'Apple_PubSub_Socket_Render': '/tmp/launch-XSkN13/Render',
    'BASIC_PROMPT': '\\[\\033[0;37m\\][\\t] \\[\\033[1;32m\\]\\u@\\h\\[\\033[1;37m\\]:\\[\\033[1;34m\\]\\w\\[\\033[0;37m\\]$\\[\\033[0m\\] ',
    'CLICOLOR': '1',
    'COMMAND_MODE': 'unix2003',
    'CONTENT_TYPE': 'text/plain',
    'DISPLAY': '/tmp/launch-6OmqAq/org.x:0',
    'DJANGO_SETTINGS_MODULE': 'settings_gmarshal',
    'EDITOR': 'mate -w',
    'HOME': '/Users/gmarshal',
    'HTTPS': 'off',
    'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'HTTP_ACCEPT_CHARSET': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
    'HTTP_ACCEPT_ENCODING': 'gzip,deflate,sdch',
    'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8',
    'HTTP_CACHE_CONTROL': 'max-age=0',
    'HTTP_CONNECTION': 'keep-alive',
    'HTTP_COOKIE': 'sessionid=ef0ea9244b8aabedce71791a4286af11; csrftoken=fe5f99858b13d79b624004b62dd47b5f; SDSESSIONID=acbd9a98140e89fcf3f424fc5f4842cb; django_language=en-US',
    'HTTP_HOST': 'localhost:8000',
    'HTTP_PROXY_CACHEKEY': 'myfakesalt',
    'HTTP_PROXY_UID': 'gmarshal',
    'HTTP_SM_USER': 'gmarshal',
    'HTTP_USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.35 Safari/535.1',
    'HTTP_X_AWS_USERNAME': 'gmarshal',
    'LANG': 'en_US.UTF-8',
    'LOGNAME': 'gmarshal',
    'MY_PROMPT': '\\[\\033[0;37m\\][\\t] \\[\\033[1;32m\\]\\u\\[\\033[1;37m\\]@\\[\\033[1;31m\\]\\h \\[\\033[1;34m\\]\\w\\[\\033[0;37m\\]$(__git_ps1)$(__hg_ps1)$(__svn_ps1)\\n\\[\\033[1;37m\\]$(prompt_char)\\[\\033[0m\\] ',
    'OLDPWD': '/Users/gmarshal/projects/portal/site/api/rpc',
    'PATH': '/Users/gmarshal/portal/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin:/usr/X11/bin:/Users/gmarshal/bin:/opt/local/bin',
    'PATH_INFO': u'/api/rpc/',
    'PS1': '(portal)\\[\\033[0;37m\\][\\t] \\[\\033[1;32m\\]\\u\\[\\033[1;37m\\]@\\[\\033[1;31m\\]\\h \\[\\033[1;34m\\]\\w\\[\\033[0;37m\\]$(__git_ps1)$(__hg_ps1)$(__svn_ps1)\\n\\[\\033[1;37m\\]$(prompt_char)\\[\\033[0m\\] ',
    'PWD': '/Users/gmarshal/portal/site',
    'QUERY_STRING': '',
    'REMOTE_ADDR': '',
    'REMOTE_HOST': '',
    'RUN_MAIN': 'true',
    'SCRIPT_NAME': u'',
    'SERVER_NAME': 'localhost',
    'SERVER_PORT': '8000',
    'SERVER_SOFTWARE': 'WSGIServer/0.1 Python/2.6.1',
    'SHELL': '/bin/bash',
    'SHLVL': '1',
    'SSH_AUTH_SOCK': '/tmp/launch-oTF2yz/Listeners',
    'TERM': 'xterm-color',
    'TERM_PROGRAM': 'Apple_Terminal',
    'TERM_PROGRAM_VERSION': '273.1',
    'TMPDIR': '/var/folders/Rx/RxLwMjH5G5eAlbu1Y4XikbTJz46/-Tmp-/',
    'TZ': 'UTC',
    'USER': 'gmarshal',
    'VIRTUAL_ENV': '/Users/gmarshal/projects/portal/',
    '_': '/Users/gmarshal/projects/portal/bin/python',
    '__CF_USER_TEXT_ENCODING': '0x77D5FC62:0:0',
    'request_time': 1313446204.253623,
    'webob.adhoc_attrs': {
        'LANGUAGE_CODE': 'en',
        'session': <django.contrib.sessions.backends.cache.SessionStore object at 0x102d26a10>,
        'user': <User: gmarshal>
    'wsgi.errors': <open file '<stderr>', mode 'w' at 0x100416140>,
    'wsgi.file_wrapper': <class wsgiref.util.FileWrapper at 0x1024c47d0>,
    'wsgi.input': <cStringIO.StringI object at 0x1033aba20>,
    'wsgi.multiprocess': False,
    'wsgi.multithread': True,
    'wsgi.run_once': False,
    'wsgi.url_scheme': 'http',
    'wsgi.version': (1, 0)

jsgaarde (jakob-simon-gaarde) said : #3

Hi George.

That's even more odd, cause it looks like environ['PATH_INFO'] is as it should be.
Let's try this: re-write the test-handler to pickle the result:

import pickle
def application(environ, start_response):

   response_body = pickle.dumps(environ)

   status = '200 OK'

   # Now content type is text/html
   response_headers = [('Content-Type', 'text/plain'),
                  ('Content-Length', str(len(response_body)))]
   start_response(status, response_headers)

   return [response_body]

pastebin the result so I can load the environment into my system.

Best Regards
Jakob Simon-Gaarde

Hi Jakob,

I've setup a sample Django project that mirrors the setup that I'm using. This should allow you to tear into the code a bit more.


Then just cd into the project dir and run the following.

virtualenv --no-site-packages .
pip install -r requirements.txt
cd example
./manage.py runserver

Left out a command

virtualenv --no-site-packages .
source bin/activate
pip install -r requirements.txt
cd example
./manage.py runserver

jsgaarde (jakob-simon-gaarde) said : #6

Hi George.

I installed and ran your example, but I get a completely different PATH_INFO value than the one you pasted earlier. In fact I get a PATH_INFO value that matches the behavior of Ladon: http://paste.ubuntu.com/667090/plain/

As you can see PATH_INFO is '/', now look at this documentation regarding HttpRequest.path_info found here: https://docs.djangoproject.com/en/dev/ref/request-response/#httprequest-objects

"The path_info attribute always contains the path info portion of the path, no matter what Web server is being used."
I guess there is always an exception to a rule ;-)

Anyway blaming the server portion of your solution won't solve your problem, so I have decided to make a patch for Ladon that will enable you to forcibly set the Ladon client root path:


Note: This will be included in the next version of Ladon.

When you have patched your local Ladon version all you need to do is add the client root path in your LadonWSGIApplication initializer:


Best Regards
Jakob Simon-Gaarde

Hi Jakob,

Thanks for the patch, it did what I was looking for but didn't work quite right. I fixed the problems it was causing and have created a new patch. http://paste.ubuntu.com/667762/

I have also updated the sample project code. https://github.com/georgemarshall/django_wsgi_view