Reputation: 141
I'm trying to build a cors proxy through flask from scratch. Here's my code
@app.route('/api/v1/cors/url=<name>&method=<method>', methods=['GET'])
def api_cors(name, method):
if method == 'http' or method == 'https':
r = request.urlopen(method+"://"+name)
return r.read()
else:
return "method not set!"
It is working good so far but I have one problem, when I pass "url=google.com&method=https" it is working fine but when I pass something like "url=google.com/images/image.jpg&method=https" the "/" will considered as a new directory
Is there anyway to evade this in flask?
Upvotes: 2
Views: 2725
Reputation: 2307
In my use-case I am building a MS Graph file browser which receives a @odata.nextLink
value from Graph API calls, which look like https://graph.microsoft.com/v1.0/groups/myGroupId/drive/items('driveItem')/children?$select=id,name,webUrl&$top=10&$skiptoken=someToken.
In my main python script I add a quote
function to the jinja environment using urllib.parse.quote
. We need this to encode the URLs within our jinja templates:
import urllib
app.jinja_env.globals.update(Auth=identity.web.Auth, quote=urllib.parse.quote)
In my Jinja template I use the following to encode the result['@odata.nextLink']
URL and make sure to set safe=''
so the /
characters are also encoded. This encoded URL is sent to our odNextLink
route:
<a href="{{ url_for('odNextLink', nextLink=quote(result['@odata.nextLink'], safe='')) }}">Next link</a>
In our route we need to make sure we have import urllib
so we can unencoded the URL using urllib.parse.unquote(nextLink)
before calling the API endpoint.
# this route should return results from a Graph API 'nextLink' call
@app.route("/od_group_items/<nextLink>")
def odNextLink(nextLink):
import urllib
token = app.auth.get_token_for_user(ast.literal_eval(os.getenv('SCOPE')))
if "error" in token:
return redirect(url_for("login"))
api_result = requests.get(
urllib.parse.unquote(nextLink),
headers={'Authorization': 'Bearer ' + token['access_token']},
timeout=30,
).json()
return api_result
Upvotes: 0
Reputation: 909
If you want use the same URL scheme that you're using now, change your routing decorator to this and it will work.
@app.route('/api/v1/cors/url=<path:name>&method=<method>', methods=['GET'])
Upvotes: 2
Reputation: 599580
Don't try and pass the value as part of the route itself. Pass it as a query parameter.
@app.route('/api/v1/cors/')
def api_cors():
url = request.args.get('url')
and call it as "/api/v1/cors/?url=https://google.com/images/image.jpg"
.
Upvotes: 4