http-2 0.11.0 → 1.0.0

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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -9
  3. data/lib/http/2/base64.rb +45 -0
  4. data/lib/http/2/client.rb +19 -6
  5. data/lib/http/2/connection.rb +235 -163
  6. data/lib/http/2/emitter.rb +7 -5
  7. data/lib/http/2/error.rb +24 -1
  8. data/lib/http/2/extensions.rb +53 -0
  9. data/lib/http/2/flow_buffer.rb +91 -33
  10. data/lib/http/2/framer.rb +184 -157
  11. data/lib/http/2/header/compressor.rb +157 -0
  12. data/lib/http/2/header/decompressor.rb +144 -0
  13. data/lib/http/2/header/encoding_context.rb +337 -0
  14. data/lib/http/2/{huffman.rb → header/huffman.rb} +25 -19
  15. data/lib/http/2/{huffman_statemachine.rb → header/huffman_statemachine.rb} +2 -0
  16. data/lib/http/2/header.rb +35 -0
  17. data/lib/http/2/server.rb +47 -20
  18. data/lib/http/2/stream.rb +130 -61
  19. data/lib/http/2/version.rb +3 -1
  20. data/lib/http/2.rb +14 -13
  21. data/sig/client.rbs +9 -0
  22. data/sig/connection.rbs +93 -0
  23. data/sig/emitter.rbs +13 -0
  24. data/sig/error.rbs +35 -0
  25. data/sig/extensions.rbs +5 -0
  26. data/sig/flow_buffer.rbs +21 -0
  27. data/sig/frame_buffer.rbs +13 -0
  28. data/sig/framer.rbs +54 -0
  29. data/sig/header/compressor.rbs +27 -0
  30. data/sig/header/decompressor.rbs +22 -0
  31. data/sig/header/encoding_context.rbs +34 -0
  32. data/sig/header/huffman.rbs +9 -0
  33. data/sig/header.rbs +27 -0
  34. data/sig/next.rbs +101 -0
  35. data/sig/server.rbs +12 -0
  36. data/sig/stream.rbs +91 -0
  37. metadata +38 -79
  38. data/.autotest +0 -20
  39. data/.coveralls.yml +0 -1
  40. data/.gitignore +0 -20
  41. data/.gitmodules +0 -3
  42. data/.rspec +0 -5
  43. data/.rubocop.yml +0 -93
  44. data/.rubocop_todo.yml +0 -131
  45. data/.travis.yml +0 -17
  46. data/Gemfile +0 -16
  47. data/Guardfile +0 -18
  48. data/Guardfile.h2spec +0 -12
  49. data/LICENSE +0 -21
  50. data/Rakefile +0 -49
  51. data/example/Gemfile +0 -3
  52. data/example/README.md +0 -44
  53. data/example/client.rb +0 -122
  54. data/example/helper.rb +0 -19
  55. data/example/keys/server.crt +0 -20
  56. data/example/keys/server.key +0 -27
  57. data/example/server.rb +0 -139
  58. data/example/upgrade_client.rb +0 -153
  59. data/example/upgrade_server.rb +0 -203
  60. data/http-2.gemspec +0 -22
  61. data/lib/http/2/buffer.rb +0 -76
  62. data/lib/http/2/compressor.rb +0 -572
  63. data/lib/tasks/generate_huffman_table.rb +0 -166
  64. data/spec/buffer_spec.rb +0 -28
  65. data/spec/client_spec.rb +0 -188
  66. data/spec/compressor_spec.rb +0 -666
  67. data/spec/connection_spec.rb +0 -681
  68. data/spec/emitter_spec.rb +0 -54
  69. data/spec/framer_spec.rb +0 -487
  70. data/spec/h2spec/h2spec.darwin +0 -0
  71. data/spec/h2spec/output/non_secure.txt +0 -317
  72. data/spec/helper.rb +0 -147
  73. data/spec/hpack_test_spec.rb +0 -84
  74. data/spec/huffman_spec.rb +0 -68
  75. data/spec/server_spec.rb +0 -52
  76. data/spec/stream_spec.rb +0 -878
  77. data/spec/support/deep_dup.rb +0 -55
  78. data/spec/support/duplicable.rb +0 -98
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5617138c0740b55546b79e29a06978a9fcb9aae208ccb2f695c32939eca5f88a
4
- data.tar.gz: 193880583c0a80aa569f433977af1798c98be25a86fb782a410e16eb38d5116c
3
+ metadata.gz: c5b015395ca278b22ea3af7f2c0c149071ddb1ad4cd5db5c52329554de87fe27
4
+ data.tar.gz: 3f7a6d671bd23efe5b60f16dc39294b6cd7a45d6087ff1be70f0624f682895a5
5
5
  SHA512:
6
- metadata.gz: 46fde2633ab7d074136a32e7ae8cdf90ecd037f3a95bfeabab9557d72a13487a47a3e298339bc74df4d89c6b802537b9c35a1f7709fd6cf1f4fde44eecbe468e
7
- data.tar.gz: 6eadeb79f3bbf6fa1911933e2dc399bfe50ae08c598cb72278a37e0c42102bf27ccbed77b7acb5e7f1e85a55bd6967e63a8950fa3184fb7c9eef750c8a9e123c
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 Status](https://travis-ci.org/igrigorik/http-2.svg?branch=master)](https://travis-ci.org/igrigorik/http-2)
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](http://www.rubydoc.info/github/igrigorik/http-2/frames)
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](https://github.com/igrigorik/http-2/blob/master/example/client.rb) and [server](https://github.com/igrigorik/http-2/blob/master/example/server.rb) implementations for basic examples.
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://www.rubydoc.info/github/igrigorik/http-2/HTTP2/Client) or a [Server](http://www.rubydoc.info/github/igrigorik/http-2/HTTP2/Server) 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:
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://www.rubydoc.info/github/igrigorik/http-2/HTTP2/Stream):
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(**settings)
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(frame)
40
+ super
39
41
  end
40
42
 
41
43
  def receive(frame)
42
44
  send_connection_preface
43
- super(frame)
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
- fail ProtocolError unless @stream_id == 1
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(**settings)
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