net-http2 0.7.0 → 0.7.1

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: 10dc650d476227c1a393c90163743402909063f2
4
- data.tar.gz: bcbc57dee7a35640a11bc4fd0a237a65a9aa02c3
3
+ metadata.gz: f2b511abf99b004afe56dbae182ac4cb4e0436d6
4
+ data.tar.gz: 3ef6020ae7d52ee3d79f08aef4fbd16ea46351de
5
5
  SHA512:
6
- metadata.gz: 95fca293c965b9f40d39e08664dbdfbb5dcb80b003b790c12d955c3913e7909c8f239c407c2368dff05dc08840819cd414c352e0f19f2de554042d474dabd21b
7
- data.tar.gz: a66cc7f54b6ae4400753cfbaf5c5af299bc996fdb0e11680900cc2a1046657b87c31b8f8dd1eadd2be5ba1fbdd6aa26b04bcce52866b0b656b8c258158c18094
6
+ metadata.gz: a1b52e03696044abe9b62d4f74ec6bdaf8cdc801c89dd278fcdcf33e2d84efdc17ea7174416c74e68295c2b014406dc54854c4fc795f95b04ff477d63bc136d4
7
+ data.tar.gz: 49820fe72d72647981e5d08434c6054783b7f69cf0bf8c8b1154ad84f87ba60adf8e6ff52bdb47b43e9b485a1011b240cf7b6a3c7419aa02fbf353c537feb96e
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # NetHttp2
4
4
 
5
- NetHttp2 is an HTTP2 client for Ruby.
5
+ NetHttp2 is an HTTP/2 client for Ruby.
6
6
 
7
7
 
8
8
  ## Installation
@@ -25,7 +25,7 @@ With a blocking call:
25
25
  require 'net-http2'
26
26
 
27
27
  # create a client
28
- client = NetHttp2::Client.new(uri: "http://106.186.112.116")
28
+ client = NetHttp2::Client.new("http://106.186.112.116")
29
29
 
30
30
  # send request
31
31
  response = client.get('/')
@@ -40,21 +40,21 @@ response.body # => "A body"
40
40
  client.close
41
41
  ```
42
42
 
43
- With a a non-blocking call:
43
+ With a non-blocking call:
44
44
  ```ruby
45
45
  require 'net-http2'
46
46
 
47
47
  # create a client
48
- client = NetHttp2::Client.new(uri: "http://106.186.112.116")
48
+ client = NetHttp2::Client.new("http://106.186.112.116")
49
49
 
50
50
  # send request
51
51
  client.async_get('/') do |response|
52
52
 
53
53
  # read the response
54
- p response.ok? # => true
55
- p response.status # => '200'
56
- p response.headers # => {":status"=>"200"}
57
- p response.body # => "A body"
54
+ response.ok? # => true
55
+ response.status # => '200'
56
+ response.headers # => {":status"=>"200"}
57
+ response.body # => "A body"
58
58
 
59
59
  # close the connection
60
60
  client.close
@@ -71,14 +71,15 @@ sleep 5
71
71
  To create a new client:
72
72
 
73
73
  ```ruby
74
- NetHttp2::Client.new(uri)
74
+ NetHttp2::Client.new(url)
75
75
  ```
76
76
 
77
77
  #### Methods
78
78
 
79
- * **new(uri, options={})** → **`NetHttp2::Client`**
80
- Returns w new client. `uri` is a `string` such as https://localhost:443.
81
- The only current option is `:ssl_context`, in case the uri has an https scheme and you want your SSL client to use a custom context.
79
+ * **new(url, options={})** → **`NetHttp2::Client`**
80
+
81
+ Returns a new client. `url` is a `string` such as https://localhost:443.
82
+ The only current option is `:ssl_context`, in case the url has an https scheme and you want your SSL client to use a custom context.
82
83
 
83
84
  For instance:
84
85
 
@@ -88,14 +89,19 @@ NetHttp2::Client.new(uri)
88
89
  ctx.key = OpenSSL::PKey::RSA.new(certificate, "cert_password")
89
90
  ctx.cert = OpenSSL::X509::Certificate.new(certificate)
90
91
 
