http-2 0.11.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -9
- data/lib/http/2/base64.rb +45 -0
- data/lib/http/2/client.rb +19 -6
- data/lib/http/2/connection.rb +235 -163
- data/lib/http/2/emitter.rb +7 -5
- data/lib/http/2/error.rb +24 -1
- data/lib/http/2/extensions.rb +53 -0
- data/lib/http/2/flow_buffer.rb +91 -33
- data/lib/http/2/framer.rb +184 -157
- 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 +337 -0
- data/lib/http/2/{huffman.rb → header/huffman.rb} +25 -19
- data/lib/http/2/{huffman_statemachine.rb → header/huffman_statemachine.rb} +2 -0
- data/lib/http/2/header.rb +35 -0
- data/lib/http/2/server.rb +47 -20
- data/lib/http/2/stream.rb +130 -61
- data/lib/http/2/version.rb +3 -1
- data/lib/http/2.rb +14 -13
- data/sig/client.rbs +9 -0
- data/sig/connection.rbs +93 -0
- data/sig/emitter.rbs +13 -0
- data/sig/error.rbs +35 -0
- data/sig/extensions.rbs +5 -0
- data/sig/flow_buffer.rbs +21 -0
- data/sig/frame_buffer.rbs +13 -0
- data/sig/framer.rbs +54 -0
- data/sig/header/compressor.rbs +27 -0
- data/sig/header/decompressor.rbs +22 -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 +38 -79
- data/.autotest +0 -20
- data/.coveralls.yml +0 -1
- data/.gitignore +0 -20
- data/.gitmodules +0 -3
- data/.rspec +0 -5
- data/.rubocop.yml +0 -93
- data/.rubocop_todo.yml +0 -131
- data/.travis.yml +0 -17
- data/Gemfile +0 -16
- data/Guardfile +0 -18
- data/Guardfile.h2spec +0 -12
- data/LICENSE +0 -21
- data/Rakefile +0 -49
- data/example/Gemfile +0 -3
- data/example/README.md +0 -44
- data/example/client.rb +0 -122
- data/example/helper.rb +0 -19
- data/example/keys/server.crt +0 -20
- data/example/keys/server.key +0 -27
- data/example/server.rb +0 -139
- data/example/upgrade_client.rb +0 -153
- data/example/upgrade_server.rb +0 -203
- data/http-2.gemspec +0 -22
- data/lib/http/2/buffer.rb +0 -76
- data/lib/http/2/compressor.rb +0 -572
- data/lib/tasks/generate_huffman_table.rb +0 -166
- data/spec/buffer_spec.rb +0 -28
- data/spec/client_spec.rb +0 -188
- data/spec/compressor_spec.rb +0 -666
- data/spec/connection_spec.rb +0 -681
- data/spec/emitter_spec.rb +0 -54
- data/spec/framer_spec.rb +0 -487
- data/spec/h2spec/h2spec.darwin +0 -0
- data/spec/h2spec/output/non_secure.txt +0 -317
- data/spec/helper.rb +0 -147
- data/spec/hpack_test_spec.rb +0 -84
- data/spec/huffman_spec.rb +0 -68
- data/spec/server_spec.rb +0 -52
- data/spec/stream_spec.rb +0 -878
- data/spec/support/deep_dup.rb +0 -55
- data/spec/support/duplicable.rb +0 -98
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5b015395ca278b22ea3af7f2c0c149071ddb1ad4cd5db5c52329554de87fe27
|
4
|
+
data.tar.gz: 3f7a6d671bd23efe5b60f16dc39294b6cd7a45d6087ff1be70f0624f682895a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce8dff286d18b7607a338572b9b85ab2ff88eb8a28b8de8a6139344d0cc2f3ebc700ca9affc8398526b88fb95b7fe5da90209c5c6fbdff155c319f9e8691062b
|
7
|
+
data.tar.gz: b7f920fc81747d811855eec66a8f63e5a18d5a8ca49d81efe8f6567c6c72a1275c4846219a1532855834717453a7e0d914d3138296fb24876f5af3d9c3151772
|
data/README.md
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
# HTTP-2
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/http-2.svg)](http://rubygems.org/gems/http-2)
|
4
|
-
[![Build
|
5
|
-
[![Coverage Status](https://coveralls.io/repos/igrigorik/http-2/badge.svg)](https://coveralls.io/r/igrigorik/http-2)
|
6
|
-
[![Analytics](https://ga-beacon.appspot.com/UA-71196-10/http-2/readme)](https://github.com/igrigorik/ga-beacon)
|
4
|
+
[![Build status](https://github.com/igrigorik/http-2/actions/workflows/ci.yml/badge.svg)](https://github.com/igrigorik/http-2)
|
7
5
|
|
8
6
|
Pure Ruby, framework and transport agnostic, implementation of HTTP/2 protocol and HPACK header compression with support for:
|
9
7
|
|
8
|
+
|
10
9
|
* [Binary framing](https://hpbn.co/http2/#binary-framing-layer) parsing and encoding
|
11
10
|
* [Stream multiplexing](https://hpbn.co/http2/#streams-messages-and-frames) and [prioritization](https://hpbn.co/http2/#stream-prioritization)
|
12
11
|
* Connection and stream [flow control](https://hpbn.co/http2/#flow-control)
|
13
12
|
* [Header compression](https://hpbn.co/http2/#header-compression) and [server push](https://hpbn.co/http2/#server-push)
|
14
13
|
* Connection and stream management
|
15
|
-
* And more... see [API docs](
|
14
|
+
* And more... see [API docs](https://www.rubydoc.info/gems/http-2)
|
16
15
|
|
17
16
|
Protocol specifications:
|
18
17
|
|
@@ -32,6 +31,7 @@ Your code is responsible for feeding data into the parser, which performs all of
|
|
32
31
|
|
33
32
|
```ruby
|
34
33
|
require 'http/2'
|
34
|
+
|
35
35
|
socket = YourTransport.new
|
36
36
|
|
37
37
|
conn = HTTP2::Client.new
|
@@ -42,12 +42,12 @@ while bytes = socket.read
|
|
42
42
|
end
|
43
43
|
```
|
44
44
|
|
45
|
-
Checkout provided [client](
|
45
|
+
Checkout provided [client](example/client.rb) and [server](example/server.rb) implementations for basic examples.
|
46
46
|
|
47
47
|
|
48
48
|
### Connection lifecycle management
|
49
49
|
|
50
|
-
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:
|
51
51
|
|
52
52
|
```ruby
|
53
53
|
# - Server ---------------
|
@@ -150,7 +150,7 @@ conn.on(:stream) do |stream|
|
|
150
150
|
end
|
151
151
|
```
|
152
152
|
|
153
|
-
Events emitted by the [Stream object](http
|
153
|
+
Events emitted by the [Stream object](lib/http/2/stream.rb):
|
154
154
|
|
155
155
|
<table>
|
156
156
|
<tr>
|
@@ -254,7 +254,7 @@ conn.on(:stream) do |stream|
|
|
254
254
|
# split response between multiple DATA frames
|
255
255
|
stream.data(response_chunk, end_stream: false)
|
256
256
|
stream.data(last_chunk)
|
257
|
-
|
257
|
+
|
258
258
|
# now send the previously promised data
|
259
259
|
push_stream.data(push_data)
|
260
260
|
end
|
@@ -285,4 +285,5 @@ rake
|
|
285
285
|
|
286
286
|
### License
|
287
287
|
|
288
|
-
(MIT License) - Copyright (c) 2013 Ilya Grigorik ![GA](https://www.google-analytics.com/__utm.gif?utmac=UA-71196-9&utmhn=github.com&utmdt=HTTP2&utmp=/http-2/readme)
|
288
|
+
(MIT License) - Copyright (c) 2013-2019 Ilya Grigorik ![GA](https://www.google-analytics.com/__utm.gif?utmac=UA-71196-9&utmhn=github.com&utmdt=HTTP2&utmp=/http-2/readme)
|
289
|
+
(MIT License) - Copyright (c) 2019 Tiago Cardoso ![GA](https://www.google-analytics.com/__utm.gif?utmac=UA-71196-9&utmhn=github.com&utmdt=HTTP2&utmp=/http-2/readme)
|
@@ -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
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HTTP2
|
2
4
|
# HTTP 2.0 client connection class that implements appropriate header
|
3
5
|
# compression / decompression algorithms and stream management logic.
|
@@ -18,7 +20,7 @@ module HTTP2
|
|
18
20
|
#
|
19
21
|
class Client < Connection
|
20
22
|
# Initialize new HTTP 2.0 client object.
|
21
|
-
def initialize(
|
23
|
+
def initialize(settings = {})
|
22
24
|
@stream_id = 1
|
23
25
|
@state = :waiting_connection_preface
|
24
26
|
|
@@ -35,24 +37,29 @@ module HTTP2
|
|
35
37
|
# @param frame [Hash]
|
36
38
|
def send(frame)
|
37
39
|
send_connection_preface
|
38
|
-
super
|
40
|
+
super
|
39
41
|
end
|
40
42
|
|
41
43
|
def receive(frame)
|
42
44
|
send_connection_preface
|
43
|
-
super
|
45
|
+
super
|
44
46
|
end
|
45
47
|
|
46
48
|
# sends the preface and initializes the first stream in half-closed state
|
47
49
|
def upgrade
|
48
|
-
|
50
|
+
@h2c_upgrade = :start
|
51
|
+
raise ProtocolError unless @stream_id == 1
|
52
|
+
|
49
53
|
send_connection_preface
|
50
|
-
new_stream(state: :half_closed_local)
|
54
|
+
stream = new_stream(state: :half_closed_local)
|
55
|
+
@h2c_upgrade = :finished
|
56
|
+
stream
|
51
57
|
end
|
52
58
|
|
53
59
|
# Emit the connection preface if not yet
|
54
60
|
def send_connection_preface
|
55
61
|
return unless @state == :waiting_connection_preface
|
62
|
+
|
56
63
|
@state = :connected
|
57
64
|
emit(:frame, CONNECTION_PREFACE_MAGIC)
|
58
65
|
|
@@ -60,9 +67,15 @@ module HTTP2
|
|
60
67
|
settings(payload)
|
61
68
|
end
|
62
69
|
|
63
|
-
def self.settings_header(
|
70
|
+
def self.settings_header(settings)
|
64
71
|
frame = Framer.new.generate(type: :settings, stream: 0, payload: settings)
|
65
72
|
Base64.urlsafe_encode64(frame[9..-1])
|
66
73
|
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def verify_pseudo_headers(frame)
|
78
|
+
_verify_pseudo_headers(frame, RESPONSE_MANDATORY_HEADERS)
|
79
|
+
end
|
67
80
|
end
|
68
81
|
end
|