class HTTPX::Connection::HTTP1

  1. lib/httpx/connection/http1.rb
Superclass: Object

Included modules

  1. Callbacks
  2. Loggable

Constants

CRLF = "\r\n"  
UPCASED = { "www-authenticate" => "WWW-Authenticate", "http2-settings" => "HTTP2-Settings", }.freeze  

Public Class methods

new (buffer, options)
[show source]
   # File lib/httpx/connection/http1.rb
12 def initialize(buffer, options)
13   @options = Options.new(options)
14   @max_concurrent_requests = @options.max_concurrent_requests
15   @max_requests = Float::INFINITY
16   @parser = Parser::HTTP1.new(self)
17   @buffer = buffer
18   @version = [1, 1]
19   @pending = []
20   @requests = []
21 end

Public Instance methods

<< (data)
[show source]
   # File lib/httpx/connection/http1.rb
38 def <<(data)
39   @parser << data
40 end
close ()
[show source]
   # File lib/httpx/connection/http1.rb
27 def close
28   reset
29   emit(:close)
30 end
consume ()
[show source]
   # File lib/httpx/connection/http1.rb
63 def consume
64   @requests.each do |request|
65     handle(request)
66   end
67 end
dispatch ()
[show source]
    # File lib/httpx/connection/http1.rb
121 def dispatch
122   if @request.expects?
123     reset
124     return handle(@request)
125   end
126 
127   request = @request
128   @request = nil
129   @requests.shift
130   response = request.response
131   emit(:response, request, response)
132 
133   if @parser.upgrade?
134     response << @parser.upgrade_data
135     throw(:called)
136   end
137 
138   reset
139   @max_requests -= 1
140   send(@pending.shift) unless @pending.empty?
141   manage_connection(response)
142 end
empty? ()
[show source]
   # File lib/httpx/connection/http1.rb
32 def empty?
33   # this means that for every request there's an available
34   # partial response, so there are no in-flight requests waiting.
35   @requests.empty? || @requests.all? { |request| !request.response.nil? }
36 end
handle_error (ex)
[show source]
    # File lib/httpx/connection/http1.rb
144 def handle_error(ex)
145   if @pipelining
146     disable
147   else
148     @requests.each do |request|
149       emit(:error, request, ex)
150     end
151   end
152 end
on_complete ()
[show source]
    # File lib/httpx/connection/http1.rb
114 def on_complete
115   return unless @request
116 
117   log(level: 2) { "parsing complete" }
118   dispatch
119 end
on_data (chunk)
[show source]
    # File lib/httpx/connection/http1.rb
104 def on_data(chunk)
105   return unless @request
106 
107   log(color: :green) { "-> DATA: #{chunk.bytesize} bytes..." }
108   log(level: 2, color: :green) { "-> #{chunk.inspect}" }
109   response = @request.response
110 
111   response << chunk
112 end
on_headers (h)
[show source]
   # File lib/httpx/connection/http1.rb
77 def on_headers(h)
78   @request = @requests.first
79   return if @request.response
80 
81   log(level: 2) { "headers received" }
82   headers = @request.options.headers_class.new(h)
83   response = @request.options.response_class.new(@request,
84                                                  @parser.status_code,
85                                                  @parser.http_version.join("."),
86                                                  headers)
87   log(color: :yellow) { "-> HEADLINE: #{response.status} HTTP/#{@parser.http_version.join(".")}" }
88   log(color: :yellow) { response.headers.each.map { |f, v| "-> HEADER: #{f}: #{v}" }.join("\n") }
89 
90   @request.response = response
91   on_complete if response.complete?
92 end
on_start ()

HTTP Parser callbacks

must be public methods, or else they won't be reachable

[show source]
   # File lib/httpx/connection/http1.rb
73 def on_start
74   log(level: 2) { "parsing begins" }
75 end
on_trailers (h)
[show source]
    # File lib/httpx/connection/http1.rb
 94 def on_trailers(h)
 95   return unless @request
 96 
 97   response = @request.response
 98   log(level: 2) { "trailer headers received" }
 99 
100   log(color: :yellow) { h.each.map { |f, v| "-> HEADER: #{f}: #{v}" }.join("\n") }
101   response.merge_headers(h)
102 end
reenqueue! ()
[show source]
   # File lib/httpx/connection/http1.rb
55 def reenqueue!
56   requests = @requests.dup
57   @requests.clear
58   requests.each do |request|
59     send(request)
60   end
61 end
reset ()
[show source]
   # File lib/httpx/connection/http1.rb
23 def reset
24   @parser.reset!
25 end
send (request)
[show source]
   # File lib/httpx/connection/http1.rb
42 def send(request)
43   if @max_requests.positive? &&
44      @requests.size >= @max_concurrent_requests
45     @pending << request
46     return
47   end
48   unless @requests.include?(request)
49     @requests << request
50     @pipelining = true if @requests.size > 1
51   end
52   handle(request)
53 end