91
- NetHttp2::Client.new(uri, ssl_context: ctx)
92
+ NetHttp2::Client.new(url, ssl_context: ctx)
92
93
  ```
93
94
 
94
95
  * **uri** → **`URI`**
95
- Returns the URI of the APNS endpoint.
96
+
97
+ Returns the URI of the endpoint.
98
+
99
+ ##### Blocking calls
100
+ These behave similarly to HTTP/1 calls.
96
101
 
97
102
  * **get(path, headers={}, options={})** → **`NetHttp2::Response` or `nil`**
98
- Sends a GET request. This is a blocking call. Options can only specify a `:timeout` (defaults to 60).
103
+
104
+ Sends a GET request. Options can only specify a `:timeout` (defaults to 60).
99
105
  Returns `nil` in case a timeout occurs.
100
106
 
101
107
  For example:
@@ -107,19 +113,26 @@ NetHttp2::Client.new(uri)
107
113
  ```
108
114
 
109
115
  * **post(path, body, headers={}, options={})** → **`NetHttp2::Response` or `nil`**
110
- Sends a POST request. This is a blocking call. Options can only specify a `:timeout` (defaults to 60).
116
+
117
+ Sends a POST request. Options can only specify a `:timeout` (defaults to 60).
111
118
  Returns `nil` in case a timeout occurs.
112
119
 
113
120
  * **put(path, body, headers={}, options={})** → **`NetHttp2::Response` or `nil`**
114
- Sends a PUT request. This is a blocking call. Options can only specify a `:timeout` (defaults to 60).
121
+
122
+ Sends a PUT request. Options can only specify a `:timeout` (defaults to 60).
115
123
  Returns `nil` in case a timeout occurs.
116
124
 
117
125
  * **delete(path, headers={}, options={})** → **`NetHttp2::Response` or `nil`**
118
- Sends a DELETE request. This is a blocking call. Options can only specify a `:timeout` (defaults to 60).
126
+
127
+ Sends a DELETE request. Options can only specify a `:timeout` (defaults to 60).
119
128
  Returns `nil` in case a timeout occurs.
120
129
 
121
- * **async_get(path, headers={}, options={})** → **`NetHttp2::Response` or `nil`**
122
- Sends a GET request. This is a non-blocking call. Options can only specify a `:timeout` (defaults to 60).
130
+ ##### Non-blocking calls
131
+ > The API of these calls is still subject to change, as on of HTTP/2 benefits is to allow for the streaming of responses' bodies.
132
+
133
+ * **async_get(path, headers={}, options={})** → block called with **`NetHttp2::Response` or `nil`**
134
+
135
+ Sends a GET request. Options can only specify a `:timeout` (defaults to 60).
123
136
  Returns `nil` in case a timeout occurs.
124
137
 
125
138
  For example:
@@ -130,16 +143,19 @@ NetHttp2::Client.new(uri)
130
143
  client.get('/path3', {}, timeout: 1) { |response_3| p response_3 }
