http-2 0.8.2 → 0.8.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 90034b82f924807e4b3cb874fceae2d8fde0c74d
4
- data.tar.gz: afe0a06580910045bd50d8920f1aaf2e7f5a9a01
3
+ metadata.gz: b7732a1022ca5c6c097c2b575ef214e7118d2646
4
+ data.tar.gz: 6d9def6bbeb440c2070edb5bd3cc38313cd360fe
5
5
  SHA512:
6
- metadata.gz: 5a272a1d3f656e7a94888d027b81cd42a462b05d3d2c94525d39d91f6d327a13a79dbfdd63f275237ca7fbf46d95694f682305e279e2803b9616922f1dbe7bcf
7
- data.tar.gz: de83deb546e98b3819904aae7b9d66024ee49f72c363c071829461ced9e3c4641529404bb17e5631c6274f90f7fdb89574315d6153e45dc17298c060bd0b6674
6
+ metadata.gz: c166616d45fdf27d87514770287e409dcdc97a5f0e821fe4da970fd99b3487cbbe7b2679d99e055d3b04474eb92bf27cd8655509d5facc55315a351b1a1d2246
7
+ data.tar.gz: a6888d5a873081b38bd2245f7c6c1be6cf456b5a39b7adc595b8b693fcac31fc50f3bd876c6293f93c76ec37cdb924aa846562eff71215d5e4af60bf282e452f
data/.gitignore CHANGED
@@ -3,11 +3,14 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
+ .DS_Store
7
+ .idea
6
8
  Gemfile.lock
7
9
  InstalledFiles
8
10
  _yardoc
9
11
  coverage
10
12
  doc/
13
+ vendor/
11
14
  lib/bundler/man
12
15
  pkg
13
16
  rdoc
@@ -1,9 +1,15 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
3
  AllCops:
4
+ TargetRubyVersion: 2.1
4
5
  DisplayCopNames: true
5
6
  Exclude:
6
- - 'bin/*'
7
+ - 'bin/**'
8
+ - 'vendor/**/*'
9
+ - '**/huffman_statemachine.rb'
10
+
11
+ Metrics/LineLength:
12
+ Max: 120
7
13
 
8
14
  Lint/EndAlignment:
9
15
  AlignWith: variable
@@ -14,5 +20,38 @@ Style/CaseIndentation:
14
20
  Style/IndentHash:
15
21
  EnforcedStyle: consistent
16
22
 
17
- Style/TrailingComma:
23
+ Style/TrailingCommaInLiteral:
18
24
  EnforcedStyleForMultiline: comma
25
+
26
+ Style/SpaceAroundOperators:
27
+ Enabled: false
28
+
29
+ Style/ExtraSpacing:
30
+ Enabled: false
31
+
32
+ Style/SignalException:
33
+ Enabled: false
34
+
35
+ Style/FrozenStringLiteralComment:
36
+ Enabled: false
37
+
38
+ Style/ParallelAssignment:
39
+ Enabled: false
40
+
41
+ Style/ParenthesesAroundCondition:
42
+ Enabled: false
43
+
44
+ Style/IfInsideElse:
45
+ Enabled: false
46
+
47
+ Style/TrailingCommaInArguments:
48
+ Enabled: false
49
+
50
+ Style/TrailingUnderscoreVariable:
51
+ Enabled: false
52
+
53
+ Performance/TimesMap:
54
+ Enabled: false
55
+
56
+ Performance/RedundantBlockCall:
57
+ Enabled: false
@@ -1,33 +1,35 @@
1
- # This configuration was generated by `rubocop --auto-gen-config`
2
- # on 2015-04-06 10:04:21 -0700 using RuboCop version 0.30.0.
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2016-06-09 10:57:54 -0400 using RuboCop version 0.40.0.
3
4
  # The point is for the user to remove these configuration records
4
5
  # one by one as the offenses are removed from the code base.
5
6
  # Note that changes in the inspected code, or installation of new
6
7
  # versions of RuboCop, may require this file to be generated again.
7
8
 
8
- # Offense count: 23
9
+ # Offense count: 24
9
10
  Metrics/AbcSize:
10
- Max: 186
11
+ Max: 185
11
12
 
12
13
  # Offense count: 16
13
14
  Metrics/BlockNesting:
14
15
  Max: 5
15
16
 
16
- # Offense count: 7
17
+ # Offense count: 5
17
18
  # Configuration parameters: CountComments.
18
19
  Metrics/ClassLength:
19
- Max: 331
20
+ Max: 325
20
21
 
21
22
  # Offense count: 12
22
23
  Metrics/CyclomaticComplexity:
23
24
  Max: 60
24
25
 
25
- # Offense count: 349
26
- # Configuration parameters: AllowURI, URISchemes.
26
+ # Offense count: 9
27
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
28
+ # URISchemes: http, https
27
29
  Metrics/LineLength:
