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
before starting to write the request and
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