http-2 0.12.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +10 -7
- data/lib/http/2/base64.rb +45 -0
- data/lib/http/2/client.rb +14 -5
- data/lib/http/2/connection.rb +184 -90
- data/lib/http/2/emitter.rb +4 -5
- data/lib/http/2/error.rb +22 -1
- data/lib/http/2/extensions.rb +51 -0
- data/lib/http/2/flow_buffer.rb +88 -35
- data/lib/http/2/framer.rb +145 -108
- data/lib/http/2/header/compressor.rb +157 -0
- data/lib/http/2/header/decompressor.rb +144 -0
- data/lib/http/2/header/encoding_context.rb +339 -0
- data/lib/http/2/{huffman.rb → header/huffman.rb} +9 -7
- data/lib/http/2/{huffman_statemachine.rb → header/huffman_statemachine.rb} +3 -1
- data/lib/http/2/header.rb +35 -0
- data/lib/http/2/server.rb +39 -14
- data/lib/http/2/stream.rb +86 -17
- data/lib/http/2/version.rb +1 -1
- data/lib/http/2.rb +12 -13
- data/sig/client.rbs +9 -0
- data/sig/connection.rbs +94 -0
- data/sig/emitter.rbs +13 -0
- data/sig/error.rbs +35 -0
- data/sig/extensions.rbs +13 -0
- data/sig/flow_buffer.rbs +21 -0
- data/sig/frame_buffer.rbs +13 -0
- data/sig/framer.rbs +55 -0
- data/sig/header/compressor.rbs +27 -0
- data/sig/header/decompressor.rbs +24 -0
- data/sig/header/encoding_context.rbs +34 -0
- data/sig/header/huffman.rbs +9 -0
- data/sig/header.rbs +27 -0
- data/sig/next.rbs +101 -0
- data/sig/server.rbs +12 -0
- data/sig/stream.rbs +91 -0
- metadata +37 -25
- data/LICENSE +0 -21
- data/lib/http/2/buffer.rb +0 -78
- data/lib/http/2/compressor.rb +0 -580
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c96822381e28e32127984c2dbb7b25b3ad5dd87d69283a752378a9f8778c72ae
|
4
|
+
data.tar.gz: beb68a1eb2670d1d0b742224b5ad65bd2bc299656433b120ff31299a481297ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 173e0163e2b05ff3eefdfcc420f8c3913c97702873964ef6c653f0329726443c4c10d73d7ffff31583b06567ef12c8f6545eae0f3d32c52d9b13d98322c09e32
|
7
|
+
data.tar.gz: 43b38b2bdd3ed6ac90382b98c96b03fd76edefbbf4a385c67c3c8db67e6f755382f09c8a3af848a1d8ed55335ad2925d05793ad71c16c5bb831b07f86e0228be
|
data/README.md
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
# HTTP-2
|
2
2
|
|
3
3
|
[](http://rubygems.org/gems/http-2)
|
4
|
-
[](https://github.com/igrigorik/http-2)
|
5
5
|
|
6
6
|
Pure Ruby, framework and transport agnostic, implementation of HTTP/2 protocol and HPACK header compression with support for:
|
7
7
|
|
8
|
+
|
8
9
|
* [Binary framing](https://hpbn.co/http2/#binary-framing-layer) parsing and encoding
|
9
10
|
* [Stream multiplexing](https://hpbn.co/http2/#streams-messages-and-frames) and [prioritization](https://hpbn.co/http2/#stream-prioritization)
|
10
11
|
* Connection and stream [flow control](https://hpbn.co/http2/#flow-control)
|
11
12
|
* [Header compression](https://hpbn.co/http2/#header-compression) and [server push](https://hpbn.co/http2/#server-push)
|
12
13
|
* Connection and stream management
|
13
|
-
* And more... see [API docs](
|
14
|
+
* And more... see [API docs](https://www.rubydoc.info/gems/http-2)
|
14
15
|
|
15
16
|
Protocol specifications:
|
16
17
|
|
@@ -30,6 +31,7 @@ Your code is responsible for feeding data into the parser, which performs all of
|
|
30
31
|
|
31
32
|
```ruby
|
32
33
|
require 'http/2'
|
34
|
+
|
33
35
|
socket = YourTransport.new
|
34
36
|
|
35
37
|
conn = HTTP2::Client.new
|
@@ -40,12 +42,12 @@ while bytes = socket.read
|
|
40
42
|
end
|
41
43
|
```
|
42
44
|
|
43
|
-
Checkout provided [client](
|
45
|
+
Checkout provided [client](example/client.rb) and [server](example/server.rb) implementations for basic examples.
|
44
46
|
|
45
47
|
|
46
48
|
### Connection lifecycle management
|
47
49
|
|
48
|
-
Depending on the role of the endpoint you must initialize either a [Client](http
|
50
|
+
Depending on the role of the endpoint you must initialize either a [Client](lib/http/2/client.rb) or a [Server](lib/http/2/server.rb) object. Doing so picks the appropriate header compression / decompression algorithms and stream management logic. From there, you can subscribe to connection level events, or invoke appropriate APIs to allocate new streams and manage the lifecycle. For example:
|
49
51
|
|
50
52
|
```ruby
|
51
53
|
# - Server ---------------
|
@@ -148,7 +150,7 @@ conn.on(:stream) do |stream|
|
|
148
150
|
end
|
149
151
|
```
|
150
152
|
|
151
|
-
Events emitted by the [Stream object](http
|
153
|
+
Events emitted by the [Stream object](lib/http/2/stream.rb):
|
152
154
|
|
153
155
|
<table>
|
154
156
|
<tr>
|
@@ -252,7 +254,7 @@ conn.on(:stream) do |stream|
|
|
252
254
|
# split response between multiple DATA frames
|
253
255
|
stream.data(response_chunk, end_stream: false)
|
254
256
|
stream.data(last_chunk)
|
255
|
-
|
257
|
+
|
256
258
|
# now send the previously promised data
|
257
259
|
push_stream.data(push_data)
|
258
260
|
end
|
@@ -283,4 +285,5 @@ rake
|
|
283
285
|
|
284
286
|
### License
|
285
287
|
|
286
|
-
(MIT License) - Copyright (c) 2013 Ilya Grigorik 
|
288
|
+
(MIT License) - Copyright (c) 2013-2019 Ilya Grigorik 
|
289
|
+
(MIT License) - Copyright (c) 2019 Tiago Cardoso 
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if RUBY_VERSION < "3.3.0"
|
4
|
+
require "base64"
|
5
|
+
elsif !defined?(Base64)
|
6
|
+
module HTTP2
|
7
|
+
# require "base64" will not be a default gem after ruby 3.4.0
|
8
|
+
module Base64
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def encode64(bin)
|
12
|
+
[bin].pack("m")
|
13
|
+
end
|
14
|
+
|
15
|
+
def decode64(str)
|
16
|
+
str.unpack1("m")
|
17
|
+
end
|
18
|
+
|
19
|
+
def strict_encode64(bin)
|
20
|
+
[bin].pack("m0")
|
21
|
+
end
|
22
|
+
|
23
|
+
def strict_decode64(str)
|
24
|
+
str.unpack1("m0")
|
25
|
+
end
|
26
|
+
|
27
|
+
def urlsafe_encode64(bin, padding: true)
|
28
|
+
str = strict_encode64(bin)
|
29
|
+
str.chomp!("==") or str.chomp!("=") unless padding
|
30
|
+
str.tr!("+/", "-_")
|
31
|
+
str
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def urlsafe_decode64(str)
|
36
|
+
if !str.end_with?("=") && str.length % 4 != 0
|
37
|
+
str = str.ljust((str.length + 3) & ~3, "=")
|
38
|
+
str.tr!("-_", "+/")
|
39
|
+
else
|
40
|
+
str = str.tr("-_", "+/")
|
41
|
+
end
|
42
|
+
strict_decode64(str)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/http/2/client.rb
CHANGED
@@ -20,7 +20,7 @@ module HTTP2
|
|
20
20
|
#
|
21
21
|
class Client < Connection
|
22
22
|
# Initialize new HTTP 2.0 client object.
|
23
|
-
def initialize(
|
23
|
+
def initialize(settings = {})
|
24
24
|
@stream_id = 1
|
25
25
|
@state = :waiting_connection_preface
|
26
26
|
|
@@ -37,20 +37,23 @@ module HTTP2
|
|
37
37
|
# @param frame [Hash]
|
38
38
|
def send(frame)
|
39
39
|
send_connection_preface
|
40
|
-
super
|
40
|
+
super
|
41
41
|
end
|
42
42
|
|
43
43
|
def receive(frame)
|
44
44
|
send_connection_preface
|
45
|
-
super
|
45
|
+
super
|
46
46
|
end
|
47
47
|
|
48
48
|
# sends the preface and initializes the first stream in half-closed state
|
49
49
|
def upgrade
|
50
|
+
@h2c_upgrade = :start
|
50
51
|
raise ProtocolError unless @stream_id == 1
|
51
52
|
|
52
53
|
send_connection_preface
|
53
|
-
new_stream(state: :half_closed_local)
|
54
|
+
stream = new_stream(state: :half_closed_local)
|
55
|
+
@h2c_upgrade = :finished
|
56
|
+
stream
|
54
57
|
end
|
55
58
|
|
56
59
|
# Emit the connection preface if not yet
|
@@ -64,9 +67,15 @@ module HTTP2
|
|
64
67
|
settings(payload)
|
65
68
|
end
|
66
69
|
|
67
|
-
def self.settings_header(
|
70
|
+
def self.settings_header(settings)
|
68
71
|
frame = Framer.new.generate(type: :settings, stream: 0, payload: settings)
|
69
72
|
Base64.urlsafe_encode64(frame[9..-1])
|
70
73
|
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def verify_pseudo_headers(frame)
|
78
|
+
_verify_pseudo_headers(frame, RESPONSE_MANDATORY_HEADERS)
|
79
|
+
end
|
71
80
|
end
|
72
81
|
end
|