Class: Iodine::Http::Http2
- Inherits:
-
Protocol
show all
- Defined in:
- lib/iodine/http/hpack.rb,
lib/iodine/http/http2.rb
Defined Under Namespace
Classes: HPACK
Instance Attribute Summary
Attributes inherited from Protocol
#io, #locker, #options
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Protocol
#call, #close, #closed?, each, #id, #initialize, #on_close, #read, #set_timeout, #ssl?, #timeout?, #write
Class Method Details
.handshake(request, io, data) ⇒ Object
119
120
121
122
123
124
125
126
|
# File 'lib/iodine/http/http2.rb', line 119
def self.handshake request, io, data
return false unless request['upgrade'.freeze] =~ /h2c/.freeze && request['http2-settings'.freeze]
io.write "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nUpgrade: h2c\r\n\r\n".freeze
http_2 = self.new(io, request)
unless data.eof?
http_2.on_message data.read
end
end
|
.pre_handshake(io, data) ⇒ Object
128
129
130
131
132
|
# File 'lib/iodine/http/http2.rb', line 128
def self.pre_handshake io, data
return false unless data[0..23] == "PRI * HTTP\/2.0\r\n\r\nSM\r\n\r\n".freeze
self.new(io).on_message data
true
end
|
Instance Method Details
#go_away(error_code) ⇒ Object
106
107
108
109
110
111
|
# File 'lib/iodine/http/http2.rb', line 106
def go_away error_code
return false if @io.closed?
@frame_locker.synchronize { emit_frame [@last_stream, error_code].pack('N*'), 0, 7 }
close
end
|
#on_message(data) ⇒ Object
56
57
58
59
60
|
# File 'lib/iodine/http/http2.rb', line 56
def on_message data
data = ::StringIO.new data
parse_preface data unless @connected
true while parse_frame data
end
|
#on_open ⇒ Object
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
|
# File 'lib/iodine/http/http2.rb', line 4
def on_open
::Iodine.warn "Http/2 requested - support is still experimental."
set_timeout 15
@hpack = ::Iodine::Http::Http2::HPACK.new
= String.new
= false
= nil
@frame_locker = Mutex.new
@frame = {}
@open_streams = {}
@connected = false
@last_stream = 0
@refuese_new = false
@settings = DEFAULT_SETTING.dup
return unless @options
::Iodine.warn "Http/2: upgrade handshake settings not implemented. upgrade request:\n#{@options}"
@last_stream = @options[:stream_id] = 1
@options[:io] = self
::Iodine.run @options, &(::Iodine::Http::Http2.dispatch)
@options = nil
end
|
#on_shutdown ⇒ Object
Gracefully close HTTP/2 when possible
114
115
116
|
# File 'lib/iodine/http/http2.rb', line 114
def on_shutdown
go_away NO_ERROR
end
|
#ping ⇒ Object
93
94
95
|
# File 'lib/iodine/http/http2.rb', line 93
def ping
@frame_locker.synchronize { emit_frame "pniodine".freeze, 0, 6 }
end
|
#push(request) ⇒ Object
97
98
99
100
101
102
103
104
|
# File 'lib/iodine/http/http2.rb', line 97
def push request
return false if @settings[SETTINGS_ENABLE_PUSH] == 0
@last_push ||= 0
emit_payload @hpack.encode(path: request[:path], method: request[:method], scheme: request[:scheme], authority: request[:authority]), (request[:sid] = (@last_push += 2)), 5, 4
Iodine.run( request, &::Iodine::Http::Http2.dispatch)
end
|
#send_response(response) ⇒ Object
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
# File 'lib/iodine/http/http2.rb', line 62
def send_response response
return false if response..frozen?
body = response.extract_body
request = response.request
return body && body.close unless response, request
return log_finished(response) && body && body.close if request.head?
if body
until body.eof?
response.bytes_written += emit_payload(body.read(@settings[SETTINGS_MAX_FRAME_SIZE], Thread.current[:write_buffer]), request[:sid], 0, (body.eof? ? 1 : 0))
end
body.close
else
emit_payload(''.freeze, request[:sid], 0, 1)
end
log_finished response
end
|
#stream_response(response, finish = false) ⇒ Object
79
80
81
82
83
84
85
86
87
88
89
90
91
|
# File 'lib/iodine/http/http2.rb', line 79
def stream_response response, finish = false
request = response.request
body = response.extract_body
response, request
return body && body.close if request.head?
if body
response.bytes_written += emit_payload body, request[:sid], 0,(finish ? 1 : 0)
body.close
elsif finish
emit_payload(''.freeze, request[:sid], 0, 1)
end
log_finished response if finish
end
|