serveDirectory and request strings #72

jaspervdj opened this Issue May 19, 2011 · 0 comments


None yet
2 participants

jaspervdj commented May 19, 2011

To reproduce this issue, simply start a static file server (Snap.Util.FileServe) and request something like:

curl -i 'localhost:8000?mee'

Expected behavior is that the static server will return, for example:

  • redirect to 'localhost:8000/'
  • directly serve the contents of 'localhost:8000/index.html'

What happens? The server returns:

HTTP/1.1 302 Found
Location: /?mee/mee

The browser will follow this redirect, requesting /?mee/mee. The issue will then simply repeat itself as the server will return

HTTP/1.1 302 Found
Location: /?mee/mee/mee/mee

Spawning a redirect loop. I think this is a pretty serious issue, so I've dug a little deeper. The redirect is created in src/Snap/Util/FileServe.hs:444

redirect $ rqURI rq `S.append` "/" `S.append` rqQueryString rq

Printing a little debug info, we receive for our first request to localhost:8000?mee:

Uri: "/?mee"
QueryString: "mee"

Which makes sense if you look at src/Snap/Internal/Http/Server.hs:630:

(pathInfo, queryString) = first dropLeadingSlash . second (S.drop 1) $
                          S.break (== (c2w '?')) uri

So there are two solutions: using contextPath </> pathInfo in the FileServe module, or dropping ?mee from the URI. I have implemented the latter, because of this identity currently given in the documentation of Request:

rqURI r == S.concat [ rqSnapletPath r, rqContextPath r, rqPathInfo r ]

But, this causes code such as:

redirect $ rqURI rq `S.append` "/" `S.append` queryString

to fail, because it now redirects to /mee. At this point, I think the input of people who actually know something about Snap would be appreciated.

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