rbsrt 0.1.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.
@@ -0,0 +1,24 @@
1
+ /*
2
+ * Ruby SRT - Ruby binding for Secure, Reliable, Transport
3
+ * Copyright (c) 2019 Klaas Speller, Recce.
4
+ *
5
+ * This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ *
9
+ */
10
+
11
+ /**
12
+ * A Ruby wrapper for SRT (Secure Reliable Transport)
13
+ *
14
+ * @author: Klaas Speller <klaas@recce.nl>
15
+ */
16
+
17
+ #ifndef RBSRT_STATS_H
18
+ #define RBSRT_STATS_H
19
+
20
+ #include <ruby/ruby.h>
21
+
22
+ void RBSRT_stat_init(VALUE srt_module);
23
+
24
+ #endif /* RBSRT_STATS_H */
Binary file
@@ -0,0 +1,113 @@
1
+ # srt streamid parser based on https://github.com/Haivision/srt/blob/master/docs/AccessControl.md
2
+
3
+ require "uri"
4
+
5
+ module SRT
6
+ class StreamIDComponents
7
+ Types = ["stream", "file", "auth"]
8
+
9
+ Modes = ["request", "publish", "bidirectional"]
10
+
11
+ Header = "#!::"
12
+
13
+ attr_accessor :resource_name
14
+ attr_accessor :user_name
15
+ attr_accessor :mode
16
+ attr_accessor :host_name
17
+ attr_accessor :type
18
+ attr_accessor :sessionid
19
+ attr_reader :extra
20
+
21
+ def initialize(*args)
22
+
23
+ @mode = :request
24
+ @type = :stream
25
+ @extra = {}
26
+
27
+ # no args
28
+ return unless args.first
29
+
30
+ # hash args
31
+ if args.first.class == ::Hash
32
+ merge_hash!(args.first)
33
+ elsif streamid = args.first.to_s
34
+ if streamid.index(Header) == 0
35
+ merge_str!(streamid)
36
+ elsif streamid =~ URI::regexp
37
+ merge_uri!(URI(streamid))
38
+ else
39
+ @resource_name = streamid
40
+ end
41
+ end
42
+ end
43
+
44
+ def to_s
45
+ streamid = Header.dup
46
+
47
+ vars = []
48
+
49
+ vars << "r=#{resource_name}" if resource_name
50
+ vars << "u=#{user_name}" if user_name
51
+ vars << "m=#{mode}" if mode
52
+ vars << "h=#{host_name}" if host_name
53
+ vars << "t=#{type}" if type
54
+ vars << "s=#{sessionid}" if sessionid
55
+
56
+ extra.each { |key,val| vars << "#{key}=#{val}" }
57
+
58
+ streamid + vars.join(",")
59
+ end
60
+
61
+ def method_missing(name, *args)
62
+ return extra[name.to_s] if extra.key? name.to_s
63
+ match = name.to_s.match(/^(.*?)(=?)$/)
64
+ case match[2]
65
+ when "="
66
+ @extra[match[1]] = args.first
67
+ else
68
+ return nil
69
+ end
70
+ end
71
+
72
+ def set(key, val)
73
+ case key.to_s
74
+ when 'resource_name', 'r' then @resource_name = val
75
+ when 'user_name', 'u' then @user_name = val
76
+ when 'mode', 'm' then @mode = val.to_sym if Modes.include?(val.to_s)
77
+ when 'host_name', 'h'
78
+ if sep = val.index("/")
79
+ @host_name = val[0..(sep - 1)]
80
+ (@resource_name = val[(sep + 1)..-1] unless @resource_name)
81
+ else
82
+ @host_name = val
83
+ end
84
+ when 'type', 't' then (@type = val.to_sym if Types.include?(val.to_s))
85
+ when 'sessionid', 's' then @sessionid = val
86
+ else @extra[key] = val
87
+ end
88
+ end
89
+
90
+ def merge_uri!(streamid)
91
+ uri = URI(streamid)
92
+
93
+ @host_name = uri.hostname
94
+ @resource_name = uri.path[1..-1] if uri.path
95
+
96
+ if uri.query && form = URI.decode_www_form(uri.query)
97
+ merge_hash!(Hash[form])
98
+ end
99
+ end
100
+
101
+ def merge_str!(streamid)
102
+ streamid.scan(/([a-z0-9_-]+?)=(.+?)(,|$)/i).each do |key,val,_|
103
+ set(key, val)
104
+ end
105
+ end
106
+
107
+ def merge_hash!(hash)
108
+ hash.each do |key, val|
109
+ set(key, val)
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,3 @@
1
+ module SRT
2
+ VERSION = "0.1.0"
3
+ end
data/lib/rbsrt.rb ADDED
@@ -0,0 +1,5 @@
1
+ $:.push File.expand_path("../", __FILE__)
2
+
3
+ require_relative "rbsrt/version"
4
+ require_relative "rbsrt/streamid_components"
5
+ require_relative "rbsrt/rbsrt"
data/rbsrt.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ require "rbsrt/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'rbsrt'
7
+ s.version = SRT::VERSION
8
+ s.licenses = ['MPLv2.0', 'MIT']
9
+ s.summary = "Ruby API for SRT (Secure Reliable Transport)"
10
+ s.description = "Build SRT (Secure Reliable Transport) servers and clients with Ruby"
11
+ s.authors = ["Klaas Speller"]
12
+ s.email = ["klaas@recce.nl"]
13
+ s.files = Dir['README*.md', 'lib/**/*', 'ext/**/*', 'bin/**/*'] + ['Rakefile', 'rbsrt.gemspec']
14
+ s.test_files = Dir['test/**/*_test.rb']
15
+ s.bindir = "bin"
16
+ s.executables = ["rbsrt-server", "rbsrt-client"]
17
+ s.homepage = 'https://github.com/spllr/rbsrt'
18
+ s.metadata = { "source_code_uri" => "https://github.com/spllr/rbsrt" }
19
+ s.extensions = %w[ext/rbsrt/extconf.rb]
20
+ s.required_ruby_version = ">= 2.2.0"
21
+ s.add_development_dependency "rake-compiler", "~> 1.0"
22
+ end
@@ -0,0 +1,153 @@
1
+ require 'minitest/spec'
2
+
3
+ require "rbsrt"
4
+ require "thread"
5
+
6
+ describe SRT::Poll do
7
+ it "can be created" do
8
+ assert_instance_of(SRT::Poll, SRT::Poll.new)
9
+ end
10
+
11
+
12
+
13
+ describe "monitor server sockets" do
14
+ before do
15
+ # puts "server start"
16
+ @server = SRT::Socket.new
17
+ @server.bind "127.0.0.1", "6789"
18
+ @server.listen 2
19
+ end
20
+
21
+ after do
22
+ # puts "server stop"
23
+ @client.close if @client
24
+ @server.close if @server
25
+ end
26
+
27
+ it "will trigger when an new connection is available" do
28
+ poll = SRT::Poll.new
29
+
30
+ poll.add @server, :in
31
+
32
+ Thread.new do
33
+ # puts "connect to server"
34
+ @client = SRT::Socket.new
35
+ @client.connect "127.0.0.1", "6789"
36
+ end
37
+
38
+
39
+ # block/ yield style
40
+
41
+ did_call = false
42
+
43
+ poll.wait do |readable, writable, errors|
44
+ did_call = true
45
+ refute_empty readable
46
+ assert_empty writable
47
+ assert_empty errors
48
+
49
+ assert_equal @server, readable.first
50
+
51
+ @accepted_sock = readable.first.accept
52
+
53
+ poll.add @accepted_sock, :in, :err
54
+ end
55
+
56
+ assert_equal true, did_call, "wait block must yield"
57
+
58
+ # return style
59
+
60
+ Thread.new do
61
+ # puts "write data to server"
62
+ @client.sendmsg "data from client"
63
+ end
64
+
65
+ readable, writable, errors = poll.wait 1000
66
+
67
+ refute_empty readable
68
+ assert_empty writable
69
+ assert_empty errors
70
+
71
+ assert_equal @accepted_sock, readable.first
72
+
73
+ assert_equal "data from client", readable.first.recvmsg
74
+
75
+ # removing sockets
76
+
77
+ poll.remove @client
78
+
79
+ Thread.new do
80
+ # puts "write data to server"
81
+ @client.sendmsg "data from client"
82
+ end
83
+
84
+ readable, writable, errors = poll.wait 100
85
+
86
+ assert_empty readable
87
+ assert_empty writable
88
+ assert_empty errors
89
+ end
90
+ end
91
+
92
+
93
+ describe "adding and updating sockets" do
94
+ before do
95
+ # puts "server start"
96
+ @server = SRT::Socket.new
97
+ @server.bind "127.0.0.1", "6789"
98
+ @server.listen 2
99
+ end
100
+
101
+ after do
102
+ # puts "server stop"
103
+ @client.close if @client
104
+ @server.close if @server
105
+ end
106
+
107
+ it "can update a socket" do
108
+ poll = SRT::Poll.new
109
+
110
+ poll.add @server, :in
111
+
112
+ Thread.new do
113
+ @client = SRT::Socket.new
114
+ @client.connect "127.0.0.1", "6789"
115
+ end
116
+
117
+ readable, _, _ = poll.wait 100
118
+
119
+ remote_client = readable.first.accept
120
+
121
+ # puts "++ IN OUT"
122
+ poll.add remote_client, :err
123
+ # puts "-- IN OUT"
124
+
125
+ Thread.new do
126
+ @client.write "foobar 1"
127
+ end
128
+
129
+ readable, writable, errors = poll.wait 100
130
+
131
+ assert_empty readable
132
+ assert_empty writable
133
+ assert_empty errors
134
+
135
+ _ = remote_client.read
136
+
137
+ # upddate
138
+
139
+ poll.update remote_client, :in
140
+
141
+ Thread.new do
142
+ @client.write "foobar 2"
143
+ end
144
+
145
+ readable, writable, errors = poll.wait 100
146
+
147
+ # pending
148
+ # refute_empty readable
149
+ # assert_empty writable
150
+ # assert_empty errors
151
+ end
152
+ end
153
+ end