Reputation: 183
I'm trying to execute curl command in python script and couldn't pass a password with symbols.
import os;
os.system("curl -H 'Content-Type: text/xml;charset=UTF-8' -u 'appuser:appuser!@3pass' -i -v 'http://app.com/webservice/getUserData' -o userdata.xml")
And I get Access Denied message in return, the username and password are correct. I guess it is because of the special characters in the password.
I have tried escape the characters like appuser\!\@3pass
but didn't help.
Can anyone guide through this?
Upvotes: 1
Views: 1242
Reputation: 140168
the command you're using cannot work because single quotes have no special meaning in Windows, they're passed literally to the curl
program. So if you copied the command line from Linux (where it would work), that won't work here (spurious quotes are passed to curl
for instance for the login/password field which recieves 'appuser
and appuser!@3pass'
, also Content-Type: text/xml;charset=UTF-8
isn't protected at all and is understood as 2 separate arguments)
Simple test from the console:
K:\progs\cli>curl.exe -V
curl 7.50.3 (x86_64-pc-win32) libcurl/7.50.3 OpenSSL/1.0.2h nghttp2/1.14.1
Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtsp smb smbs smtp smtps
telnet tftp
Features: AsynchDNS IPv6 Largefile NTLM SSL HTTP2
(also works if I use "-V"
with double quotes), but if I use simple quoting on the version arg I get:
K:\progs\cli>curl.exe '-V'
curl: (6) Could not resolve host: '-V'
As o11c commented, there's a python module to handle curl, you'd be better off with it.
For other cases when you can't do otherwise, using os.system
is deprecated. Using subprocess.check_call
for instance is better (python 3.5 has a unified run
function):
Let's fix your example:
subprocess.check_call(["curl","-H","Content-Type: text/xml;charset=UTF-8","-u",'appuser:appuser!@3pass',"-i","-v",'http://app.com/webservice/getUserData',"-o","userdata.xml"])
note that I purposedly mixed single & double quotes. Python doesn't care. And if there's a space in the argument, check_call
mechanism manages to handle argument protection/quoting automatically.
when calling this script I get userdata.xml
filled in like:
HTTP/1.1 301 Moved Permanently
Date: Fri, 15 Sep 2017 20:49:50 GMT
Server: Apache
Location: http://www.app.com/webservice/getUserData
Content-Type: text/html; charset=iso-8859-1
Transfer-Encoding: chunked
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.app.com/webservice/getUserData">here</a>.</p>
</body></html>
Upvotes: 4