Class: HTTP::Request::Writer
- Inherits:
-
Object
- Object
- HTTP::Request::Writer
- Defined in:
- lib/http/request/writer.rb
Constant Summary collapse
- CRLF =
CRLF is the universal HTTP delimiter
"\r\n"
- ZERO =
Chunked data termintaor.
"0"
- CHUNKED =
Chunked transfer encoding
"chunked"
- CHUNKED_END =
End of a chunked transfer
"#{ZERO}#{CRLF}#{CRLF}".freeze
Instance Method Summary collapse
-
#add_body_type_headers ⇒ Object
Adds the headers to the header array for the given request body we are working with.
-
#add_headers ⇒ Object
Adds headers to the request header from the headers array.
-
#chunked? ⇒ Boolean
Returns true if the request should be sent in chunked encoding.
-
#connect_through_proxy ⇒ Object
Send headers needed to connect through proxy.
-
#each_chunk {|data| ... } ⇒ Object
Yields chunks of request data that should be sent to the socket.
-
#encode_chunk(chunk) ⇒ Object
Returns the chunk encoded for to the specified "Transfer-Encoding" header.
-
#initialize(socket, body, headers, headline) ⇒ Writer
constructor
A new instance of Writer.
-
#join_headers ⇒ Object
Joins the headers specified in the request into a correctly formatted http request header string.
-
#send_request ⇒ Object
Writes HTTP request data into the socket.
-
#stream ⇒ Object
Stream the request to a socket.
Constructor Details
#initialize(socket, body, headers, headline) ⇒ Writer
Returns a new instance of Writer.
20 21 22 23 24 25 |
# File 'lib/http/request/writer.rb', line 20 def initialize(socket, body, headers, headline) @body = body @socket = socket @headers = headers @request_header = [headline] end |
Instance Method Details
#add_body_type_headers ⇒ Object
Adds the headers to the header array for the given request body we are working with
49 50 51 52 53 54 55 56 57 |
# File 'lib/http/request/writer.rb', line 49 def add_body_type_headers return if @headers[Headers::CONTENT_LENGTH] || chunked? || ( @body.source.nil? && %w[GET HEAD DELETE CONNECT].any? do |method| @request_header[0].start_with?("#{method} ") end ) @request_header << "#{Headers::CONTENT_LENGTH}: #{@body.size}" end |
#add_headers ⇒ Object
Adds headers to the request header from the headers array
28 29 30 31 32 |
# File 'lib/http/request/writer.rb', line 28 def add_headers @headers.each do |field, value| @request_header << "#{field}: #{value}" end end |
#chunked? ⇒ Boolean
Returns true if the request should be sent in chunked encoding.
105 106 107 |
# File 'lib/http/request/writer.rb', line 105 def chunked? @headers[Headers::TRANSFER_ENCODING] == CHUNKED end |
#connect_through_proxy ⇒ Object
Send headers needed to connect through proxy
42 43 44 45 |
# File 'lib/http/request/writer.rb', line 42 def connect_through_proxy add_headers write(join_headers) end |
#each_chunk {|data| ... } ⇒ Object
Yields chunks of request data that should be sent to the socket.
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.
81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/http/request/writer.rb', line 81 def each_chunk data = join_headers @body.each do |chunk| data << encode_chunk(chunk) yield data data.clear end yield data unless data.empty? yield CHUNKED_END if chunked? end |
#encode_chunk(chunk) ⇒ Object
Returns the chunk encoded for to the specified "Transfer-Encoding" header.
96 97 98 99 100 101 102 |
# File 'lib/http/request/writer.rb', line 96 def encode_chunk(chunk) if chunked? chunk.bytesize.to_s(16) << CRLF << chunk << CRLF else chunk end end |
#join_headers ⇒ Object
Joins the headers specified in the request into a correctly formatted http request header string
61 62 63 64 65 |
# File 'lib/http/request/writer.rb', line 61 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 ⇒ Object
Writes HTTP request data into the socket.
68 69 70 71 72 73 |
# File 'lib/http/request/writer.rb', line 68 def send_request each_chunk { |chunk| write chunk } rescue Errno::EPIPE # server doesn't need any more data nil end |
#stream ⇒ Object
Stream the request to a socket
35 36 37 38 39 |
# File 'lib/http/request/writer.rb', line 35 def stream add_headers add_body_type_headers send_request end |