h2 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e62e384940a1e408102e4e518942c1245ce374f82007c858d9de5a0b286c2301
4
- data.tar.gz: d3fc7f3d111b3786cb50c58f862b32dad713557ae69cf18233cd1eda7ca0d5be
3
+ metadata.gz: 9a9868c3d9496207683352704cd152a9d5426ff42cd3aa30035a56981596e957
4
+ data.tar.gz: 43e60980d431d769835d4bb15de0cacbb5676c250b1e461c31e4f88c89734c48
5
5
  SHA512:
6
- metadata.gz: 907a28fb440862cbc3a6a9dbb80db39408f3635f4aa4983358bba508617ddbb8fcb9da0a30b3601a614f4ea7a79ff4cceece1b7d1c687b6afc3e663ad5d4459d
7
- data.tar.gz: 317f75c090f2f54526a2bff4b2e8b7d298ab7f6bf8f4653e9bd5ac2916f333133e26a7b47d357c447a7a0a6741468b99733e1212c71ee018f4698c51b0ea5eaf
6
+ metadata.gz: 19e4e75141869144f1ed7b6abf8b6faeb61d00db6466d02ec5264ec7d95ddada0de2914b071dc13a5293885189fea5cb9b235515fc8e282218244d19b5eea08a
7
+ data.tar.gz: 50a36bbc351d0dca3cc81750800e2a5085e403bc6019a8620cef8ec5d8977c4e227dcd994656365eb9d75ae03d4fdb0dd9d2e740f2eeccbdf636210f8952dd50
data/CHANGELOG.md CHANGED
@@ -1,6 +1,11 @@
1
1
  h2 changelog
2
2
  ============
3
3
 
4
+ ### 0.6.1 27 jul 2018
5
+
6
+ * fix race between reading and sending first frame
7
+ * make `port:` default to 443 for `H2::Client.new`
8
+
4
9
  ### 0.6.0 25 jul 2018
5
10
 
6
11
  * update server API - kwargs
data/Gemfile CHANGED
@@ -2,6 +2,8 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
+ gem 'http-2', path: '../http-2'
6
+
5
7
  group :concurrent_ruby do
6
8
  gem 'concurrent-ruby'
7
9
  end
data/exe/h2 CHANGED
@@ -9,7 +9,6 @@ require 'colored'
9
9
  require 'optparse'
10
10
 
11
11
  begin # {{{
12
- raise LoadError if ARGV.include?('--dev')
13
12
  require 'h2'
14
13
  rescue LoadError
15
14
  $: << File.expand_path('../../lib', __FILE__)
@@ -59,10 +58,6 @@ OptionParser.new do |o|
59
58
  options[:debug] = true
60
59
  end
61
60
 
62
- o.on '--dev', 'load lib from source tree' do
63
- # handled above for reasons
64
- end
65
-
66
61
  o.on '-g', '--goaway', 'send GOAWAY frame when stream is complete' do
67
62
  options[:goaway] = true
68
63
  end
@@ -142,8 +137,8 @@ end
142
137
 
143
138
  puts s.body
144
139
 
145
- c.goaway if options[:goaway]
146
140
  c.block! if options[:block]
141
+ c.goaway if options[:goaway]
147
142
  c.close
148
143
 
149
144
  # }}}
data/lib/h2.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'http/2'
4
+ require 'logger'
4
5
  require 'uri'
5
6
  require 'h2/version'
6
7
 
@@ -28,8 +29,21 @@ module H2
28
29
  :put
29
30
  ]
30
31
 
32
+ Logger = ::Logger.new STDOUT
33
+
31
34
  class << self
32
35
 
36
+ # turn on extra verbose debug logging
37
+ #
38
+ def verbose!
39
+ @verbose = true
40
+ end
41
+
42
+ def verbose?
43
+ @verbose = false unless defined?(@verbose)
44
+ @verbose
45
+ end
46
+
33
47
  # convenience wrappers to make requests with HTTP methods
34
48
  #
35
49
  # @see H2.request
@@ -120,6 +134,33 @@ module H2
120
134
 
121
135
  end
122
136
 
