0

I'm trying to redirect to a Graphite URL with Flask. The graphite URLs I'm building are complex and must include the literal characters {, }, and |. Flask is escaping them to %7B %7C and %7D.

Is there any way I can stop this? On the graphite side, I want a target that looks like this: sumSeries({metric|metric|metric})

@app.route("/")
def index():
  instances = get_data()
  url = build_graphite_url(instances)
  print url
  return redirect(url)
andyhky
  • 1,798
  • 1
  • 17
  • 30
  • I don't beleive you can use these characters in URLs. [See here](http://www.blooberry.com/indexdot/html/topics/urlencoding.htm) – Joe Doherty Aug 19 '13 at 15:47
  • 3
    if you think is `Flask` escaping uncorrectly, try to make a `Response` object with a line `Location: url` and a `302` status code. That's what redirect does. More info here: http://flask.pocoo.org/docs/api/#flask.Flask.make_response – Paolo Casciello Aug 19 '13 at 16:19

1 Answers1

2

If you dig into the Flask source you will eventually run into a function called get_wsgi_headers in wrappers.py under werkzeug: See here.

This function is called when the final response is created and returned, and if you scroll down a little you will find that it checks to see if a location header was set and if so, does some auto correction to make sure the url is absolute. During this time, it needs to escape the url, which is why your URL is escaped.

From the best of my knowledge, the only way to prevent this is to patch get_wsgi_headers so that it will basically not escape certain characters, since after all Flask is open source :)

Also as a side note, the reason why you cannot listen for the after_request callback and modify the response headers is because werkzeug's get_wsgi_headers is called after the callback, so whatever Location you set in the callback will end up being escaped as well.

smaili
  • 1,245
  • 9
  • 18