Mam małą aplikację, którą napisałem w Pythonie i działała ... aż do wczoraj, kiedy to nagle zaczęło się pojawiać błąd w połączeniu HTTPS. Nie pamiętam, czy była aktualizacja, ale zarówno Python 2.7.3rc2, jak i Python 3.2 nie działają tak samo.
Przejrzałem go i dowiedziałem się, że dzieje się tak, gdy ludzie stoją za serwerem proxy, ale ja nie jestem (i nic się nie zmieniło w mojej sieci od czasu ostatniego działania). Komputer mojego systemu z systemem Windows i Python 2.7.2 nie ma problemów (w tej samej sieci).
>>> url = 'https://www.mediafire.com/api/user/get_session_token.php'
>>> response = urllib2.urlopen(url).read()
File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
return _opener.open(url, data, timeout)
File "/usr/lib/python2.7/urllib2.py", line 400, in open
response = self._open(req, data)
File "/usr/lib/python2.7/urllib2.py", line 418, in _open
'_open', req)
File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
result = func(*args)
File "/usr/lib/python2.7/urllib2.py", line 1215, in https_open
return self.do_open(httplib.HTTPSConnection, req)
File "/usr/lib/python2.7/urllib2.py", line 1177, in do_open
raise URLError(err)
urllib2.URLError: <urlopen error [Errno 8] _ssl.c:504: EOF occurred in violation of protocol>
Co jest nie tak? Każda pomoc jest mile widziana.
PS .: Starsze wersje Pythona też nie działają, nie w moim systemie i nie w sesji na żywo z USB, ale działają w sesji na żywo Ubuntu 11.10.
Odpowiedzi:
Wydaje się, że jest to związane z dodaniem obsługi TLS 1.1 i 1.2 do wersji OpenSSL znalezionej w 12.04. Błąd połączenia można odtworzyć za pomocą narzędzia wiersza polecenia OpenSSL:
Połączenie powiedzie się, jeśli wymuszę użycie TLS 1.0 z
-tls1
argumentem wiersza poleceń.Proponuję tutaj zgłosić raport o błędzie dotyczący tego problemu:
https://bugs.launchpad.net/ubuntu/+filebug
źródło
Dla nowicjuszy pythonowych, takich jak ja, oto sposób na najprostszy sposób zastąpienia httplib. U góry skryptu Python dołącz następujące wiersze:
Odtąd możesz używać urllib lub cokolwiek innego, tak jak zwykle.
Uwaga: dotyczy Pythona 2.7. W przypadku rozwiązania w języku Python 3.x należy zastąpić klasę HTTPSConnection znalezioną w http.client. Zostawiam to jako ćwiczenie dla czytelnika. :-)
źródło
httplib
. Ludzie mogą korzystać z innych gniazd SSL. Można łataćssl
zamiast tego jak w mojej odpowiedzi poniżej.BadStatusLine: ''
Możesz uniknąć modyfikacji pliku httplib.py, modyfikując obiekt HTTPSConnection:
Metoda żądania tworzy nowe gniazdo tylko wtedy, gdy nie zdefiniowano connection.sock. Utworzenie własnego przez dodanie parametru ssl_version spowoduje, że metoda żądania go wykorzysta. Wtedy wszystko inne działa jak zwykle.
Miałem ten sam problem i to działa dla mnie.
pozdrowienia
źródło
Problem tkwi w tym
ssl
, że nie ma to nic wspólnego z HTTP, więc po co łatać,httplib
jeśli można łataćssl
. Poniższy kod powinien naprawić wszystkie gniazda SSL, w tym między innymi HTTPS dla Python 2.6+ (wbudowanessl
, nie próbowałempyopenssl
).źródło
EDYCJA httplib.py (/usr/lib/pythonX.X/httplib.py w systemie Linux)
ZNAJDŹ deklarację klasy HTTPSConnection
Kod klasy wewnątrz linii CHANGE
DO
Wtedy żądanie HTTP HTTPS powinno działać
źródło
Ten problem jest prawdopodobnie spowodowany wyłączeniem SSLv2 na serwerze WWW, ale Python 2.x domyślnie próbuje nawiązać połączenie z PROTOCOL_SSLv23.
Oto link do mojej odpowiedzi na podobny problem dotyczący przepełnienia stosu - /programming//a/24166498/41957
Aktualizacja: jest to funkcjonalnie to samo co powyższa odpowiedź @ temoto.
źródło
Prostą poprawką, która działała dla mnie, było zastąpienie domyślnego protokołu SSL:
źródło