28
- Max: 231
30
+ Max: 108
29
31
 
30
- # Offense count: 27
32
+ # Offense count: 29
31
33
  # Configuration parameters: CountComments.
32
34
  Metrics/MethodLength:
33
35
  Max: 134
@@ -41,6 +43,77 @@ Metrics/ParameterLists:
41
43
  Metrics/PerceivedComplexity:
42
44
  Max: 46
43
45
 
44
- # Offense count: 7
46
+ # Offense count: 1
47
+ # Cop supports --auto-correct.
48
+ # Configuration parameters: MaxKeyValuePairs.
49
+ Performance/RedundantMerge:
50
+ Exclude:
51
+ - 'lib/http/2/server.rb'
52
+
53
+ # Offense count: 4
45
54
  Style/Documentation:
46
- Enabled: false
55
+ Exclude:
56
+ - 'spec/**/*'
57
+ - 'test/**/*'
58
+ - 'example/helper.rb'
59
+ - 'example/upgrade_server.rb'
60
+ - 'lib/tasks/generate_huffman_table.rb'
61
+
62
+ # Offense count: 1
63
+ # Cop supports --auto-correct.
64
+ Style/EmptyCaseCondition:
65
+ Exclude:
66
+ - 'example/upgrade_server.rb'
67
+
68
+ # Offense count: 1
69
+ # Configuration parameters: MinBodyLength.
70
+ Style/GuardClause:
71
+ Exclude:
72
+ - 'lib/http/2/connection.rb'
73
+
74
+ # Offense count: 2
75
+ # Cop supports --auto-correct.
76
+ # Configuration parameters: SupportedStyles, IndentationWidth.
77
+ # SupportedStyles: special_inside_parentheses, consistent, align_brackets
78
+ Style/IndentArray:
79
+ EnforcedStyle: consistent
80
+
81
+ # Offense count: 1
82
+ # Cop supports --auto-correct.
83
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
84
+ # SupportedStyles: symmetrical, new_line, same_line
85
+ Style/MultilineArrayBraceLayout:
86
+ Exclude:
87
+ - 'spec/compressor_spec.rb'
88
+
89
+ # Offense count: 16
90
+ # Cop supports --auto-correct.
91
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
92
+ # SupportedStyles: symmetrical, new_line, same_line
93
+ Style/MultilineHashBraceLayout:
94
+ Exclude:
95
+ - 'spec/compressor_spec.rb'
96
+
97
+ # Offense count: 1
98
+ # Cop supports --auto-correct.
99
+ Style/MutableConstant:
100
+ Exclude:
101
+ - 'example/upgrade_server.rb'
102
+
103
+ # Offense count: 1
104
+ # Cop supports --auto-correct.
105
+ Style/RedundantSelf:
106
+ Exclude:
107
+ - 'lib/http/2/connection.rb'
108
+
109
+ # Offense count: 1
110
+ # Cop supports --auto-correct.
111
+ Style/UnneededInterpolation:
112
+ Exclude:
113
+ - 'spec/compressor_spec.rb'
114
+
115
+ # Offense count: 1
116
+ # Cop supports --auto-correct.
117
+ Style/ZeroLengthPredicate:
118
+ Exclude:
119
+ - 'lib/http/2/framer.rb'
data/Gemfile CHANGED
@@ -4,14 +4,13 @@ gem 'rake'
4
4
  gem 'yard'
5
5
 
6
6
  group :test do
7
- gem 'activesupport'
8
7
  gem 'autotest-standalone'
9
8
  gem 'coveralls', require: false
10
9
  gem 'pry'
11
10
  gem 'pry-byebug', platform: :mri
12
11
  gem 'rspec', '~> 3.4.0'
13
12
  gem 'rspec-autotest'
14
- gem 'rubocop', '~> 0.30.0'
13
+ gem 'rubocop', '0.43.0'
15
14
  end
16
15
 
17
16
  gemspec
@@ -0,0 +1,19 @@
1
+
2
+ guard :process, name: 'HTTP/2 Server', command: 'ruby example/server.rb', stop_signal: 'TERM' do
3
+ watch(%r{^example/(.+)\.rb$})
4
+ watch(%r{^lib/http/2/(.+)\.rb$})
5
+
6
+ watch('Gemfile.lock')
7
+ end
8
+
9
+ def h2spec
10
+ puts 'Starting H2 Spec'
11
+ sleep 0.7
12
+ system '~/go-workspace/bin/h2spec -p 8080 -o 1 -s 4.2'
13
+ puts "\n"
14
+ end
15
+
16
+ guard :shell, name: 'H2 Spec' do
17
+ watch(%r{^example/(.+)\.rb$}) { h2spec }
18
+ watch(%r{^lib/http/2/(.+)\.rb$}) { h2spec }
19
+ end
@@ -0,0 +1,12 @@
1
+ def h2spec
2
+ puts "Starting H2 Spec"
3
+ sleep 0.7
4
+ system '~/go-workspace/bin/h2spec -p 8080 -o 1 -s 5.1'
5
+ puts "\n"
6
+ end
7
+
8
+ guard :shell, name:'H2 Spec' do
9
+ watch(%r{^example/(.+)\.rb$}) { h2spec }
10
+ watch(%r{^lib/http/2/(.+)\.rb$}) { h2spec }
11
+ end
12
+
data/README.md CHANGED
@@ -239,16 +239,16 @@ conn.on(:stream) do |stream|
239
239
 
