http-protocol 0.14.0 → 0.15.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c88f948d7e13dd7114fc7f83b002035a6fa5229b15756fcad9edc92e9ac14ad9
4
- data.tar.gz: ef513cdd8c0ad42a5ac9cc7e24f37ce2540abe8e4e041ca04322d61de656192c
3
+ metadata.gz: 1baf62bdb22b5778de7e8fceaf33f97a9ab003b27da9057b81408b1abe871503
4
+ data.tar.gz: 85219e156d6ed52c0120d15579782767796fe1cdd5bb6917f4bdd354702fc27d
5
5
  SHA512:
6
- metadata.gz: '0694ce003550f943c96bcbe8a8b9dc5e1bc387f496bf7feb07bc5e7614f43f2bdd3745c6709327e3b073d466cdb33f1fa8cb73259c994c02d986d5afe9663ef3'
7
- data.tar.gz: d21bb4ab8fdbeacecc4772d5108f7e5ae79878b7ea6b5fc51b15a89eff6f766e6910e7fc72472d2f3b1213f29fb6556f665045a1cfb5510248c6d6cf8eb23e3e
6
+ metadata.gz: 9ebfd44308c12dfaf2dbefd44b29b01810cae5ba781b5549b2130eca635a9c894ca47442a5edc70dc9b51ae5bd8e23c5500577337676dbc6488508fee170405c
7
+ data.tar.gz: c7b015854f7c07c2040214c11f530810c91846021276a8e989029493c7cb84b59626290c81d8e06877197d04621c7ad64a8dcb94844758dd722641d29604fd6d
@@ -43,6 +43,23 @@ module HTTP
43
43
  raise ProtocolError, "Cannot send connection preface in state #{@state}"
44
44
  end
45
45
  end
46
+
47
+ def receive_push_promise(frame)
48
+ if frame.stream_id == 0
49
+ raise ProtocolError, "Cannot receive headers for stream 0!"
50
+ end
51
+
52
+ if stream = @streams[frame.stream_id]
53
+ # This is almost certainly invalid:
54
+ promised_stream, request_headers = stream.receive_push_promise(frame)
55
+
56
+ if stream.closed?
57
+ @streams.delete(stream.id)
58
+ end
59
+
60
+ return promised_stream, request_headers
61
+ end
62
+ end
46
63
  end
47
64
  end
48
65
  end
@@ -41,6 +41,14 @@ module HTTP
41
41
  raise ProtocolError, "Cannot send connection preface in state #{@state}"
42
42
  end
43
43
  end
44
+
45
+ def enable_push?
46
+ @remote_settings.enable_push?
47
+ end
48
+
49
+ def receive_push_promise
50
+ raise ProtocolError, "Server cannot receive push promises."
51
+ end
44
52
  end
45
53
  end
46
54
  end
@@ -115,7 +115,7 @@ module HTTP
115
115
  end
116
116
 
117
117
  def send_headers?
118
- @state == :idle or @state == :reseved_local or @state == :open or @state == :half_closed_remote
118
+ @state == :idle or @state == :reserved_local or @state == :open or @state == :half_closed_remote
119
119
  end
120
120
 
121
121
  def send_failure(status, reason)
@@ -127,6 +127,8 @@ module HTTP
127
127
  else
128
128
  send_reset_stream(PROTOCOL_ERROR)
129
129
  end
130
+
131
+ return nil
130
132
  end
131
133
 
132
134
  private def write_headers(priority, headers, flags = 0)
@@ -150,7 +152,7 @@ module HTTP
150
152
  else
151
153
  @state = :open
152
154
  end
153
- elsif @state == :reseved_local
155
+ elsif @state == :reserved_local
154
156
  frame = write_headers(*args)
155
157
 
156
158
  @state = :half_closed_remote
@@ -246,7 +248,7 @@ module HTTP
246
248
  end
247
249
 
248
250
  @headers = process_headers(frame)
249
- elsif @state == :reseved_remote
251
+ elsif @state == :reserved_remote
250
252
  @state = :half_closed_local
251
253
 
252
254
  @headers = process_headers(frame)
@@ -307,6 +309,65 @@ module HTTP
307
309
  raise ProtocolError, "Cannot reset stream in state: #{@state}"
308
310
  end
309
311
  end
312
+
313
+ # A normal request is client request -> server response -> client.
314
+ # A push promise is server request -> client -> server response -> client.
315
+ # The server generates the same set of headers as if the client was sending a request, and sends these to the client. The client can reject the request by resetting the (new) stream. Otherwise, the server will start sending a response as if the client had send the request.
316
+ private def write_push_promise(stream_id, headers, flags = 0, **options)
317
+ data = @connection.encode_headers(headers)
318
+
319
+ frame = PushPromiseFrame.new(@id, flags)
320
+ frame.pack(stream_id, data, maximum_size: @connection.maximum_frame_size)
321
+
322
+ write_frame(frame)
323
+
324
+ return frame
325
+ end
326
+
327
+ def reserved_local!
328
+ if @state == :idle
329
+ @state = :reserved_local
330
+ else
331
+ raise ProtocolError, "Cannot reserve stream in state: #{@state}"
332
+ end
333
+ end
334
+
335
+ def reserved_remote!
336
+ if @state == :idle
337
+ @state = :reserved_remote
338
+ else
339
+ raise ProtocolError, "Cannot reserve stream in state: #{@state}"
340
+ end
341
+ end
342
+
343
+ def create_promise_stream(headers, stream_id)
344
+ @connection.create_stream(stream_id)
345
+ end
346
+
347
+ # Server push is semantically equivalent to a server responding to a request; however, in this case, that request is also sent by the server, as a PUSH_PROMISE frame.
348
+ # @param headers [Hash] contains a complete set of request header fields that the server attributes to the request.
349
+ def send_push_promise(headers, stream_id = @connection.next_stream_id)
350
+ if @state == :open or @state == :half_closed_remote
351
+ promised_stream = self.create_promise_stream(headers, stream_id)
352
+ promised_stream.reserved_local!
353
+
354
+ write_push_promise(promised_stream.id, headers)
355
+
356
+ return promised_stream
357
+ else
358
+ raise ProtocolError, "Cannot send push promise in state: #{@state}"
359
+ end
360
+ end
361
+
362
+ def receive_push_promise(frame)
363
+ promised_stream_id, data = frame.unpack
364
+ headers = @connection.decode_headers(data)
365
+
366
+ stream = self.create_promise_stream(headers, promised_stream_id)
367
+ stream.reserved_remote!
368
+
369
+ return stream, headers
370
+ end
310
371
  end
311
372
  end
312
373
  end
@@ -20,6 +20,6 @@
20
20
 
21
21
  module HTTP
22
22
  module Protocol
23
- VERSION = "0.14.0"
23
+ VERSION = "0.15.0"
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http-protocol
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-08 00:00:00.000000000 Z
11
+ date: 2019-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http-hpack
@@ -143,8 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
143
  - !ruby/object:Gem::Version
144
144
  version: '0'
145
145
  requirements: []
146
- rubyforge_project:
147
- rubygems_version: 2.7.8
146
+ rubygems_version: 3.0.2
148
147
  signing_key:
149
148
  specification_version: 4
150
149
  summary: Provides abstractions to handle HTTP1 and HTTP2 protocols.