131
144
  ```
132
145
 
133
- * **async_post(path, body, headers={}, options={})** → **`NetHttp2::Response` or `nil`**
134
- Sends a POST request. This is a non-blocking call. Options can only specify a `:timeout` (defaults to 60).
146
+ * **async_post(path, body, headers={}, options={})** → block called with **`NetHttp2::Response` or `nil`**
147
+
148
+ Sends a POST request. Options can only specify a `:timeout` (defaults to 60).
135
149
  Returns `nil` in case a timeout occurs.
136
150
 
137
- * **async_put(path,body, headers={}, options={})** → **`NetHttp2::Response` or `nil`**
138
- Sends a PUT request. This is a non-blocking call. Options can only specify a `:timeout` (defaults to 60).
151
+ * **async_put(path,body, headers={}, options={})** → block called with **`NetHttp2::Response` or `nil`**
152
+
153
+ Sends a PUT request. Options can only specify a `:timeout` (defaults to 60).
139
154
  Returns `nil` in case a timeout occurs.
140
155
 
141
- * **async_delete(path, headers={}, options={})** → **`NetHttp2::Response` or `nil`**
142
- Sends a DELETE request. This is a non-blocking call. Options can only specify a `:timeout` (defaults to 60).
156
+ * **async_delete(path, headers={}, options={})** → block called with **`NetHttp2::Response` or `nil`**
157
+
158
+ Sends a DELETE request. Options can only specify a `:timeout` (defaults to 60).
143
159
  Returns `nil` in case a timeout occurs.
144
160
 
145
161
 
@@ -148,15 +164,19 @@ NetHttp2::Client.new(uri)
148
164
  #### Methods
149
165
 
150
166
  * **ok?** → **`boolean`**
167
+
151
168
  Returns if the request was successful.
152
169
 
153
170
  * **headers** → **`hash`**
171
+
154
172
  Returns a Hash containing the Headers of the response.
155
173
 
156
174
  * **status** → **`string`**
175
+
157
176
  Returns the status code.
158
177
 
159
178
  * **body** → **`string`**
179
+
160
180
  Returns the RAW body of the response.
161
181
 
162
182
 
@@ -5,12 +5,14 @@ require 'http/2'
5
5
 
6
6
  module NetHttp2
7
7
 
8
+ DRAFT = 'h2'
9
+
8
10
  class Client
9
11
  attr_reader :uri
10
12
 
11
- def initialize(uri, options={})
12
- @uri = URI.parse(uri)
13
- @ssl_context = options[:ssl_context] || OpenSSL::SSL::SSLContext.new
13
+ def initialize(url, options={})
14
+ @uri = URI.parse(url)
15
+ @ssl_context = add_npn_to_context(options[:ssl_context] || OpenSSL::SSL::SSLContext.new)
14
16
 
15
17
  @is_ssl = (@uri.scheme == 'https')
16
18
 
@@ -105,28 +107,24 @@ module NetHttp2
105
107
  end
106
108
 
107
109
  def thread_loop(socket)
110
+
111
+ send_before_receiving(socket)
112
+
108
113
  loop do
109
- if ssl?
110
- available = socket.pending
111
- if available > 0
112
- data_received = socket.sysread(available)
113
- h2 << data_received
114
- break if socket.closed?
115
- end
116
- end
114
+
115
+ next if read_if_pending(socket)
117
116
 
118
117
  ready = IO.select([socket, @pipe_r])
119
118
 
119
+ if ready[0].include?(socket)
120
+ data_received = socket.readpartial(1024)
121
+ h2 << data_received
122
+ end
123
+
120
124
  if ready[0].include?(@pipe_r)
121
125
  data_to_send = @pipe_r.read_nonblock(1024)
122
126
  socket.write(data_to_send)
123
127
  end
124
-
125
- if ready[0].include?(socket)
126
- data_received = socket.read_nonblock(1024)
127
- h2 << data_received
128
- break if socket.closed?
129
- end
130
128
  end
131
129
  end
132
130
 
@@ -139,6 +137,7 @@ module NetHttp2
139
137
  socket.hostname = @uri.hostname
140
138
 
141
139
  socket.connect
140
+ raise "Failed to negotiate #{DRAFT} via NPN" if socket.npn_protocol != DRAFT
142
141
 
143
142
  socket
144
143
  else
@@ -146,6 +145,27 @@ module NetHttp2
146
145
  end
147
146
  end
148
147
 
148
+ def send_before_receiving(socket)
149
+ data_to_send = @pipe_r.read_nonblock(1024)
150
+ socket.write(data_to_send)
151
+ rescue IO::WaitReadable
152
+ IO.select([@pipe_r])
153
+ retry
154
+ end
155
+
156
+ def read_if_pending(socket)
157
+ if ssl?
158
+ available = socket.pending
159
+
160
+ if available > 0
161
+ data_received = socket.sysread(available)
162
+ h2 << data_received
163
+
164
+ true
165
+ end
166
+ end
167
+ end
168
+
149
169
  def h2
150
170
  @h2 ||= HTTP2::Client.new.tap do |h2|
151
171
  h2.on(:frame) do |bytes|
@@ -157,6 +177,14 @@ module NetHttp2
157
177
  end
158
178
  end
159
179
 
180
+ def add_npn_to_context(ctx)
181
+ ctx.npn_protocols = [DRAFT]
182
+ ctx.npn_select_cb = lambda do |protocols|
183
+ DRAFT if protocols.include?(DRAFT)
184
+ end
185
+ ctx
186
+ end
187
+
160
188
  def exit_thread(thread)
161
189
  return unless thread && thread.alive?
162
190
  thread.exit
@@ -1,3 +1,3 @@
1
1
  module NetHttp2
2
- VERSION = "0.7.0"
2
+ VERSION = "0.7.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-http2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roberto Ostinelli
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-28 00:00:00.000000000 Z
11
+ date: 2016-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http-2