4
4
# Copyright, 2024, by Thomas Morgan.
5
5
# Copyright, 2024, by Samuel Williams.
6
6
7
+ require_relative "defaultable"
8
+
7
9
require_relative "http1"
8
10
require_relative "http2"
9
11
10
12
module Async
11
13
module HTTP
12
14
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
16
17
HTTP2_PREFACE = "PRI * HTTP/2.0\r \n \r \n SM\r \n \r \n "
17
18
HTTP2_PREFACE_SIZE = HTTP2_PREFACE . bytesize
18
19
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
+
19
29
# Determine if the inbound connection is HTTP/1 or HTTP/2.
20
30
#
21
31
# @parameter stream [IO::Stream] The stream to detect the protocol for.
22
32
# @returns [Class] The protocol class to use.
23
- def self . protocol_for ( stream )
33
+ def protocol_for ( stream )
24
34
# Detect HTTP/2 connection preface
25
35
# https://www.rfc-editor.org/rfc/rfc9113.html#section-3.4
26
36
preface = stream . peek do |read_buffer |
@@ -33,38 +43,35 @@ def self.protocol_for(stream)
33
43
end
34
44
35
45
if preface == HTTP2_PREFACE
36
- HTTP2
46
+ @http2
37
47
else
38
- HTTP1
48
+ @http1
39
49
end
40
50
end
41
51
42
52
# Create a client for an outbound connection. Defaults to HTTP/1 for plaintext connections.
43
53
#
44
54
# @parameter peer [IO] The peer to communicate with.
45
55
# @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 ] || { }
48
58
49
- HTTP1 . client ( peer , **options )
59
+ @http1 . client ( peer , **options )
50
60
end
51
61
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.
53
63
#
54
64
# @parameter peer [IO] The peer to communicate with.
55
65
# @parameter options [Hash] Options to pass to the protocol, keyed by protocol class.
56
- def self . server ( peer , **options )
66
+ def server ( peer , **options )
57
67
stream = ::IO ::Stream ( peer )
58
68
protocol = protocol_for ( stream )
59
69
options = options [ protocol ] || { }
60
70
61
71
return protocol . server ( stream , **options )
62
72
end
63
73
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
68
75
end
69
76
end
70
77
end
0 commit comments