Async::HTTPSourceAsyncHTTPProtocolHTTP

class HTTP

HTTP is an http:// server that auto-selects HTTP/1.1 or HTTP/2 by detecting the HTTP/2 connection preface.

Definitions

def initialize(http1: HTTP1, http2: HTTP2)

Create a new HTTP protocol instance.

Signature

parameter http1 HTTP1

The HTTP/1 protocol instance.

parameter http2 HTTP2

The HTTP/2 protocol instance.

Implementation

def initialize(http1: HTTP1, http2: HTTP2)
	@http1 = http1
	@http2 = http2
end

def protocol_for(stream)

Determine if the inbound connection is HTTP/1 or HTTP/2.

Signature

parameter stream IO::Stream

The stream to detect the protocol for.

returns Class

The protocol class to use.

Implementation

def protocol_for(stream)
	# Detect HTTP/2 connection preface
	# https://www.rfc-editor.org/rfc/rfc9113.html#section-3.4
	preface = stream.peek do |read_buffer|
		if read_buffer.bytesize >= HTTP2_PREFACE_SIZE
			break read_buffer[0, HTTP2_PREFACE_SIZE]
		elsif read_buffer.bytesize > 0
			# If partial read_buffer already doesn't match, no need to wait for more bytes.
			break read_buffer unless HTTP2_PREFACE[read_buffer]
		end
	end
	
	if preface == HTTP2_PREFACE
		@http2
	else
		@http1
	end
end

def client(peer, **options)

Create a client for an outbound connection. Defaults to HTTP/1 for plaintext connections.

Signature

parameter peer IO

The peer to communicate with.

parameter options Hash

Options to pass to the protocol, keyed by protocol class.

Implementation

def client(peer, **options)
	options = options[@http1] || {}
	
	return @http1.client(peer, **options)
end

def server(peer, **options)

Create a server for an inbound connection. Able to detect HTTP1 and HTTP2.

Signature

parameter peer IO

The peer to communicate with.

parameter options Hash

Options to pass to the protocol, keyed by protocol class.

Implementation

def server(peer, **options)
	stream = IO::Stream(peer)
	protocol = protocol_for(stream)
	options = options[protocol] || {}
	
	return protocol.server(stream, **options)
end