-
-
Notifications
You must be signed in to change notification settings - Fork 45
/
server.rb
74 lines (56 loc) · 1.69 KB
/
server.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# frozen_string_literal: true
# Released under the MIT License.
# Copyright, 2018-2024, by Samuel Williams.
require_relative 'connection'
require_relative 'request'
require 'protocol/http2/server'
module Async
module HTTP
module Protocol
module HTTP2
class Server < ::Protocol::HTTP2::Server
include Connection
def initialize(stream)
# Used by some generic methods in Connetion:
@stream = stream
framer = ::Protocol::HTTP2::Framer.new(stream)
super(framer)
@requests = Async::Queue.new
end
attr :requests
def accept_stream(stream_id)
super do
Request::Stream.create(self, stream_id)
end
end
def close(error = nil)
if @requests
# Stop the request loop:
@requests.enqueue(nil)
@requests = nil
end
super
end
def each(task: Task.current)
task.annotate("Reading #{version} requests for #{self.class}.")
# It's possible the connection has died before we get here...
@requests&.async do |task, request|
task.annotate("Incoming request: #{request.method} #{request.path.inspect}.")
@count += 1
task.defer_stop do
response = yield(request)
rescue
# We need to close the stream if the user code blows up while generating a response:
request.stream.send_reset_stream(::Protocol::HTTP2::INTERNAL_ERROR)
raise
else
request.send_response(response)
end
end
# Maybe we should add some synchronisation here - i.e. only exit once all requests are finished.
end
end
end
end
end
end