Open defnull opened 9 years ago
What effect would this have on cross-domain redirects?
It had entered for the 0.12+ or just 0.13?
What effect would this have on cross-domain redirects?
@shakna-israel , like this (?) --
bottle.redirect('//my-other-domain.com/my-page/123')
or something another?
@polymorphm, That sounds good. Sorry for weighing in, just developing a CORS app at the moment, and it tends to be the kind of thing that breaks when trying to match URI compliance.
@shakna-israel , please , try check this changing in your CORS-apps
diff --git a/bottle.py b/bottle.py
index 535ddd3..359ceaf 100644
--- a/bottle.py
+++ b/bottle.py
@@ -2418,7 +2418,7 @@ def redirect(url, code=None):
res = response.copy(cls=HTTPResponse)
res.status = code
res.body = ""
- res.set_header('Location', urljoin(request.url, url))
+ res.set_header('Location', url)
raise res
I think this check-result -- is will be important for all
@polymorphm, it seems to work absolutely fine.
The solution proposed by @polymorphm meets our case.
I think this should be linked to the following related issues: #748 and (the much older) #293
In my case, I have an application deployed on Apache with mod_wsgi at a subdirectory (e.g. example.com/myapp/). From my virtualhost config:
WSGIScriptAlias /myapp /var/www/myapp/app.wsgi
# ...
And in myapp.py:
@route('/<dirname>')
def bare_dir(dirname):
redirect('/%s/' % dirname)
Even though the /<dirname>
path matches example.com/myapp/abc
, the browser is redirected to example.com/abc/
. I need to use the following:
@route('/<dirname>')
def bare_dir(dirname):
redirect('%s/' % dirname) # no leading slash
I'm not an expert on web standards, so maybe this is the intended usage? But I expected a /url/
redirect to go to the application root and not the server root (as described in #293).
The server/app root problem is a very common and annoying thing. Unfortunately, there is no reliable way to know about the 'application root' other than configuration. A proxy could redirect arbitrary urls to the application, rewriting the URL in any way desirable. There is SCRIPT_PATH
but that has its own issues.
Currently bottle resolves relative URLs against something it thinks is the server root. It uses request.url
which is reconstructed out of different CGI parameters and breaks easily for proxied applications. So, by removing the automatic urljoin()
, we would not change behavior for most apps expect for broken proxy configurations, which is acceptable I think.
Magically prefixing redirect paths with SCRIPT_PATH
or a configurable 'application root' would however break existing applications, so that is not an option. You could define your own patched redirect()
function in two or three lines of code it you really want this behavior.
I tent do (finally) just pull this simple change, and if we find out later that the missing urljoin breaks reasonable existing applications, we could still make it configurable.
In #747 @polymorphm pojnted out that according to RFC7231 (which obsoletes RFC2616) relative URLs in the Location header are allowed.
Current behavior: Bottle tries to turn relative URLs in
bottle.redirect()
calls into absolute URLs by joining with therequest.url
string. See https://github.com/bottlepy/bottle/blob/master/bottle.py#L2445New behavior: Bottle just passes the provided URI as is. No URL-joining will be performed.
This behavior change should have no effect on well behaved clients. Relative URLs in
Location
headers are supported by all client libraries I know of because it is a common (previously non-standard but now allowed) practice for years now.It is still a behavior change with no obvious upgrade path. This is why I opened this issue. If you can think of a situation where this change breaks an existing application, or introduce a security risk, please speak up.