Я был использован для отправки XML строк в API моего брандмауэра с помощью этой команды cURL:
curl -k https://192.1.1.1:90/APIController -F "reqxml=<myfile.xml"
Теперь я хотел бы сделать это в python. Поскольку строка XML будет создаваться программно, я не предоставляю файл XML, а строку XML. Это мой код прямо сейчас:
#!/usr/bin/env python
import requests
def xml_string():
return '''
reqxml=<?xml version="1.0" encoding="UTF-8"?>
<Request>
<Login>
<Username>admin</Username>
<Password>admin</Password>
</Login>
<Set>
… further markup …
</Set>
</Request>
'''
def send_xml():
response = requests.post(
"https://192.1.1.1:90/APIController",
headers={"Content-Type": "application/xml"},
data=xml_string(),
verify=False
)
print(response.status_code)
send_xml()
Вывод подробной команды curl -k -v https://192.1.1.1:90/APIController -F "reqxml=<testcategory.xml"
:
* Trying 192.1.1.1...
* TCP_NODELAY set
* Connected to 192.1.1.1 (192.1.1.1) port 90 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=NA …
* start date: Aug 1 00:00:00 2010 GMT
* expire date: Dec 31 23:59:59 2030 GMT
* issuer: C=NA …
* SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway.
> POST /APIController HTTP/1.1
> Host: 192.1.1.1:90
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 796
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------20be8a5c28d38998
>
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Date: Sun, 26 Apr 2020 10:07:59 GMT
< Server: xxxx
< X-Frame-Options: SAMEORIGIN
< Strict-Transport-Security: max-age=31536000
< X-Content-Type-Options: nosniff
< Content-Type: text/xml; charset=UTF-8
< Cache-Control: max-age=2592000
< Expires: Tue, 26 May 2020 10:07:59 GMT
< Transfer-Encoding: chunked
<
<?xml version="1.0" encoding="UTF-8"?>
<Response APIVersion="1702.1" IPS_CAT_VER="1">
<Login>
<status>Authentication Successful</status>
</Login>
<Status code="200">Configuration applied successfully.</Status>
</Response>
* Connection #0 to host 192.1.1.1 left intact
Но несмотря на то, что возвращенный код состояния равен 200, команда не имела никакого эффекта на брандмауэре настройки не были изменены. Почему код python не работает должным образом?
РЕДАКТИРОВАТЬ: я обнаружил, что строка XML полностью игнорируется при запуске кода выше python. Может быть, этот рабочий код в PHP может пролить немного света?
<code><?php
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<Request>
<Login>
<Username>admin</Username>
<Password>admin</Password>
</Login>
<Set>
…
</Set>
</Request>';
$url = "https://192.1.1.1:90/APIController";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_POSTFIELDS, "reqxml=" . $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
echo '<pre>';
echo htmlentities($data);
echo '
'; if (curl_errno ($ ch)) {print curl_error ($ ch); } else {curl_close ($ ch); }?>