HTTPConnection.request не соблюдает тайм-аут?

Я пытаюсь использовать HTTPConnection (2.7.8), чтобы сделать запрос, и я установил тайм-аут на 10 с помощью HTTPConnection(host, timeout=10). Однако HTTPConnection.request(), похоже, не истекает через 10 секунд. На самом деле, HTTPConnection.timeout, кажется, даже не читается HTTPConnection.request() (оно читается только HTTPConnection.connect(). Правильно ли я понимаю? timeout применимо только к connect(), а не request()? Есть ли способ таймаута request()?

Обновление:

Я думаю, что еще больше сузил проблему: если я не предоставлю схему, она не будет соблюдать тайм-аут сокета. Если схема была предоставлена, то есть полный URL-адрес был http://google.com:22222, то время ожидания истекло соответственно. Интересно, почему наличие схемы должно иметь значение. То есть следующее не соблюдает тайм-аут

    socket.setdefaulttimeout(3)
    conn = HTTPConnection('google.com:22222')
    conn.timeout = 3
    conn.request('GET', '')

тогда как это делает:

    socket.setdefaulttimeout(3)
    conn = HTTPConnection('http://google.com:22222')
    conn.timeout = 3
    conn.request('GET', '')

Однако это происходит не со всеми доменами.

Спасибо


person Kar    schedule 23.02.2015    source источник
comment
Пожалуйста, проверьте http://stackoverflow.com/questions/265720/http-request-timeout. Надеюсь это поможет :)   -  person itzMEonTV    schedule 23.02.2015
comment
Нет, этот ответ мне не подходит. Он по-прежнему застрял на request(). Пример URL: google.com:2222.   -  person Kar    schedule 23.02.2015
comment
Вы пытались указать IP-адрес напрямую (вместо имени хоста)? Позвоните socket.getaddrinfo(), чтобы получить IP-адрес. Похоже, та же проблема, что и время ожидания ftplib.FTP имеет непоследовательное поведение: request() выполняет несколько операций с сокетами. Каждая операция ограничена тайм-аутом. Но совмещение нескольких операций может занять больше времени.   -  person jfs    schedule 23.02.2015
comment
Я думаю, что еще больше сузил проблему: если я не предоставлю схему, она не будет соблюдать тайм-аут сокета. Если была предоставлена ​​схема, т. е. полный URL-адрес http://google.com:22222, время истекло. Интересно, почему наличие схемы должно иметь значение.   -  person Kar    schedule 23.02.2015
comment
Непонятно, как вы используете HTTPConnection. Создайте самую короткую программу, демонстрирующую разницу (установите HTTPConnection.debuglevel=1)   -  person jfs    schedule 23.02.2015
comment
@ J.F.Sebastian Я добавил фрагменты кода.   -  person Kar    schedule 23.02.2015
comment
@ J.F.Sebastian Я думаю, что предложение в вашем первом комментарии объясняет мою проблему.   -  person Kar    schedule 23.02.2015


Ответы (1)


Сбой следующего кода занимает около 30 секунд:

#!/usr/bin/env python2
from httplib import HTTPConnection

conn = HTTPConnection('google.com', 22222, timeout=2)
conn.request('GET', '')

Если ip передается в HTTPConnection вместо имени хоста, то ошибка тайм-аута возникает через 2 секунды, как и ожидалось:

#!/usr/bin/env python2
import socket
from httplib import HTTPConnection

host, port = 'google.com', 22222
ip, port = socket.getaddrinfo(host, port)[0][-1]
conn = HTTPConnection(ip, port, timeout=2)
conn.request('GET', '')

Объяснение такое же, как и в время ожидания ftplib.FTP имеет непоследовательное поведение: время ожидания может ограничивать отдельные операции сокета, но ничего не говорит о продолжительности самого вызова HTTPConnection(), который может попробовать несколько IP-адресов, возвращаемых getaddrinfo(), и тайм-аут ограничивает только отдельные операции сокета. Объединение нескольких операций может занять больше времени.

Ваш HTTPConnection('http://google.com:22222') не работает раньше, потому что URL-адрес является неверным аргументом: он должен быть либо host, либо host:port. Абсолютное url принимается методом request(), хотя даже там оно имеет особое значение — обычно вы просто указываете путь, такой как '/'.

person jfs    schedule 23.02.2015