'Python download request fails when file name has a plus (+) sign
I'm writing an application in Python to download files from a server (actually a NAS) of a friend of mine that we use for file sharing. I use its official API combined with the requests module.
Application has a bug that when the file requested has a plus (+) sign in the name the request response is "Bad gateway" (502) instead of OK (200) and download fails because it can't find the file.
If I remove the plus sign from the file name, it works.
If the name has any other special characters like underscores, dots, parenthesis, brackets, etc. it works.
Error only happens when a plus sign.
I know it has something to do with url encode skipping the plus sign for some reason and not converting it into a "%2B" which I think would be the expected behaviour if I'm not wrong.
I've seen here many questions talking about the urllib module but not sure if that's what I need and how I would use it to encode the. After many days of heavy researching I can't figure out how to fix this.
The line of code that sets the download request URL is:
download_request = requests.get(url+DOWNLOAD_API.format(path, file, sid), stream=True)
DOWNLOAD_API is:
DOWNLOAD_API = 'webapi/entry.cgi?api=SYNO.FileStation.Download&version=2&method=download&path=/{}/{}&mode=open&_sid={}'
Example of final URL causing the error:
'https://mynas.quickconnect.to:65375/webapi/entry.cgi?api=SYNO.FileStation.Download&version=2&method=download&path=/video/Example%20file+.txt&mode=open&_sid=qoHtK6Lu2TChqMJzMov65_yOg3c4e9hXKG8BTq-z3zUrbOQd2AFoEJNhSuN3uFfWFAQNh-Hf53E3nZ1v6ggX7A'
I've been looking for how to ask a good question in Stackoverflow because I'm not very used to it. Hopefully I did well.
Thanks in advance.
Solution 1:[1]
@JonClements answer was correct.
If you format the URL like I was doing:
download_request = requests.get(url+DOWNLOAD_API.format(path, file, sid), stream=True)
then you have to manually encode plus signs as %2B. Instead, you want to set all the parameters within the requests.get method, like this:
download_request = requests.get(url,
params={'api':'SYNO.FileStation.Download', 'version': 2, 'method':'download', 'path':"/"+path+"/"+file, 'mode':'open', '_sid':sid},
stream=True)
Now it works. Bug is fixed.
Thank you so much!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | AlexMnrs |
