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 +4 -4
- data/ext/ds9/ds9.c +57 -0
- data/lib/ds9.rb +10 -1
- data/test/helper.rb +29 -7
- data/test/test_client.rb +49 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ddb3bec07f20bfb55e016cdcd831e56f9a94b70f7db63862d7951019e989567
|
4
|
+
data.tar.gz: 36d9dee001423093b24bea5fff33e46d06ac52247f971e23a4e97ede9fb36fcc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5200c393ba44667a62181c95d4943373dff514ed50ac70ab9459b8ad5d156f8be24743ad0c182985ddd77c8cbc41339215881c3d29cc56857118c7346444e590
|
7
|
+
data.tar.gz: d765ceb6ed1cadc9e090a42706d66858419af65c5f079b9a132ad32d6aba3fdd0bf9a95e7f2d249c5119bd336546b301f4778117dc7a033129d7dae21afcaba6
|
data/ext/ds9/ds9.c
CHANGED
@@ -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.
|
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
|
data/test/helper.rb
CHANGED
@@ -78,16 +78,28 @@ module DS9
|
|
78
78
|
include IOEvents
|
79
79
|
|
80
80
|
class Response
|
81
|
-
attr_reader :stream_id, :body
|
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
|
90
|
-
|
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]
|
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
|
data/test/test_client.rb
CHANGED
@@ -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.
|
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-
|
11
|
+
date: 2018-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|