44# Copyright, 2024, by Thomas Morgan.
55# Copyright, 2024, by Samuel Williams.
66
7+ require_relative "defaultable"
8+
79require_relative "http1"
810require_relative "http2"
911
1012module Async
1113 module HTTP
1214 module Protocol
13- # HTTP is an http:// server that auto-selects HTTP/1.1 or HTTP/2 by detecting the HTTP/2
14- # connection preface.
15- module HTTP
15+ # HTTP is an http:// server that auto-selects HTTP/1.1 or HTTP/2 by detecting the HTTP/2 connection preface.
16+ class HTTP
1617 HTTP2_PREFACE = "PRI * HTTP/2.0\r \n \r \n SM\r \n \r \n "
1718 HTTP2_PREFACE_SIZE = HTTP2_PREFACE . bytesize
1819
20+ # Create a new HTTP protocol instance.
21+ #
22+ # @parameter http1 [HTTP1] The HTTP/1 protocol instance.
23+ # @parameter http2 [HTTP2] The HTTP/2 protocol instance.
24+ def initialize ( http1 : HTTP1 , http2 : HTTP2 )
25+ @http1 = http1
26+ @http2 = http2
27+ end
28+
1929 # Determine if the inbound connection is HTTP/1 or HTTP/2.
2030 #
2131 # @parameter stream [IO::Stream] The stream to detect the protocol for.
2232 # @returns [Class] The protocol class to use.
23- def self . protocol_for ( stream )
33+ def protocol_for ( stream )
2434 # Detect HTTP/2 connection preface
2535 # https://www.rfc-editor.org/rfc/rfc9113.html#section-3.4
2636 preface = stream . peek do |read_buffer |
@@ -33,38 +43,35 @@ def self.protocol_for(stream)
3343 end
3444
3545 if preface == HTTP2_PREFACE
36- HTTP2
46+ @http2
3747 else
38- HTTP1
48+ @http1
3949 end
4050 end
4151
4252 # Create a client for an outbound connection. Defaults to HTTP/1 for plaintext connections.
4353 #
4454 # @parameter peer [IO] The peer to communicate with.
4555 # @parameter options [Hash] Options to pass to the protocol, keyed by protocol class.
46- def self . client ( peer , **options )
47- options = options [ protocol ] || { }
56+ def client ( peer , **options )
57+ options = options [ @http1 ] || { }
4858
49- HTTP1 . client ( peer , **options )
59+ @http1 . client ( peer , **options )
5060 end
5161
52- # Create a server for an inbound connection. Able to detect HTTP1 vs HTTP2.
62+ # Create a server for an inbound connection. Able to detect HTTP1 and HTTP2.
5363 #
5464 # @parameter peer [IO] The peer to communicate with.
5565 # @parameter options [Hash] Options to pass to the protocol, keyed by protocol class.
56- def self . server ( peer , **options )
66+ def server ( peer , **options )
5767 stream = ::IO ::Stream ( peer )
5868 protocol = protocol_for ( stream )
5969 options = options [ protocol ] || { }
6070
6171 return protocol . server ( stream , **options )
6272 end
6373
64- # @returns [Array] The names of the supported protocols.
65- def self . names
66- [ "h2" , "http/1.1" , "http/1.0" ]
67- end
74+ extend Defaultable
6875 end
6976 end
7077 end
0 commit comments