Domanda

I need to disable nagle algorithm in python2.6. I found out that patching HTTPConnection in httplib.py that way

    def connect(self):
        """Connect to the host and port specified in __init__."""
        self.sock = socket.create_connection((self.host,self.port),
                                         self.timeout)
        self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True) # added line

does the trick.

Obviously, I would like to avoid patching system lib if possible. So, the question is: what is right way to do such thing? (I'm pretty new to python and can be easily missing some obvious solution here)

È stato utile?

Soluzione

It's not possible to change the socket options that httplib specifies, and it's not possible to pass in your own socket object either. In my opinion this sort of lack of flexibility is the biggest weakness of most of the Python HTTP libraries. For example, prior to Python 2.6 it wasn't even possible to specify a timeout for the connection (except by using socket.setdefaulttimeout() globally, which wasn't very clean).

If you don't mind external dependencies, it looks like httplib2 already has TCP_NODELAY specified.

You could monkey-patch the library. Because python is a dynamic language and more or less everything is done as a namespace lookup at runtime, you can simply replace the appropriate method on the relevant class:

:::python
import httplib

def patch_httplib():
    orig_connect = httplib.HTTPConnection.connect
    def my_connect(self):
        orig_connect(self)
        self.sock.setsockopt(...)

However, this is extremely error-prone as it means that your code becomes quite specific to a particular Python version, as these library functions and classes do change. For example, in 2.7 there's a _tunnel() method called which uses the socket, so you'd want to hook in the middle of the connect() method - monkey-patching makes that extremely tricky.

In short, I don't think there's an easy answer, I'm afraid.

Altri suggerimenti

Please note that if using the socket library directly, the following is sufficient:

self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)

I append this information to the accepted answer because it satisfies the information need that brought me here.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top