Тайм-аут библиотеки запросов Python под Linux

Я пытаюсь использовать библиотеку request.py для вызовов веб-службы отдыха. Я написал быстрый прототип для своего использования под Windows, и все работало нормально, но когда я попытался запустить тот же прототип под Linux, я получил ошибку «requests.exceptions.Timeout: Request timed out». Кто-нибудь знает, почему это может происходить? Если я попытаюсь использовать библиотеку для доступа к URL-адресу, отличному от https, он отлично работает как под Windows, так и под Linux.

import requests

url = 'https://path.to.rest/svc/?options'
r = requests.get(url, auth=('uid','passwd'), verify=False)
print(r.content)

Я заметил, что если я оставлю параметр verify=False в вызове get, я получу другое исключение, а именно «requests.exceptions.SSLError: не удается подключиться к URL-адресу HTTPS, поскольку модуль SSL недоступен». Это кажется возможной основной причиной, хотя я не знаю, почему они изменили код ошибки, но я не могу найти ссылку на модуль ssl, и я проверил, что certifi был установлен. Интересно, что если я не указываю параметр проверки в Windows, я получаю другое исключение: «requests.exceptions.SSLError: [Errno 1] _ssl.c:503: ошибка: 14090086: подпрограммы SSL: SSL3_GET_SERVER_CERTIFICATE: ошибка проверки сертификата»

РЕДАКТИРОВАТЬ:

Трассировки для всех упомянутых случаев/сценариев

Полный код, как показано выше:

Traceback(most recent call last):
    File "testRequests.py", line 15, in <module>
        r = requests.get(url, auth=('uid','passwd'), verify=False)
    File "build/bdist.linux-x86_64/egg/requests/api.py", line 52, in get
    File "build/bdist.linux-x86_64/egg/requests/api.py", line 40, in request
    File "build/bdist.linux-x86_64/egg/requests/sessions.py", line 208, in request
    File "build/bdist.linux-x86_64/egg/requests/models.py", line 586, in send
requests.exceptions.Timeout: Request timed out

Код, как показано выше, минус параметр "verify=False":

Traceback(most recent call last):
    File "testRequests.py", line 15, in <module>
        r = requests.get(url, auth=('uid','passwd'))
    File "build/bdist.linux-x86_64/egg/requests/api.py", line 52, in get
    File "build/bdist.linux-x86_64/egg/requests/api.py", line 40, in request
    File "build/bdist.linux-x86_64/egg/requests/sessions.py", line 208, in request
    File "build/bdist.linux-x86_64/egg/requests/models.py", line 584, in send
requests.exceptions.SSLError: Can't connect to HTTPS URL because the SSL module is not available

Код, как показано выше, минус параметр "verify=False" и запуск под окнами:

Traceback(most recent call last):
    File "testRequests.py", line 59, in <module>
        r = requests.get(url, auth=('uid','passwd'))
    File "c:\Python27\lib\site-packages\requests\api.py", line 52, in get
        return request('get', url, **kwargs)
    File "c:\Python27\lib\site-packages\requests\api.py", line 40, in request
        return s.request(method=method, url=url, **kwargs)
    File "c:\Python27\lib\site-packages\requests\sessions.py", line 208, in request
        r.send(prefetch=prefetch)
    File "c:\Python27\lib\site-packages\requests\models.py", line 584, in send
        raise SSLError(e)
requests.exceptions.SSLError: [Errno 1] _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

person ntlarson    schedule 17.04.2012    source источник
comment
Что происходит, когда вы запускаете import ssl; from ssl import socket в той же среде Python, где вы получаете ошибку requests.exceptions.Timeout: Request timed out?   -  person Piotr Dobrogost    schedule 17.04.2012
comment
Я добавил трассировку, прошу прощения за то, что оставил ее. Я также попытался выполнить команды импорта, которые вы упомянули, и получил сообщение ImportError: No module named _ssl, однако, если я запускаю его в своей среде Windows, он импортируется нормально, это, похоже, моя проблема. Единственный модуль в pypi для ssl — это тот, который предоставляет функциональность ssl для более старых версий python, подразумевая, что она должна быть в 2.7. Любая идея, почему он не будет импортировать? Нужно ли устанавливать ssl на рассматриваемый сервер (я не проверял, установлен ли он уже или нет)?   -  person ntlarson    schedule 18.04.2012
comment
Можете ли вы попробовать это: import ssl; ssl.get_server_certificate(('google.com',443)) ? и посмотреть, что происходит.   -  person lukecampbell    schedule 18.04.2012
comment
команда импорта ssl не работает. Кроме того, это разрабатывается и работает в частной сети, поэтому у меня нет внешнего подключения к таким службам, как Google.   -  person ntlarson    schedule 18.04.2012
comment
ssl является частью CPython... вам может понадобиться перекомпилировать python с поддержкой openssl. (Я однажды скомпилировал Python 2.7 на Mac без установленного openssl, и у меня была очень похожая проблема). Не могу помочь вам с Windows, но для Linux используйте менеджер пакетов (yum или apt-get). Удалите его, установите openssl и установите (скомпилируйте, если можете).   -  person lukecampbell    schedule 18.04.2012
comment
хорошо, я попробую это. Спасибо :-) о, и все в окнах работает нормально. Я упомянул это только как точку сравнения, пытаясь определить, почему один работает, а другой нет.   -  person ntlarson    schedule 18.04.2012
comment
Что показывает sys.version?   -  person Piotr Dobrogost    schedule 18.04.2012
comment
Люккемпбелл спасибо. Я отредактировал соответствующий файл и перекомпилировал, и это, похоже, решило проблему.   -  person ntlarson    schedule 18.04.2012


Ответы (1)


Я не эксперт в этом вопросе, но похоже, что сертификат с сервера не может быть правильно проверен. Я не знаю, как Python и ssl справляются с проверкой сертификата, но первый вариант — попытаться проигнорировать исключение или, возможно, изменить https на http, чтобы увидеть, разрешает ли веб-служба небезопасные вызовы службы.

Если проблема связана с ошибкой импорта для ssl, модуль является частью CPython, и вам может потребоваться убедиться, что интерпретатор Python скомпилирован с поддержкой SSL (от openssl). Посмотрите на удаление пакета для python (будьте осторожны) и скомпилируйте его с поддержкой openssl, лично я настоятельно рекомендую вам заглянуть в virtualenv, прежде чем что-либо удалять, компиляция Python не слишком сложна, и это даст вам более тонкий контроль над тем, что вы стремитесь сделать.

person lukecampbell    schedule 17.04.2012
comment
Спасибо за ваш вклад. Сервер не разрешает незащищенные соединения. Я уже задавал этот вопрос, и проверка сертификата игнорируется параметром verify=False, и ошибка сохраняется. - person ntlarson; 18.04.2012
comment
Можете ли вы получить какие-либо сертификаты с сервера в Python? import ssl; ssl.get_server_certificate(('google.com',443)) Вы можете заменить google.com именем хоста веб-службы. - person lukecampbell; 18.04.2012
comment
@lukecampbell Извините за некропостинг, но у меня похожая проблема, и import ssl; ssl.get_server_certificate(('google.com',443)) просто зависает. У вас есть идеи, что делать дальше, чтобы устранить эту проблему? - person Ale; 22.08.2019