Recientemente extendí una API de Python para las API de almacenamiento de Windows Azure (PyAzure) para incluir compatibilidad con las API de administración de servicios. Ver https://github.com/bmb/pyazure.Python HTTPS contra la API de administración de servicios de Azure falla en Windows
Estoy usando un HTTPSClientAuthHandler como el sugerido en using pyOpenSSL to create urllib custom opener. En Linux, con varias versiones de Python 2.6 y 2.7 esto funciona bien. Sin embargo, Windows es otra historia. Todas las peticiones en contra de la dirección de host de administración Azure fallan con:
[Errno 10054] Una conexión existente forzosamente fue cerrada por el host remoto
Lo que creo, es el restablecimiento de conexión socket errno 10054" por peer ", en arrastre.
Esto no parece ser un problema en mi código API (a menos que el método de autenticación de certificado de cliente que estoy usando es falsa de alguna manera), pero algo de nivel inferior. Puedo reproducir el problema sin urllib2 o httplib simplemente configurando un socket SSL y enviando la misma solicitud HTTP por el canal como lo haría urllib2, p. para enumerar las ubicaciones de los centros de datos válidos Azure:
>>> import socket, ssl, sys
>>> sys.version
'2.7.1 (r271:86832, Nov 27 2010, 17:19:03) [MSC v.1500 64 bit (AMD64)]'
>>> s = ssl.wrap_socket(socket.socket(), certfile='c:\\users\\blair\\research\\clouds\\azure\\BlairBethwaiteAzure1.pfx.pem')
>>> s.connect(('management.core.windows.net',443))
>>> s.send("GET /SUBSCRIPTION_ID/locations HTTP/1.1\r\nAccept-Encoding: identity\r\nX-Ms-Version: 2011-10-01\r\nHost: management.core.windows.net\r\nConnection: close\r\nUser-Agent: Python-urllib/2.6\r\n\r\n")
202
>>> s.read()
Traceback (most recent call last):
c:\Users\blair\research\clouds\azure\pyazure\<ipython-input-63-3306c981d8a7>
in <module>()
----> 1 s.read()
C:\Python27\lib\ssl.pyc in read(self, len)
136
137 try:
--> 138 return self._sslobj.read(len)
139 except SSLError, x:
140 if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
error: [Errno 10054] An existing connection was forcibly closed by the remote host
Reemplazar SUBSCRIPTION_ID arriba, con su ID de suscripción Azure. La excepción se aumenta ~ 45s después de llamar a SSLSocket.read. El certificado es un archivo PEM con el formato adecuado que incluye tanto la clave privada y el certificado, se convirtió desde el PFX (en Ubuntu 10.04) usando:
openssl pkcs12 -en PFXFile salida privado pemfile -nodes
No creo que importe aquí, pero también probé unix2dos -ing el archivo PEM, sin ningún resultado. Me sale el mismo comportamiento, incluso cuando yo no proporcionan ningún certificado, pero hacerlo en Linux resulta en un error de la API adecuada desde el servidor:
'HTTP/1.1 403 Forbidden \ r \ nContent-Longitud: 0 \ r \ nserver: Microsoft-HTTPAPI/2.0 \ r \ nDate: Jue 01 Dic 2011 13:59:29 GMT \ r \ nConnection: cerrar \ r \ n \ r \ n'
Ésta ha sido verificado independientemente por otra persona que usa Windows 7 (igual que yo). No es un problema de cortafuegos del lado del cliente - el mismo código funciona en un NAT-ed Linux VM que se ejecutan en el mismo host.
Estoy perplejo. Realmente agradecería cualquier ayuda aquí la gente podría ser capaz de proporcionar ...
Actualización: Esto parece estar relacionado con la implementación de SSL subyacente en Python. CPython 2.7.1 tiene el comportamiento de error como se muestra arriba, pero desde que he probado y tenido éxito con ActiveState Python (ambos 2,7 y 2,6), por ejemplo:
>>> import sys, socket, ssl
>>> sys.version
'2.7.1 (r271:86832, Feb 7 2011, 11:30:38) [MSC v.1500 32 bit (Intel)]'
>>> s = ssl.wrap_socket(socket.socket(), certfile='\\\\VBOXSVR\\azure\\BlairBethwaiteAzure1.pfx.pem')
>>> s.connect(('management.core.windows.net',443))
>>> s.send('GET /SUBSCRIPTION_ID/locations HTTP/1.1\r\nAccept-Encoding: identity\r\nX-Ms-Version: 2011-10-01\r\nHost: management.core.windows.net\r\nUser-Agent: Python-urllib/2.6\r\n\r\n')
183
>>> s.read(4096)
'HTTP/1.1 200 OK\r\nContent-Length: 908\r\nContent-Type: application/xml; charset=utf-8\r\nServer: Microsoft-HTTPAPI/2.0\r\nx-ms-request-id: 08ca048cda6b445da6b3a8f3e4890197\r\nDate: Fri, 02 Dec 2011 03:02:14 GMT\r\n\r\n<Locations xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Location><Name>Anywhere US</Name><DisplayName>Anywhere US</DisplayName></Location><Location><Name>South Central US</Name><DisplayName>South Central US</DisplayName></Location><Location><Name>North Central US</Name><DisplayName>North Central US</DisplayName></Location><Location><Name>Anywhere Europe</Name><DisplayName>Anywhere Europe</DisplayName></Location><Location><Name>North Europe</Name><DisplayName>North Europe</DisplayName></Location><Location><Name>West Europe</Name><DisplayName>West Europe</DisplayName></Location><Location><Name>Anywhere Asia</Name><DisplayName>Anywhere Asia</DisplayName></Location><Location><Name>Southeast Asia</Name><DisplayName>Southeast Asia</DisplayName></Location><Location><Name>East Asia</Name><DisplayName>East Asia</DisplayName></Location></Locations>'
Y como era de esperar mi API también funciona:
ActivePython 2.6.7.20 (ActiveState Software Inc.) based on
Python 2.6.7 (r267:88850, Jun 27 2011, 13:20:48) [MSC v.1500 64 bit (AMD64)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyazure import pyazure
>>> pa = pyazure.PyAzure(subscription_id=SUBSCRIPTION_ID, management_cert_path='c:\\users\\blair\\research\\clouds\\azure\\BlairBethwaiteAzure1.pfx.pem')
>>> list(pa.wasm.list_locations())
['Anywhere US', 'South Central US', 'North Central US', 'Anywhere Europe', 'North Europe', 'West Europe', 'Anywhere Asia', 'Southeast Asia', 'East Asia']
Los archivos Lib \ ssl.py en CPython2.7 y ActivePython2.7 son idénticos, así que supongo que esto se debe a alguna diferencia en las bibliotecas C subyacentes, quizás un error en CPython. ¿Algún gurú por ahí?
¿Tiene algún proceso proxy como Fiddler en su equipo? –
Sin proxy local ni sniffer. – Blairo