ds9 1.1.0 → 1.1.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: 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