ds9 1.1.0 → 1.1.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
  SHA256:
3
- metadata.gz: 01fed28540c96e99ddb6513b914d305459d44518385ae18449a718089bf206ff
4
- data.tar.gz: adee017da6138cbe133f12d33ce01b2d1e9dbd73f1fbb5b694b4f7ef02e377be
3
+ metadata.gz: 9ddb3bec07f20bfb55e016cdcd831e56f9a94b70f7db63862d7951019e989567
4
+ data.tar.gz: 36d9dee001423093b24bea5fff33e46d06ac52247f971e23a4e97ede9fb36fcc
5
5
  SHA512:
6
- metadata.gz: 3bba90e6ae993d0f9fa1654482760da4696cbd8858e2a609b4e45ac206e812ddd8ad09835d04e3be61ffc7c28e1b8e4876e3b8752309fb735826269af04af6c2
7
- data.tar.gz: 455f543137a742a2c0b9f10408ee02b9aaf7f1546e6fec7a18815928c3d184abcaf54d4f8299356e10578df0f5cb9b2e4a05d76feaa1b9d60f6bdf98a7f2bed2
6
+ metadata.gz: 5200c393ba44667a62181c95d4943373dff514ed50ac70ab9459b8ad5d156f8be24743ad0c182985ddd77c8cbc41339215881c3d29cc56857118c7346444e590
7
+ data.tar.gz: d765ceb6ed1cadc9e090a42706d66858419af65c5f079b9a132ad32d6aba3fdd0bf9a95e7f2d249c5119bd336546b301f4778117dc7a033129d7dae21afcaba6
@@ -277,6 +277,12 @@ static ssize_t rb_data_read_callback(nghttp2_session *session,
277
277
  return 0;
278
278
  }
279
279
 
280
+ if (ret == Qfalse) {
281
+ *data_flags |= NGHTTP2_DATA_FLAG_EOF;
282
+ *data_flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
283
+ return 0;
284
+ }
285
+
280
286
  Check_Type(ret, T_STRING);
281
287
  len = RSTRING_LEN(ret);
282
288
  memcpy(buf, StringValuePtr(ret), len);
@@ -448,6 +454,48 @@ static VALUE session_submit_settings(VALUE self, VALUE settings)
448
454
  return self;
449
455
  }
450
456
 
457
+ static VALUE session_submit_trailer(VALUE self, VALUE stream_id, VALUE trailers)
458
+ {
459
+ size_t niv;
460
+ nghttp2_nv *nva;
461
+ nghttp2_session *session;
462
+ int rv;
463
+ int32_t s_id;
464
+ copy_header_func_t copy_func;
465
+
466
+ TypedData_Get_Struct(self, nghttp2_session, &ds9_session_type, session);
467
+ CheckSelf(session);
468
+
469
+ s_id = NUM2INT(stream_id);
470
+
471
+ switch(TYPE(trailers))
472
+ {
473
+ case T_ARRAY:
474
+ niv = RARRAY_LEN(trailers);
475
+ copy_func = copy_list_to_nv;
476
+ break;
477
+ case T_HASH:
478
+ niv = RHASH_SIZE(trailers);
479
+ copy_func = copy_hash_to_nv;
480
+ break;
481
+ default:
482
+ Check_Type(trailers, T_ARRAY);
483
+ }
484
+
485
+ nva = xcalloc(niv, sizeof(nghttp2_nv));
486
+ copy_func(trailers, nva, niv);
487
+
488
+ rv = nghttp2_submit_trailer(session, s_id, nva, niv);
489
+
490
+ xfree(nva);
491
+
492
+ if (0 != rv) {
493
+ explode(rv);
494
+ }
495
+
496
+ return self;
497
+ }
498
+
451
499
  static VALUE session_send(VALUE self)