240
240
  # fires when client terminates its request (i.e. request finished)
241
241
  stream.on(:half_close) do
242
- head = {
243
- ":status" => 200,
244
- ":path" => "/other_resource",
245
- "content-type" => "text/plain"
246
- }
242
+ promise_header = { ':method' => 'GET',
243
+ ':authority' => 'localhost',
244
+ ':scheme' => 'https',
245
+ ':path' => "/other_resource" }
247
246
 
248
247
  # initiate server push stream
249
- stream.promise(head) do |push|
250
- push.headers({ ... })
251
- push.data(...)
248
+ push_stream = nil
249
+ stream.promise(promise_header) do |push|
250
+ push.headers({...})
251
+ push_stream = push
252
252
  end
253
253
 
254
254
  # send response
@@ -259,8 +259,10 @@ conn.on(:stream) do |stream|
259
259
 
260
260
  # split response between multiple DATA frames
261
261
  stream.data(response_chunk, end_stream: false)
262
- promise.data(payload)
263
262
  stream.data(last_chunk)
263
+
264
+ # now send the previously promised data
265
+ push_stream.data(push_data)
264
266
  end
265
267
  end
266
268
  ```
@@ -279,6 +281,13 @@ The client can cancel any given push stream (via `.close`), or disable server pu
279
281
  ```ruby
280
282
  client.settings(streams: 0) # setting max limit to 0 disables server push
