lib/async/http/protocol/http2.rb in async-http-0.9.0 vs lib/async/http/protocol/http2.rb in async-http-0.10.0

- old
+ new

@@ -18,10 +18,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'request' require_relative 'response' +require_relative '../headers' require 'async/notification' require 'http/2' @@ -36,10 +37,18 @@ def self.server(stream) self.new(::HTTP2::Server.new, stream) end + HTTPS = 'https'.freeze + SCHEME = ':scheme'.freeze + METHOD = ':method'.freeze + PATH = ':path'.freeze + AUTHORITY = ':authority'.freeze + REASON = ':reason'.freeze + STATUS = ':status'.freeze + def initialize(controller, stream) @controller = controller @stream = stream @controller.on(:frame) do |data| @@ -70,19 +79,17 @@ @reader.alive? end def read_in_background(task: Task.current) task.async do |nested_task| - while true - if data = @stream.io.read(10) - # Async.logger.debug(self) {"Reading data: #{data.size} bytes"} - @controller << data - else - Async.logger.debug(self) {"Connection reset by peer!"} - break - end + buffer = Async::IO::BinaryString.new + + while data = @stream.io.read(1024*8, buffer) + @controller << data end + + Async.logger.debug(self) {"Connection reset by peer!"} end end def close Async.logger.debug(self) {"Closing connection"} @@ -93,21 +100,23 @@ def receive_requests(&block) # emits new streams opened by the client @controller.on(:stream) do |stream| request = Request.new request.version = "HTTP/2.0" - request.headers = {} + request.headers = Headers.new # stream.on(:active) { } # fires when stream transitions to open state # stream.on(:close) { } # stream is closed by client and server stream.on(:headers) do |headers| headers.each do |key, value| - if key == ':method' + if key == METHOD request.method = value - elsif key == ':path' + elsif key == PATH request.path = value + elsif key == AUTHORITY + request.authority = value else request.headers[key] = value end end end @@ -118,11 +127,11 @@ stream.on(:half_close) do response = yield request # send response - stream.headers(':status' => response[0].to_s) + stream.headers(STATUS => response[0].to_s) stream.headers(response[1]) unless response[1].empty? response[2].each do |chunk| stream.data(chunk, end_stream: false) @@ -135,17 +144,20 @@ while data = @stream.io.read(1024) @controller << data end end - def send_request(method, path, headers = {}, body = nil) + RESPONSE_VERSION = 'HTTP/2'.freeze + + def send_request(authority, method, path, headers = {}, body = nil) stream = @controller.new_stream internal_headers = { - ':scheme' => 'https', - ':method' => method, - ':path' => path, + SCHEME => HTTPS, + METHOD => method, + PATH => path, + AUTHORITY => authority, }.merge(headers) stream.headers(internal_headers, end_stream: true) # if body @@ -155,20 +167,20 @@ # # stream.data("", end_stream: true) # end response = Response.new - response.version = "HTTP/2" - response.headers = {} + response.version = RESPONSE_VERSION + response.headers = Headers.new response.body = Async::IO::BinaryString.new stream.on(:headers) do |headers| # Async.logger.debug(self) {"Stream headers: #{headers.inspect}"} headers.each do |key, value| - if key == ':status' + if key == STATUS response.status = value.to_i - elsif key == ':reason' + elsif key == REASON response.reason = value else response.headers[key] = value end end