Which seems to suggest what you are seeing. Perhaps there's an ENV variable that can provide the un-manipulated args?
I'll be addressing this in the new URL rewriting mechanism. In the meantime, have a look at the raw_args option in routes.py:
# specify a list of apps that bypass args-checking and use request.raw_args
#
#routes_apps_raw=['myapp']
#routes_apps_raw=['myapp', 'myotherapp']
This is a hack to work around the problem. If you list your app in this routing variable, request.args will be set to None, and the (mostly) unprocessed args will appear as a string in request.raw_args. You'll need to split them yourself and do whatever processing you need.
Alternatively, experiment with using the query string (vars) instead of args.
Ok, I'm gonna experiment with raw_args.I was wondering what's this #routes_apps_raw=['myapp'] thing before (I was customizing routes)
When I use this functionality, am I correct in assuming that, I've to do encoding and decoding both?I can decode request.raw_args.But where did I encode?I'm using URL function.So, should I encode return value of URL function or individual arguments and variables that I'm passing?
urllib.quote(string[, safe])Replace special characters in string using the %xx escape. Letters, digits, and the characters '_.-' are never quoted. By default, this function is intended for quoting the path section of the URL.The optional safe parameter specifies additional characters that should not be quoted — its default value is '/'.
Example: quote('/~connolly/') yields '/%7econnolly/'.
urllib.quote_plus(string[, safe])
Like quote(), but also replaces spaces by plus signs, as required for quoting HTML form values when building up a query string to go into a URL. Plus signs in the original string are escaped unless they are included in safe. It also does not have safe default to '/'.
urllib.urlencode(query[, doseq])
Convert a mapping object or a sequence of two-element tuples to a “percent-encoded” string, suitable to pass to urlopen()above as the optional data argument. This is useful to pass a dictionary of form fields to a POST request. The resulting string is a series of key=value pairs separated by '&' characters, where both key and value are quoted usingquote_plus() above. When a sequence of two-element tuples is used as the query argument, the first element of each tuple is a key and the second is a value. The value element in itself can be a sequence and in that case, if the optional parameter doseq is evaluates to True, individual key=value pairs separated by '&' are generated for each element of the value sequence for the key. The order of parameters in the encoded string will match the order of parameter tuples in the sequence. The urlparse module provides the functions parse_qs() and parse_qsl() which are used to parse query strings into Python data structures.
Also, will you help me by giving difference between urllib.quote() and urllib.quote_plus() and it's use case.I haven't got that much experience with urllib class.
I suggest this:
file_match = re.compile(r'([\w@ -][=.]?)+$')
def download():
file = request.raw_args.split('/')[-1]
if not file_match.match(file):
raise HTTP(400, thread.routes.error_message % 'invalid request',
web2py_error='invalid args')
request.args = [file]
return response.download(request, db)
Notice that response.download will be looking at args[-1]; that's why we're taking [-1] above.
Massimo's point is important: when you use raw_args, it's your responsibility to validate each arg; otherwise you're opening yourself up to attack.
file_match above is the standard arg-checking pattern.