Feature #11507
openNet::HTTP should use TCP_CORK or TCP_NOPUSH to avoid fragmenting packets
Description
I discovered while implementing a soap client against a badly implemented http server that for sending a 723 bytes, Net::HTTP sends two packets:
Frame 185: 579 bytes on wire (4632 bits), 579 bytes captured (4632 bits) on interface 0
Point-to-Point Protocol
Internet Protocol Version 4, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 63525 (63525), Dst Port: 7001 (7001), Seq: 210, Ack: 1, Len: 523
[2 Reassembled TCP Segments (732 bytes): #183(209), #185(523)]
[Frame: 183, payload: 0-208 (209 bytes)]
[Frame: 185, payload: 209-731 (523 bytes)]
[Segment count: 2]
[Reassembled TCP length: 732]
[Reassembled TCP Data: 504f5354202f20485454502f312e310d0a534f4150416374...]
Hypertext Transfer Protocol
POST / HTTP/1.1\r\n
SOAPAction: ""\r\n
Content-Type: text/xml;charset=UTF-8\r\n
Content-Length: 523\r\n
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\n
Accept: */*\r\n
User-Agent: Ruby\r\n
Host: 172.16.129.10:7001\r\n
\r\n
[Full request URI: http://127.0.0.1:7001/]
[HTTP request 1/1]
[Response in frame: 187]
eXtensible Markup Language
So Net::HTTP client performance could be improved by using the TCP_CORK option on Linux and TCP_NOPUSH option on BSD's.
I implemented at the time an embedded tcp server on a relatively slow MIPS processor under Linux and using TCP_CORK greatly improved the throughput of the server, so it might also help here. I suppose it also depends on the network hardware.
Implementing this simply means (on linux at least) calling
int state = 1;
setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
before starting to write the request and
int state = 0;
setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
after when it's written. It will prevent the kernel to send anything until the request is completely written. From what I see, the BasicSocket::setsockopt supports TCP_CORK so that should be quite easy. Unfortunatly I do not have time to implement that right now but I hope I'll be able to implement it and do some tests soon.
No data to display