WSGI doesn't support Absolute URL (HTTP/1 compat)

Bug #1517673 reported by Vijay Panghal
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Object Storage (swift)
Fix Released
Undecided
Unassigned

Bug Description

When http request contains absolute URL rather than absolute PATH, swift returns 401 unauthorized Temp url Invalid in response.

I have looked at the swift implementation, and this specific code is causing the problem
<pre>
if env['REQUEST_METHOD'] in self.methods:
            try:
                self.logger.debug("%s", env['PATH_INFO'])
                ver, acc, cont, obj = split_path(env['PATH_INFO'], 4, 4, True) <<<< This is throwing ValueError
            except ValueError as v:
                return None
            if ver == 'v1' and obj.strip('/'):
                return acc

</pre>

In failure case,
<pre>
env['PATH_INFO'] = https://xxxxx:8095/v1/AUTH_encmzh/container/object1
</pre>

In success case,
<pre>
env['PATH_INFO'] = /v1/AUTH_encmzh/container/object1
</pre>

As per RFC https://tools.ietf.org/html/rfc2616#section-5.1.2, both URL and PATH are acceptable in request line. But Swift falls over for Absolute URL one.

I am facing this issue when I am accesing swift over https proxy. Where client passes the absolute URL in http request line.

clayg (clay-gerrard)
summary: - Swift returns 401 unauthorized Invalid TempUrl on Absolute URL
+ WSGI doesn't support Absolute URL (HTTP/1 compat)
Revision history for this message
clayg (clay-gerrard) wrote :

wsgiref doesn't really say what should be done about absolute uri - open bug upstream with no obvious suggestion (beyond the obviou "fix PATH_INFO and keep full uri around somewhere").

I think this is another reason [1] we need to pass our own HTTPProtocol class to the eventlet WSGI server. Then I think fairly early we could call urlparse on PATH_INFO in the environ and put the relative bits in there.

To get started I ran this:

    import socket

    sock = socket.socket()
    sock.connect(('127.0.0.1', 8080))
    sock.sendall('GET http://localhost:8080/auth/v1.0 HTTP/1.1\r\n\r\n')
    print sock.recv(100)

Plus a `print self.environ` in swob.Request.split_path.

1. lp bug #1467155 being another recent one that comes to mind.

Revision history for this message
Samuel Merritt (torgomatic) wrote :

This one required a bit of pointer-chasing, but I'm confident now that the bug is in the WSGI server, not Swift.

When it comes to PATH_INFO and some other environment variables, PEP 3333 delegates that to the CGI specification [1]. CGI, in turn, has this little nugget of wisdom regarding PATH_INFO:

    The syntax and semantics are similar to a decoded HTTP URL `hpath' token (defined in RFC 1738 [3]), with the exception that a PATH_INFO of "/" represents a single void path segment.

So now we go look at RFC 1738 [2] for what an hpath token is, and we get some grammar:

    ; HTTP

    httpurl = "http://" hostport [ "/" hpath [ "?" search ]]
    hpath = hsegment *[ "/" hsegment ]
    hsegment = *[ uchar | ";" | ":" | "@" | "&" | "=" ]
    search = *[ uchar | ";" | ":" | "@" | "&" | "=" ]

That seems pretty clear (as clear as BNFs get, at any rate) that PATH_INFO is only the path part of the URL. In the first example given, PATH_INFO should be "/v1/AUTH_encmzh/container/object1" and should not contain the protocol, hostname, and other garbage.

[1] CGI specification version 1.1: http://graphcomp.com/info/specs/cgi11.html

[2] http://www.rfc-base.org/txt/rfc-1738.txt

Revision history for this message
clayg (clay-gerrard) wrote :

yeah definitely an oversight in the particular WSGI implementation we happen to use - I'm sure upstream eventlet would welcome a fix - but it's not very clear what the expected handling is according to the pep.

I mean if it was obvious according to the WSGI spec how this should be handled I think wsgiref would have done it by now [1].

1. https://bugs.python.org/issue21472 <- forgot to link the upstream bug for this gap in WSGI

Revision history for this message
Thiago da Silva (thiagodasilva) wrote :

bug was fixed in eventlet

Changed in swift:
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.