class HTTP::Request::Writer
def add_body_type_headers
Adds the headers to the header array for the given request body we are working
def add_body_type_headers return if @headers[Headers::CONTENT_LENGTH] || chunked? @request_header << "#{Headers::CONTENT_LENGTH}: #{@body.size}" end
def add_headers
def add_headers @headers.each do |field, value| @request_header << "#{field}: #{value}" end end
def chunked?
def chunked? @headers[Headers::TRANSFER_ENCODING] == CHUNKED end
def connect_through_proxy
def connect_through_proxy add_headers write(join_headers) end
def encode_chunk(chunk)
def encode_chunk(chunk) if chunked? chunk.bytesize.to_s(16) << CRLF << chunk << CRLF else chunk end end
def initialize(socket, body, headers, headline)
def initialize(socket, body, headers, headline) @body = body @socket = socket @headers = headers @request_header = [headline] end
def join_headers
Joins the headers specified in the request into a correctly formatted
def join_headers # join the headers array with crlfs, stick two on the end because # that ends the request header @request_header.join(CRLF) + CRLF * 2 end
def send_request
def send_request # It's important to send the request in a single write call when # possible in order to play nicely with Nagle's algorithm. Making # two writes in a row triggers a pathological case where Nagle is # expecting a third write that never happens. data = join_headers @body.each do |chunk| data << encode_chunk(chunk) write(data) data.clear end write(data) unless data.empty? write(CHUNKED_END) if chunked? end
def stream
def stream add_headers add_body_type_headers send_request end
def write(data)
def write(data) until data.empty? length = @socket.write(data) break unless data.bytesize > length data = data.byteslice(length..-1) end end