Подтвердить что ты не робот

Как установить флаг TCP_NODELAY при загрузке URL с urllib2?

Я использую urllib2 для загрузки веб-страницы, мой код:

httpRequest = urllib2.Request("http:/www....com")
pageContent = urllib2.urlopen(httpRequest)
pageContent.readline()

Как я могу получить свойства сокета для установки TCP_NODELAY?

В обычном сокете я бы использовал функцию:

socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
4b9b3361

Ответ 1

Если вам нужен доступ к такому низкоуровневому свойству в используемом сокете, вам придется перегрузить некоторые объекты.

Сначала вам нужно создать подкласс HTTPHandler, который в стандартной библиотеке:

class HTTPHandler(AbstractHTTPHandler):

    def http_open(self, req):
        return self.do_open(httplib.HTTPConnection, req)

    http_request = AbstractHTTPHandler.do_request_

Как вы можете видеть, он использует HTTPConnection для открытия соединения... Вам также придется переопределить его;), чтобы обновить метод connect().

Что-то вроде этого должно быть хорошим началом:

class LowLevelHTTPConnection(httplib.HTTPConnection):

    def connect(self):
        httplib.HTTPConnection.connect(self)
        self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)


class LowLevelHTTPHandler(HTTPHandler):

    def http_open(self, req):
        return self.do_open(LowLevelHTTPConnection, req)

urllib2 достаточно умен, чтобы вы могли подклассифицировать некоторый обработчик, а затем использовать его, urllib2.build_opener для этого:

urllib2.install_opener(urllib2.build_opener(LowLevelHTTPHandler)) # tell urllib2 to use your HTTPHandler in replacement of the standard HTTPHandler
httpRequest = urllib2.Request("http:/www....com")
pageContent = urllib2.urlopen(httpRequest)
pageContent.readline()

Ответ 2

Для запросов классы кажутся в request.packages.urllib3; есть 2 класса, HTTPConnection и HTTPSConnection. Они должны быть обезврежены на уровне верхнего уровня модуля:

from requests.packages.urllib3 import connectionpool

_HTTPConnection = connectionpool.HTTPConnection
_HTTPSConnection = connectionpool.HTTPSConnection

class HTTPConnection(_HTTPConnection):
    def connect(self):
        _HTTPConnection.connect(self)
        self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

class HTTPSConnection(_HTTPSConnection):
    def connect(self):
        _HTTPSConnection.connect(self)
        self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

connectionpool.HTTPConnection = HTTPConnection
connectionpool.HTTPSConnection = HTTPSConnection

Ответ 3

Вам нужно использовать urllib2?

В качестве альтернативы вы можете использовать httplib2, у которого есть опция TCP_NODELAY.

https://code.google.com/p/httplib2/

Он добавляет зависимость от вашего проекта, но кажется менее хрупким, чем исправление обезьяны.