281
283
  ```
284
+ ### Specs
285
+
286
+ To run specs:
287
+
288
+ ```ruby
289
+ rake
290
+ ```
282
291
 
283
292
  ### License
284
293
 
data/Rakefile CHANGED
@@ -2,10 +2,48 @@ require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
3
  require 'rubocop/rake_task'
4
4
  require 'yard'
5
+ require 'open3'
5
6
  require_relative 'lib/tasks/generate_huffman_table'
6
7
 
7
- RSpec::Core::RakeTask.new
8
+ RSpec::Core::RakeTask.new(:spec) do |t|
9
+ t.exclude_pattern = './spec/hpack_test_spec.rb'
10
+ end
11
+
12
+ RSpec::Core::RakeTask.new(:hpack) do |t|
13
+ t.pattern = './spec/hpack_test_spec.rb'
14
+ end
15
+
16
+ task :h2spec do
17
+ if /darwin/ !~ RUBY_PLATFORM
18
+ abort "h2spec rake task currently only works on OSX.
19
+ Download other binaries from https://github.com/summerwind/h2spec/releases"
20
+ end
21
+
22
+ system 'ruby example/server.rb -p 9000 &', out: File::NULL
23
+ sleep 1
24
+
25
+ output = ''
26
+ Open3.popen2e('spec/h2spec/h2spec.darwin -p 9000 -o 1') do |_i, oe, _t|
27
+ oe.each do |l|
28
+ l.gsub!(/\e\[(\d+)(;\d+)*m/, '')
29
+
30
+ output << l
31
+ if l =~ /passed.*failed/
32
+ puts "\n#{l}"
33
+ break # suppress post-summary failure output
34
+ else
35
+ print '.'
36
+ end
37
+ end
38
+ end
39
+
40
+ File.write 'spec/h2spec/output/non_secure.txt', output
41
+
42
+ system 'kill `pgrep -f example/server.rb`'
43
+ end
44
+
8
45
  RuboCop::RakeTask.new
9
46
  YARD::Rake::YardocTask.new
10
47
 
11
48
  task default: [:spec, :rubocop]
49
+ task all: [:default, :hpack]
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'http_parser.rb'
@@ -8,6 +8,10 @@ $> ruby server.rb
8
8
  $> ruby client.rb http://localhost:8080/ # GET
9
9
  $> ruby client.rb http://localhost:8080/ -d 'some data' # POST
10
10
 
11
+ # Server push
12
+ $> ruby server.rb --push
13
+ $> ruby client.rb http://localhost:8080/ # GET
14
+
11
15
  # TLS + NPN negotiation
12
16
  $> ruby server.rb --secure
13
17
  $> ruby client.rb https://localhost:8080/ # GET
@@ -17,9 +17,11 @@ if uri.scheme == 'https'
17
17
  ctx = OpenSSL::SSL::SSLContext.new
18
18
  ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
19
19
 
20
- ctx.npn_protocols = [DRAFT]
21
- ctx.npn_select_cb = lambda do |protocols|
22
- puts "NPN protocols supported by server: #{protocols}"
20
+ # For ALPN support, Ruby >= 2.3 and OpenSSL >= 1.0.2 are required
21
+
22
+ ctx.alpn_protocols = [DRAFT]
23
+ ctx.alpn_select_cb = lambda do |protocols|
24
+ puts "ALPN protocols supported by server: #{protocols}"
23
25
  DRAFT if protocols.include? DRAFT
24
26
  end
25
27
 
@@ -28,8 +30,8 @@ if uri.scheme == 'https'
28
30
  sock.hostname = uri.hostname
29
31
  sock.connect
30
32
 
31
- if sock.npn_protocol != DRAFT
32
- puts "Failed to negotiate #{DRAFT} via NPN"
33
+ if sock.alpn_protocol != DRAFT
34
+ puts "Failed to negotiate #{DRAFT} via ALPN"
33
35
  exit
34
36
  end
35
37
  else
@@ -37,6 +39,9 @@ else
37
39
  end
38
40
 
39
41
  conn = HTTP2::Client.new
42
+ stream = conn.new_stream
43
+ log = Logger.new(stream.id)
44
+
40
45
  conn.on(:frame) do |bytes|
41
46
  # puts "Sending bytes: #{bytes.unpack("H*").first}"
42
47
  sock.print bytes
@@ -49,9 +54,6 @@ conn.on(:frame_received) do |frame|
49
54
  puts "Received frame: #{frame.inspect}"
50
55
  end
51
56
 
52
- stream = conn.new_stream
53
- log = Logger.new(stream.id)
54
-
55
57
  conn.on(:promise) do |promise|
56
58
  promise.on(:headers) do |h|
57
59
  log.info "promise headers: #{h}"
@@ -68,7 +70,6 @@ end
68
70
 
69
71
  stream.on(:close) do
70
72
  log.info 'stream closed'
71
- sock.close
72
73
  end
73
74
 
74
75
  stream.on(:half_close) do
@@ -6,7 +6,7 @@ require 'openssl'
6
6
  require 'http/2'
7
7
  require 'uri'
8
8
 
9
- DRAFT = 'h2'
9
+ DRAFT = 'h2'.freeze
10
10
 
11
11
  class Logger
12
12
  def initialize(id)
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDLjCCAhYCCQDIZ/9hq/2pXjANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJB
3
+ VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0
4
+ cyBQdHkgTHRkMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTYwNjA2MTk0MzI1WhcN
5
+ MTcwNjA2MTk0MzI1WjBZMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0
6
+ ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDEwls
7
+ b2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCjFXrWqtRZ
8
+ EMOO/o6AxGbgDYMgg/7uxCFQJM5Z6C4II6D8V94FDyCd+J0LOK2hB+QUdFqpA1S9
9
+ 6RW2MvIwdvRt03RJMgbfcUF0+w4ZItv2xrW9waCfCmLSRDZgcSATacEF6u9p2Vs+
10
+ o4J/cHacirSwjy4+m94CgkxtUFGtGcJaFqAZ6Cdj5WvQdJSiAI3x3gNC/UGA+5dL
11
+ sp8+vwWx+/TMc6nDBmoRW3GHeG/NApQSh01w3wDv0FmUaFQlA5WPya/Js+CyuYh1
12
+ miXbQJEjDnGGaJjnoyRAQpPrk72Jj+bnfOu9kxpzkuLJOsbaofRFkM+/Ar5U+bQz
13
+ uU0ErQ8Ih8MPAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBACL8HkKjW8kWLlW4TE5K
14
+ EcfsBad2Ah5ugTocJ/pLnr/YEo8uD91gECDtsuFTXul9n2M7U5jJmzbHZ63cjyC3
15
+ lb1BxJxUL7aIyaL61IMMcIJMWhC9VGnFUshMDNVBhuRkKs/QvaMD5KefKN1E9I2M
16
+ mZ72Yww0VihYwNOu3MTn8gUuy9eU6k/gTYPY7PJVh18QmR+Fs2MaaPp+bDwxiqML
17
+ 0o2I6+0ZsqM3vFtcUjxjRASV5s+JkM34pTWFwUOl7TZv1YsxCKSz4f0BXDImZEvU
18
+ rwqFdlELp5WOG9LJsrszDRbf1wbFUsG1XXZpIBiWo3d6pOiIyRKrak1vKViNfYvI
19
+ W30=
20
+ -----END CERTIFICATE-----