137
+ module FrameDebugger
138
+
139
+ def self.included base
140
+ H2.verbose!
141
+ base::PARSER_EVENTS.push :frame_sent, :frame_received
142
+ end
143
+
144
+ def on_frame_sent f
145
+ Logger.debug "Sent frame: #{truncate_frame(f).inspect}"
146
+ end
147
+
148
+ def on_frame_received f
149
+ Logger.debug "Received frame: #{truncate_frame(f).inspect}"
150
+ end
151
+
152
+ private
153
+
154
+ def truncate_string s
155
+ (String === s && s.length > 64) ? "#{s[0,64]}..." : s
156
+ end
157
+
158
+ def truncate_frame f
159
+ f.reduce({}) { |h, (k, v)| h[k] = truncate_string(v); h }
160
+ end
161
+
162
+ end
163
+
123
164
  end
124
165
 
125
166
  require 'h2/client'
data/lib/h2/client.rb CHANGED
@@ -7,16 +7,18 @@ module H2
7
7
  include Blockable
8
8
  include On
9
9
 
10
- CONNECTION_EVENTS = [
10
+ PARSER_EVENTS = [
11
11
  :close,
12
12
  :frame,
13
13
  :goaway,
14
14
  :promise
15
15
  ]
16
16
 
17
- ALPN_PROTOCOLS = ['h2']
18
- DEFAULT_MAXLEN = 4096
19
- RE_IP_ADDR = Regexp.union Resolv::IPv4::Regex, Resolv::IPv6::Regex
17
+ # include FrameDebugger
18
+
19
+ ALPN_PROTOCOLS = ['h2']
20
+ DEFAULT_MAXLEN = 4096
21
+ RE_IP_ADDR = Regexp.union Resolv::IPv4::Regex, Resolv::IPv6::Regex
20
22
 
21
23
  attr_accessor :last_stream
22
24
  attr_reader :client, :reader, :scheme, :socket, :streams
@@ -24,14 +26,14 @@ module H2
24
26
  # create a new h2 client
25
27
  #
26
28
  # @param [String] host IP address or hostname
27
- # @param [Integer] port TCP port
29
+ # @param [Integer] port TCP port (default: 443)
28
30
  # @param [String,URI] url full URL to parse (optional: existing +URI+ instance)
29
31
  # @param [Hash,FalseClass] tls TLS options (optional: +false+ do not use TLS)
30
32
  # @option tls [String] :cafile path to CA file
31
33
  #
32
34
  # @return [H2::Client]
33
35
  #
34
- def initialize host: nil, port: nil, url: nil, tls: {}
36
+ def initialize host: nil, port: 443, url: nil, tls: {}
35
37
  raise ArgumentError if url.nil? && (host.nil? || port.nil?)
36
38
 
37
39
  if url
@@ -52,11 +54,12 @@ module H2
52
54
  @socket = tls_socket @socket if @tls
53
55
  @client = HTTP2::Client.new
54
56
 
57
+ @first = true
58
+ @reading = false
59
+
55
60
  init_blocking
56
61
  yield self if block_given?
57
62
  bind_events
58
-
59
- read
60
63
  end
61
64
 
62
65
  # @return true if the connection is closed
@@ -76,6 +79,14 @@ module H2
76
79
  @socket.eof?
77
80
  end
78
81
 
82
+ def reading?
83
+ @mutex.synchronize { @reading }
84
+ end
85
+
86
+ def reading!
87
+ @mutex.synchronize { @reading = true }
88
+ end
89
+
79
90
  # send a goaway frame and wait until the connection is closed
80
91
  #
81
92
  def goaway!
@@ -98,7 +109,7 @@ module H2
98
109
  # binds all connection events to their respective on_ handlers
99
110
  #
100
111
  def bind_events
101
- CONNECTION_EVENTS.each do |e|
112
+ PARSER_EVENTS.each do |e|
102
113
  @client.on(e){|*a| __send__ "on_#{e}", *a}
103
114
  end
104
115
  end
@@ -194,6 +205,8 @@ module H2
194
205
  # creates a new +Thread+ to read the given number of bytes each loop from
195
206
  # the current +@socket+
196
207
  #
208
+ # NOTE: initial client frames (settings, etc) should be sent first!
209
+ #
197
210
  # NOTE: this is the override point for celluloid actor pool or concurrent
198
211
  # ruby threadpool support
199
212
  #
@@ -202,6 +215,7 @@ module H2
202
215
  def read maxlen = DEFAULT_MAXLEN
203
216
  main = Thread.current
204
217
  @reader = Thread.new do
218
+ reading!
205
219
  begin
206
220
  _read maxlen
207
221
  rescue => e
@@ -230,7 +244,7 @@ module H2
230
244
  begin
231
245
  @client << data
232
246
  rescue HTTP2::Error::ProtocolError => pe
233
- STDERR.puts 'mystery protocol error!'
247
+ STDERR.puts "protocol error: #{pe.message}"
234
248
  STDERR.puts pe.backtrace.map {|l| "\t" + l}
235
249
  end
236
250
  end
@@ -286,6 +300,9 @@ module H2
286
300
  @socket.write bytes
287
301
  end
288
302
  @socket.flush
303
+
304
+ @first = false if @first
305
+ read unless @first or @reading
289
306
  end
290
307
 
291
308
  # fake exceptionless IO for writing on older ruby versions
@@ -9,6 +9,7 @@ module H2
9
9
  include ::Celluloid
10
10
 
11
11
  def read client, maxlen = DEFAULT_MAXLEN
12
+ client.reading!
12
13
  client._read maxlen
13
14
  end
14
15
  end
@@ -18,6 +18,7 @@ module H2
18
18
  def read maxlen = DEFAULT_MAXLEN
19
19
  main = Thread.current
20
20
  @reader = self.class.thread_pool.post do
21
+ reading!
21
22
  begin
22
23
  _read maxlen
23
24
  rescue => e
data/lib/h2/server.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'celluloid/current'
2
- require 'logger'
3
2
  require 'reel'
4
3
  require 'h2/reel/ext'
5
4
  require 'h2'
@@ -8,8 +7,6 @@ module H2
8
7
 
9
8
  CONTENT_LENGTH_KEY = 'content-length'
10
9
 
11
- Logger = ::Logger.new STDOUT
12
-
13
10
  class << self
14
11
 
15
12
  def alpn?
@@ -21,17 +18,6 @@ module H2
21
18
  @jruby = RUBY_ENGINE == 'jruby'
22
19
  end
23
20
 
24
- # turn on extra verbose debug logging
25
- #
26
- def verbose!
27
- @verbose = true
28
- end
29
-
30
- def verbose?
31
- @verbose = false unless defined?(@verbose)
32
- @verbose
33
- end
34
-
35
21
  end
36
22
 
37
23
  # base H2 server, a direct subclass of +Reel::Server+
@@ -13,12 +13,12 @@ module H2
13
13
  #
14
14
  PARSER_EVENTS = [
15
15
  :frame,
16
- :frame_sent,
17
- :frame_received,
18
16
  :stream,
19
17
  :goaway
20
18
  ]
21
19
 
20
+ # include FrameDebugger
21
+
22
22
  attr_reader :parser, :server, :socket
23
23
 
24
24
  def initialize socket:, server:
@@ -94,7 +94,7 @@ module H2
94
94
 
95
95
  rescue => e
96
96
  Logger.error "Exception: #{e.message} - closing socket"
97
- STDERR.puts e.backtrace
97
+ STDERR.puts e.backtrace if H2.verbose?
98
98
  close
99
99
 
100
100
  end
@@ -107,24 +107,12 @@ module H2
107
107
  # called by +@parser+ with a binary frame to write to the +@socket+
108
108
  #
109
109
  def on_frame bytes
110
- Logger.debug "Writing bytes: #{truncate_string(bytes.unpack("H*").first)}" if H2.verbose?
111
-
112
- # N.B. this is the important bit
113
- #
114
110
  @socket.write bytes
115
111
  rescue IOError, Errno::EPIPE => e
116
112
  Logger.error e.message
117
113
  close
118
114
  end
119
115
 
120
- def on_frame_sent f
121
- Logger.debug "Sent frame: #{truncate_frame(f).inspect}" if H2.verbose?
122
- end
123
-
124
- def on_frame_received f
125
- Logger.debug "Received frame: #{truncate_frame(f).inspect}" if H2.verbose?
126
- end
127
-
128
116
  # the +@parser+ calls this when a new stream has been initiated by the
129
117
  # client
130
118
  #
@@ -138,16 +126,6 @@ module H2
138
126
  close
139
127
  end
140
128
 
141
- private
142
-
143
- def truncate_string s
144
- (String === s && s.length > 64) ? "#{s[0,64]}..." : s
145
- end
146
-
147
- def truncate_frame f
148
- f.reduce({}) { |h, (k, v)| h[k] = truncate_string(v); h }
149
- end
150
-
151
129
  end
152
130
  end
153
131
  end
data/lib/h2/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module H2
2
- VERSION = '0.6.0'
2
+ VERSION = '0.6.1'
3
3
 
4
4
  class << self
5
5
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: h2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenichi Nakamura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-07-25 00:00:00.000000000 Z
11
+ date: 2018-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http-2