class HTTP::Request::Writer

Constants

CHUNKED

Chunked transfer encoding

CHUNKED_END

End of a chunked transfer

CRLF

CRLF is the universal HTTP delimiter

ZERO

Chunked data termintaor.

Public Class Methods

new(socket, body, headers, headline) click to toggle source
# File lib/http/request/writer.rb, line 19
def initialize(socket, body, headers, headline)
  @body           = body
  @socket         = socket
  @headers        = headers
  @request_header = [headline]
end

Public Instance Methods

add_body_type_headers() click to toggle source

Adds the headers to the header array for the given request body we are working with

# File lib/http/request/writer.rb, line 48
def add_body_type_headers
  return if @headers[Headers::CONTENT_LENGTH] || chunked?

  @request_header << "#{Headers::CONTENT_LENGTH}: #{@body.size}"
end
add_headers() click to toggle source

Adds headers to the request header from the headers array

# File lib/http/request/writer.rb, line 27
def add_headers
  @headers.each do |field, value|
    @request_header << "#{field}: #{value}"
  end
end
chunked?() click to toggle source

Returns true if the request should be sent in chunked encoding.

# File lib/http/request/writer.rb, line 90
def chunked?
  @headers[Headers::TRANSFER_ENCODING] == CHUNKED
end
connect_through_proxy() click to toggle source

Send headers needed to connect through proxy

# File lib/http/request/writer.rb, line 41
def connect_through_proxy
  add_headers
  write(join_headers)
end
encode_chunk(chunk) click to toggle source

Returns the chunk encoded for to the specified “Transfer-Encoding” header.

# File lib/http/request/writer.rb, line 81
def encode_chunk(chunk)
  if chunked?
    chunk.bytesize.to_s(16) << CRLF << chunk << CRLF
  else
    chunk
  end
end
join_headers() click to toggle source

Joins the headers specified in the request into a correctly formatted http request header string

# File lib/http/request/writer.rb, line 56
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
send_request() click to toggle source
# File lib/http/request/writer.rb, line 62
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
stream() click to toggle source

Stream the request to a socket

# File lib/http/request/writer.rb, line 34
def stream
  add_headers
  add_body_type_headers
  send_request
end

Private Instance Methods

write(data) click to toggle source
# File lib/http/request/writer.rb, line 96
def write(data)
  until data.empty?
    length = @socket.write(data)
    break unless data.bytesize > length
    data = data.byteslice(length..-1)
  end
end