--qMm9M+Fa2AknHoGS
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
I was playing with setsockopt because I was seeing about a 0.1 second
latency on HTTP requests.
However it seems that the underlying problem is that the Net::HTTP library
sends its request as multiple writes (one for the GET or POST line, one for
each header line, one for the blank line, and one for any POST content if
included)
Coalescing these into a single write is straightforward, so I'd like to
propose that at least GET requests be fixed as follows:
module Net
class HTTPGenericRequest
def request( sock, ver, path )
req printf('%s %s HTTP/%s', @method, path, ver) + "\r\n"
canonical_each do |k,v|
req << (k + ': ' + v + "\r\n")
end
req << "\r\n"
sock.write req
end
end
end
That still leaves two writes for a POST (one for the headers, one for the
data). My suggested fix is attached; if the POST data is large then it
doesn't concatenate the header and request, to save building a potentially
large intermediate string.
Doing this reduces the number of network packets sent, gets rid of the
latency problem, and doesn't require any non-portable setsockopt tweaking.
Regards,
Brian.
--qMm9M+Fa2AknHoGS
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="httpfast.rb"
require 'net/http'
# This is just an optimisation: sending the request in a single write
module Net
class HTTPGenericRequest
def send_request_with_body( sock, ver, path, body )
if block_given? then
ac ccumulator.new
yield ac # must be yield, DO NOT USE block.call
data c.terminate
else
data ody
end
@header['content-length'] ata.size.to_s
@header.delete 'transfer-encoding'
unless @header['content-type'] then
$stderr.puts 'Content-Type did not set; using application/x-www-form-urlencoded' if $VERBOSE
@header['content-type'] application/x-www-form-urlencoded'
end
request sock, ver, path, data
end
def request( sock, ver, path, rest )
req printf('%s %s HTTP/%s', @method, path, ver) + "\r\n"
canonical_each do |k,v|
req << (k + ': ' + v + "\r\n")
end
req << "\r\n"
if rest.size < 1500 # worth trying to put in single TCP segment
req << rest
sock.write req
else
sock.write req
sock.write rest
end
end
end
end
--qMm9M+Fa2AknHoGS--