452
500
  {
453
501
  int rv;
@@ -536,6 +584,8 @@ ruby_read(nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t leng
536
584
  VALUE ret = rb_funcall(source->ptr, rb_intern("read"), 1, INT2NUM(length));
537
585
 
538
586
  if (NIL_P(ret)) {
587
+ VALUE self = (VALUE)user_data;
588
+ rb_funcall(self, rb_intern("remove_post_buffer"), 1, INT2NUM(stream_id));
539
589
  *data_flags |= NGHTTP2_DATA_FLAG_EOF;
540
590
  return 0;
541
591
  } else {
@@ -562,6 +612,8 @@ file_read(nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t leng
562
612
 
563
613
  if (nread == 0) {
564
614
  *data_flags |= NGHTTP2_DATA_FLAG_EOF;
615
+ VALUE self = (VALUE)user_data;
616
+ rb_funcall(self, rb_intern("remove_post_buffer"), 1, INT2NUM(stream_id));
565
617
  }
566
618
  return nread;
567
619
  }
@@ -619,6 +671,10 @@ static VALUE session_submit_request(VALUE self, VALUE settings, VALUE body)
619
671
  explode(rv);
620
672
  }
621
673
 
674
+ if(!NIL_P(body)) {
675
+ rb_funcall(self, rb_intern("save_post_buffer"), 2, INT2NUM(rv), body);
676
+ }
677
+
622
678
  return INT2NUM(rv);
623
679
  }
624
680
 
@@ -928,6 +984,7 @@ void Init_ds9(void)
928
984
  rb_define_method(cDS9Server, "submit_response", server_submit_response, 2);
929
985
  rb_define_method(cDS9Server, "submit_push_promise", server_submit_push_promise, 2);
930
986
  rb_define_method(cDS9Server, "submit_shutdown", session_submit_shutdown, 0);
987
+ rb_define_method(cDS9Server, "submit_trailer", session_submit_trailer, 2);
931
988
 
932
989
  rb_define_singleton_method(eDS9Exception, "to_string", errors_to_string, 1);
933
990
 
data/lib/ds9.rb CHANGED
@@ -2,7 +2,7 @@ require 'ds9.so'
2
2
  require 'stringio'
3
3
 
4
4
  module DS9
5
- VERSION = '1.1.0'
5
+ VERSION = '1.1.1'
6
6
 
7
7
  module Frames
8
8
  class Frame
@@ -73,12 +73,21 @@ module DS9
73
73
 
74
74
  class Session
75
75
  def initialize
76
+ @post_buffers = {}
76
77
  cbs = make_callbacks
77
78
  init_internals cbs
78
79
  end
79
80
 
80
81
  private
81
82
 
83
+ def save_post_buffer id, stream
84
+ @post_buffers[id] = stream
85
+ end
86
+
87
+ def remove_post_buffer id
88
+ @post_buffers.delete id
89
+ end
90
+
82
91
  def send_event string
83
92
  raise NotImplementedError
84
93
  end
@@ -78,16 +78,28 @@ module DS9
78
78
  include IOEvents
79
79
 
80
80
  class Response
81
- attr_reader :stream_id, :body, :headers
81
+ attr_reader :stream_id, :body
82
82
 
83
83
  def initialize stream_id
84
84
  @stream_id = stream_id
85
- @headers = {}
85
+ @headers = [{}]
86
86
  @body = StringIO.new
87
87
  end
88
88
 
89
- def [] k; @headers[k]; end
90
- def []= k, v; @headers[k] = v; end
89
+ def headers
90
+ @headers[0]
91
+ end
92
+
93
+ def trailers
94
+ @headers[1]
95
+ end
96
+
97
+ def [] k; @headers.last[k]; end
98
+ def []= k, v; @headers.last[k] = v; end
99
+
100
+ def bump
101
+ @headers << {}
102
+ end
91
103
  end
92
104
 
93
105
  attr_reader :responses, :response_queue, :frames
@@ -104,7 +116,11 @@ module DS9
104
116
  end
105
117
 
106
118
  def on_begin_headers frame
107
- @response_streams[frame.stream_id] = Response.new(frame.stream_id)
119
+ if @response_streams[frame.stream_id]
120
+ @response_streams[frame.stream_id].bump
121
+ else
122
+ @response_streams[frame.stream_id] = Response.new(frame.stream_id)
123
+ end
108
124
  end
109
125
 
110
126
  def on_header name, value, frame, flags
@@ -144,7 +160,13 @@ module DS9
144
160
  end
145
161
 
146
162
  def on_data_source_read stream_id, length
147
- @write_streams[stream_id].body.shift
163
+ chunk = @write_streams[stream_id].body.shift
164
+ if chunk.nil? && @write_streams[stream_id].trailers
165
+ submit_trailer stream_id, @write_streams[stream_id].trailers
166
+ false
167
+ else
168
+ chunk
169
+ end
148
170
  end
149
171
 
150
172
  def on_stream_close id, error_code
@@ -172,7 +194,7 @@ module DS9
172
194
  end
173
195
  end
174
196
 
175
- class Response < Struct.new :stream, :stream_id, :body
197
+ class Response < Struct.new :stream, :stream_id, :body, :trailers
176
198
  def push headers
177
199
  stream.submit_push_promise stream_id, headers
178
200
  end
@@ -287,4 +287,53 @@ class TestClient < DS9::TestCase
287
287
  assert_equal res_hash, responses.first.headers
288
288
  assert_equal ["omglolwut"], responses.map(&:body).map(&:string)
289
289
  end
290
+
291
+ def test_trailers
292
+ body = 'omglolwut'
293
+
294
+ req_hash = {
295
+ ':method' => 'GET',
296
+ ':path' => '/',
297
+ ':scheme' => 'https',
298
+ ':authority' => ['localhost', '8080'].join(':'),
299
+ 'accept' => '*/*',
300
+ 'user-agent' => 'test',
301
+ }
302
+
303
+ res_hash = {
304
+ ":status" => '200',
305
+ "server" => 'test server',
306
+ "date" => 'Sat, 27 Jun 2015 17:29:21 GMT',
307
+ "x-whatever" => "blah"
308
+ }
309
+
310
+ trailers = { 'x-foo' => 'bar' }
311
+
312
+ server, client = pipe do |req, res|
313
+ assert_equal req_hash, req.headers
314
+
315
+ res.submit_response res_hash
316
+ res.trailers = trailers
317
+ res.finish body
318
+ end
319
+
320
+ client.submit_request req_hash
321
+
322
+ s = Thread.new { server.run }
323
+ c = Thread.new { client.run }
324
+
325
+ responses = []
326
+ while response = client.responses.pop
327
+ responses << response
328
+ if responses.length == 1
329
+ client.terminate_session DS9::NO_ERROR
330
+ end
331
+ end
332
+
333
+ s.join
334
+ c.join
335
+ assert_equal res_hash, responses.first.headers
336
+ assert_equal trailers, responses.first.trailers
337
+ assert_equal ["omglolwut"], responses.map(&:body).map(&:string)
338
+ end
290
339
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ds9
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-25 00:00:00.000000000 Z
11
+ date: 2018-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest