riddl 1.0.17 → 1.0.19
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 +4 -4
- data/examples/library/server.rb +1 -0
- data/examples/sse/server.rb +11 -6
- data/lib/ruby/riddl/ns/description/1.0/description.rng +27 -19
- data/lib/ruby/riddl/protocols/sse.rb +142 -46
- data/lib/ruby/riddl/protocols/websocket.rb +24 -89
- data/lib/ruby/riddl/server.rb +66 -45
- data/lib/ruby/riddl/wrapper.rb +20 -12
- data/ns/description/1.0/description.rng +27 -19
- data/riddl.gemspec +2 -2
- data/test/tc_sse.rb +82 -0
- data/test/tc_websocket.rb +29 -13
- data/tools/riddlcheck +8 -2
- data/tools/riddlprocess +8 -3
- metadata +12 -17
- data/examples/declaration-test/main.log +0 -57
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 49c4953ef05b90ac6aa446b325443636f844d639519abbc173b155ad1c045b08
|
|
4
|
+
data.tar.gz: 3d63d119a11e3d0f1421aa306b5b24c5ee61778fadcee9bf87667757c77b3f46
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 530bd8988c1b6768a7b27b61bf0ed13b4c665e2c17a633dc53825a59513d004e937525f7a8f59e9088a08a69c6140e117108c73987bd9e94b29f6e52901647e0
|
|
7
|
+
data.tar.gz: 823f21fb6983372c5df9045969820fc16ed116d1170b96d155191cdfb40b418ef9ac77c8b82d1d52e72c91d48c9eb16cc6419ce8c083dcd889be21f5b6a7f507
|
data/examples/library/server.rb
CHANGED
data/examples/sse/server.rb
CHANGED
|
@@ -4,26 +4,29 @@ require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/server'
|
|
|
4
4
|
|
|
5
5
|
class Bar < Riddl::Implementation
|
|
6
6
|
def response
|
|
7
|
-
$
|
|
8
|
-
|
|
7
|
+
$connections_mutex.synchronize do
|
|
8
|
+
$connections.each do |c|
|
|
9
|
+
c.send('some data')
|
|
10
|
+
end
|
|
9
11
|
end
|
|
10
12
|
Riddl::Parameter::Complex.new("return","text/plain","hello world")
|
|
11
13
|
end
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
$connections = []
|
|
17
|
+
$connections_mutex = Mutex.new
|
|
15
18
|
|
|
16
19
|
class Echo < Riddl::SSEImplementation
|
|
17
20
|
def onopen
|
|
18
21
|
# if true (or any object for that matter) is returned, then 200 is sent
|
|
19
22
|
# if false (or nil) is returned 404, the sse is denied
|
|
20
23
|
puts "Connection established"
|
|
21
|
-
$connections << self
|
|
24
|
+
$connections_mutex.synchronize { $connections << self }
|
|
22
25
|
end
|
|
23
26
|
|
|
24
27
|
def onclose
|
|
25
28
|
puts "Connection closed"
|
|
26
|
-
$connections.delete(self)
|
|
29
|
+
$connections_mutex.synchronize { $connections.delete(self) }
|
|
27
30
|
end
|
|
28
31
|
end
|
|
29
32
|
|
|
@@ -32,8 +35,10 @@ Riddl::Server.new(File.dirname(__FILE__) + '/description.xml', :port => 9292) do
|
|
|
32
35
|
|
|
33
36
|
parallel do
|
|
34
37
|
loop do
|
|
35
|
-
$
|
|
36
|
-
c
|
|
38
|
+
$connections_mutex.synchronize do
|
|
39
|
+
$connections.each do |c|
|
|
40
|
+
c.send('heartbeat')
|
|
41
|
+
end
|
|
37
42
|
end
|
|
38
43
|
sleep 15
|
|
39
44
|
end
|
|
@@ -14,21 +14,23 @@
|
|
|
14
14
|
<data type="anyURI"/>
|
|
15
15
|
</attribute>
|
|
16
16
|
<ref name="riddl-description-other-atts"/>
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
17
|
+
<interleave>
|
|
18
|
+
<zeroOrMore>
|
|
19
|
+
<choice>
|
|
20
|
+
<element name="message">
|
|
21
|
+
<ref name="riddl-description-other-atts"/>
|
|
22
|
+
<ref name="riddl-message"/>
|
|
23
|
+
</element>
|
|
24
|
+
<element name="transformation">
|
|
25
|
+
<ref name="riddl-description-other-atts"/>
|
|
26
|
+
<ref name="riddl-transformation"/>
|
|
27
|
+
</element>
|
|
28
|
+
</choice>
|
|
29
|
+
</zeroOrMore>
|
|
30
|
+
<element name="resource">
|
|
31
|
+
<ref name="riddl-resource-dynamic"/>
|
|
32
|
+
</element>
|
|
33
|
+
</interleave>
|
|
32
34
|
</define>
|
|
33
35
|
|
|
34
36
|
<define name="riddl-message">
|
|
@@ -199,7 +201,6 @@
|
|
|
199
201
|
<data type="anyURI"/>
|
|
200
202
|
</attribute>
|
|
201
203
|
</optional>
|
|
202
|
-
<ref name="riddl-description-others"/>
|
|
203
204
|
</define>
|
|
204
205
|
|
|
205
206
|
<define name="riddl-resource-recursive-choice">
|
|
@@ -222,21 +223,28 @@
|
|
|
222
223
|
<data type="boolean"/>
|
|
223
224
|
</attribute>
|
|
224
225
|
</optional>
|
|
225
|
-
|
|
226
|
+
</define>
|
|
227
|
+
|
|
228
|
+
<define name="riddl-resource-body">
|
|
229
|
+
<interleave>
|
|
230
|
+
<ref name="riddl-description-others"/>
|
|
231
|
+
<ref name="riddl-resource-content"/>
|
|
232
|
+
<ref name="riddl-resource-sub"/>
|
|
233
|
+
</interleave>
|
|
226
234
|
</define>
|
|
227
235
|
|
|
228
236
|
<define name="riddl-resource-dynamic">
|
|
229
237
|
<ref name="riddl-resource-attributes"/>
|
|
230
|
-
<ref name="riddl-resource-content"/>
|
|
231
238
|
<ref name="riddl-resource-recursive-choice"/>
|
|
239
|
+
<ref name="riddl-resource-body"/>
|
|
232
240
|
</define>
|
|
233
241
|
<define name="riddl-resource-named">
|
|
234
242
|
<ref name="riddl-resource-attributes"/>
|
|
235
243
|
<attribute name="relative">
|
|
236
244
|
<ref name="riddl-datatype-relpath"/>
|
|
237
245
|
</attribute>
|
|
238
|
-
<ref name="riddl-resource-content"/>
|
|
239
246
|
<ref name="riddl-resource-recursive-choice"/>
|
|
247
|
+
<ref name="riddl-resource-body"/>
|
|
240
248
|
</define>
|
|
241
249
|
|
|
242
250
|
<define name="riddl-resource-sub">
|
|
@@ -1,72 +1,168 @@
|
|
|
1
1
|
module Riddl
|
|
2
2
|
module Protocols
|
|
3
|
-
|
|
3
|
+
module SSE
|
|
4
4
|
class Error < RuntimeError; end
|
|
5
5
|
|
|
6
6
|
class ParserData
|
|
7
7
|
attr_accessor :headers, :request_path, :query_string, :http_method, :body, :request_url
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
class
|
|
11
|
-
|
|
10
|
+
class Base #{{{
|
|
11
|
+
def initialize(app, env)
|
|
12
|
+
@app = app
|
|
13
|
+
@env = env
|
|
14
|
+
@closed = true
|
|
15
|
+
end
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
end
|
|
17
|
+
def send_with_id(id, data)
|
|
18
|
+
return if closed?
|
|
19
|
+
push("#{id}: #{data}" + EOL + EOL)
|
|
20
|
+
end
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
def close
|
|
23
|
+
return if closed?
|
|
24
|
+
@closed = true
|
|
25
|
+
do_close
|
|
26
|
+
end
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@body.call [ "#{id}: #{data}" + EOL + EOL ]
|
|
28
|
+
def closed?
|
|
29
|
+
@closed
|
|
27
30
|
end
|
|
28
|
-
end
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
def trigger_on_open; @closed = false; res = @app.onopen; res ? true : false; end
|
|
33
|
+
def trigger_on_close; @closed = true; @app.onclose; end
|
|
34
|
+
|
|
35
|
+
def response_headers(cross_site_xhr)
|
|
36
|
+
headers = {
|
|
37
|
+
'Content-Type' => 'text/event-stream',
|
|
38
|
+
'Cache-Control' => 'no-cache',
|
|
39
|
+
'X-Accel-Buffering' => 'no'
|
|
40
|
+
}
|
|
41
|
+
if @env['HTTP_ORIGIN'] && cross_site_xhr
|
|
42
|
+
headers['Access-Control-Allow-Origin'] = '*'
|
|
43
|
+
headers['Access-Control-Max-Age'] = '0'
|
|
44
|
+
end
|
|
45
|
+
headers
|
|
33
46
|
end
|
|
34
|
-
|
|
47
|
+
protected :response_headers
|
|
48
|
+
end #}}}
|
|
35
49
|
|
|
36
|
-
|
|
37
|
-
|
|
50
|
+
class Thin < Base #{{{
|
|
51
|
+
class DeferrableBody #{{{
|
|
52
|
+
include EventMachine::Deferrable
|
|
38
53
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
def call(body)
|
|
55
|
+
body.each { |chunk| @body_callback.call(chunk) }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def each(&blk)
|
|
59
|
+
@body_callback = blk
|
|
60
|
+
end
|
|
61
|
+
end #}}}
|
|
62
|
+
|
|
63
|
+
def initialize(app, env)
|
|
64
|
+
super
|
|
65
|
+
@env['async.close'].callback { trigger_on_close }
|
|
66
|
+
@body = DeferrableBody.new
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def dispatch(data, cross_site_xhr)
|
|
70
|
+
headers = response_headers(cross_site_xhr)
|
|
71
|
+
EventMachine::next_tick {
|
|
72
|
+
if trigger_on_open
|
|
73
|
+
@env['async.callback'].call [200, headers, @body]
|
|
74
|
+
else
|
|
75
|
+
@body.fail
|
|
76
|
+
@env['async.callback'].call [404, headers, {}]
|
|
77
|
+
end
|
|
78
|
+
}
|
|
79
|
+
nil
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def push(str)
|
|
83
|
+
EM.next_tick { @body.call [str] }
|
|
84
|
+
end
|
|
85
|
+
protected :push
|
|
86
|
+
|
|
87
|
+
def do_close
|
|
88
|
+
EM.next_tick { @body.succeed }
|
|
89
|
+
end
|
|
90
|
+
protected :do_close
|
|
91
|
+
end #}}}
|
|
46
92
|
|
|
93
|
+
class Generic < Base # other servers like PUMA
|
|
94
|
+
class QueueBody #{{{
|
|
95
|
+
def initialize
|
|
96
|
+
@queue = Queue.new
|
|
97
|
+
@on_close = nil
|
|
98
|
+
@closed_fired = false
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def on_close(&blk)
|
|
102
|
+
@on_close = blk
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def call(chunk)
|
|
106
|
+
Array(chunk).each { |c| @queue << chunk_encode(c) }
|
|
107
|
+
end
|
|
47
108
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
109
|
+
def each
|
|
110
|
+
loop do
|
|
111
|
+
chunk = @queue.pop
|
|
112
|
+
break if chunk.nil?
|
|
113
|
+
begin
|
|
114
|
+
yield chunk
|
|
115
|
+
rescue IOError, Errno::EPIPE, Errno::ECONNRESET
|
|
116
|
+
break
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
ensure
|
|
120
|
+
fire_on_close
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def close
|
|
124
|
+
@queue << "0#{EOL}#{EOL}"
|
|
125
|
+
@queue << nil
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def chunk_encode(c)
|
|
129
|
+
c.bytesize.to_s(16) + EOL + c + EOL
|
|
130
|
+
end
|
|
131
|
+
private :chunk_encode
|
|
132
|
+
|
|
133
|
+
def fire_on_close
|
|
134
|
+
return if @closed_fired
|
|
135
|
+
@closed_fired = true
|
|
136
|
+
@on_close.call if @on_close
|
|
137
|
+
end
|
|
138
|
+
private :fire_on_close
|
|
139
|
+
end #}}}
|
|
140
|
+
|
|
141
|
+
def initialize(app, env)
|
|
142
|
+
super
|
|
143
|
+
@body = QueueBody.new
|
|
144
|
+
@body.on_close { trigger_on_close }
|
|
57
145
|
end
|
|
58
|
-
|
|
146
|
+
|
|
147
|
+
def dispatch(data, cross_site_xhr)
|
|
148
|
+
headers = response_headers(cross_site_xhr).merge('Transfer-Encoding' => 'chunked')
|
|
59
149
|
if trigger_on_open
|
|
60
|
-
|
|
150
|
+
[200, headers, @body]
|
|
61
151
|
else
|
|
62
|
-
@body.
|
|
63
|
-
|
|
152
|
+
@body.close
|
|
153
|
+
[404, headers, []]
|
|
64
154
|
end
|
|
65
|
-
|
|
66
|
-
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def push(str)
|
|
158
|
+
@body.call [str]
|
|
159
|
+
end
|
|
160
|
+
protected :push
|
|
67
161
|
|
|
68
|
-
|
|
69
|
-
|
|
162
|
+
def do_close
|
|
163
|
+
@body.close
|
|
164
|
+
end
|
|
165
|
+
protected :do_close
|
|
70
166
|
end
|
|
71
167
|
end
|
|
72
168
|
end
|
|
@@ -1,109 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require 'thin'
|
|
4
|
-
|
|
5
|
-
module Thin #{{{
|
|
6
|
-
class Connection
|
|
7
|
-
attr_accessor :websocket
|
|
8
|
-
def websocket?
|
|
9
|
-
!self.websocket.nil?
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def pre_process_with_websocket
|
|
13
|
-
@request.env['thin.connection'] = self
|
|
14
|
-
pre_process_without_websocket
|
|
15
|
-
end
|
|
16
|
-
alias :pre_process_without_websocket :pre_process
|
|
17
|
-
alias :pre_process :pre_process_with_websocket
|
|
18
|
-
|
|
19
|
-
def receive_data_with_websocket(data)
|
|
20
|
-
if self.websocket?
|
|
21
|
-
self.websocket.receive_data(data)
|
|
22
|
-
else
|
|
23
|
-
receive_data_without_websocket(data)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
alias :receive_data_without_websocket :receive_data
|
|
27
|
-
alias :receive_data :receive_data_with_websocket
|
|
28
|
-
|
|
29
|
-
def unbind_with_websocket
|
|
30
|
-
if self.websocket?
|
|
31
|
-
self.websocket.unbind
|
|
32
|
-
else
|
|
33
|
-
unbind_without_websocket
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
alias :unbind_without_websocket :unbind
|
|
37
|
-
alias :unbind :unbind_with_websocket
|
|
38
|
-
end
|
|
39
|
-
end #}}}
|
|
40
|
-
|
|
41
|
-
module EventMachine
|
|
42
|
-
module WebSocket
|
|
43
|
-
class Handshake
|
|
44
|
-
def receive_data(data)
|
|
45
|
-
data.request_url = Riddl::Protocols::Utils::escape(data.request_url)
|
|
46
|
-
@parser = data
|
|
47
|
-
@headers = data.headers
|
|
48
|
-
process(@headers, data.body)
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
1
|
+
require 'faye/websocket'
|
|
2
|
+
Faye::WebSocket.load_adapter('thin')
|
|
53
3
|
|
|
54
4
|
module Riddl
|
|
55
5
|
module Protocols
|
|
56
|
-
class WebSocket
|
|
6
|
+
class WebSocket
|
|
57
7
|
class Error < RuntimeError; end
|
|
58
8
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
end
|
|
64
|
-
def upgrade?
|
|
65
|
-
true
|
|
66
|
-
end
|
|
67
|
-
end
|
|
9
|
+
def initialize(app, env)
|
|
10
|
+
@app = app
|
|
11
|
+
@closed = true
|
|
12
|
+
@socket = Faye::WebSocket.new(env)
|
|
68
13
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
14
|
+
@socket.on(:open) { trigger_on_open }
|
|
15
|
+
@socket.on(:message) { |event| trigger_on_message(event.data) }
|
|
16
|
+
@socket.on(:close) { trigger_on_close }
|
|
17
|
+
@socket.on(:error) { |event| trigger_on_error(event.message) }
|
|
73
18
|
end
|
|
74
19
|
|
|
75
|
-
def
|
|
76
|
-
|
|
77
|
-
@socket.send_data(data) unless closed?
|
|
78
|
-
end
|
|
20
|
+
def dispatch
|
|
21
|
+
@socket.rack_response
|
|
79
22
|
end
|
|
80
23
|
|
|
81
|
-
def
|
|
82
|
-
EM.next_tick
|
|
83
|
-
unless closed?
|
|
84
|
-
@socket.close_connection(*args)
|
|
85
|
-
trigger_on_close
|
|
86
|
-
end
|
|
87
|
-
end
|
|
24
|
+
def send(data)
|
|
25
|
+
EM.next_tick { @socket.send(data) unless closed? }
|
|
88
26
|
end
|
|
89
27
|
|
|
90
|
-
def
|
|
91
|
-
|
|
92
|
-
def trigger_on_close; @closed = true; @app.onclose; end
|
|
93
|
-
def trigger_on_error(error); @closed = true; @app.onerror(error); true; end
|
|
94
|
-
|
|
95
|
-
def initialize(app, socket)
|
|
96
|
-
@app = app
|
|
97
|
-
@socket = socket
|
|
98
|
-
@ssl = socket.backend.respond_to?(:ssl?) && socket.backend.ssl?
|
|
99
|
-
@closed = true
|
|
100
|
-
socket.websocket = self
|
|
101
|
-
socket.comm_inactivity_timeout = 0
|
|
28
|
+
def close_connection
|
|
29
|
+
EM.next_tick { @socket.close unless closed? }
|
|
102
30
|
end
|
|
103
31
|
|
|
104
32
|
def closed?
|
|
105
33
|
@closed
|
|
106
34
|
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def trigger_on_open; @closed = false; @app.onopen; end
|
|
39
|
+
def trigger_on_message(m); @app.onmessage(m); end
|
|
40
|
+
def trigger_on_close; @closed = true; @app.onclose; end
|
|
41
|
+
def trigger_on_error(msg); @app.onerror(msg); end
|
|
107
42
|
end
|
|
108
43
|
end
|
|
109
44
|
end
|
data/lib/ruby/riddl/server.rb
CHANGED
|
@@ -53,6 +53,7 @@ module Riddl
|
|
|
53
53
|
:secure => false,
|
|
54
54
|
:verbose => false,
|
|
55
55
|
:http_only => false,
|
|
56
|
+
:server => 'thin',
|
|
56
57
|
:runtime_opts => [
|
|
57
58
|
["--port [PORT]", "-p [PORT]", "Specify http port.", ->(p){
|
|
58
59
|
@riddl_opts[:port] = p.to_i
|
|
@@ -102,12 +103,16 @@ module Riddl
|
|
|
102
103
|
app.use Rack::CommonLogger, @riddl_logger
|
|
103
104
|
end
|
|
104
105
|
|
|
106
|
+
if @riddl_opts[:secure] && @riddl_opts[:server].to_s != 'thin'
|
|
107
|
+
raise NotImplementedError, "secure (TLS) mode is not yet supported with the '#{@riddl_opts[:server]}' backend, only 'thin'"
|
|
108
|
+
end
|
|
109
|
+
|
|
105
110
|
server = Rack::Server.new(
|
|
106
111
|
:app => app,
|
|
107
112
|
:Host => @riddl_opts[:bind],
|
|
108
113
|
:Port => @riddl_opts[:port],
|
|
109
114
|
:environment => @riddl_opts[:verbose] ? 'deployment' : 'none',
|
|
110
|
-
:server =>
|
|
115
|
+
:server => @riddl_opts[:server],
|
|
111
116
|
:signals => false
|
|
112
117
|
)
|
|
113
118
|
@riddl_opts[:startup].call if @riddl_opts[:startup]
|
|
@@ -115,46 +120,68 @@ module Riddl
|
|
|
115
120
|
@riddl_opts[:custom_protocol] = @riddl_opts[:custom_protocol].new(@riddl_opts)
|
|
116
121
|
puts @riddl_opts[:custom_protocol].support if @riddl_opts[:custom_protocol].support
|
|
117
122
|
end
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
|
|
124
|
+
if @riddl_opts[:server].to_s == 'thin'
|
|
125
|
+
begin
|
|
126
|
+
EM.run do
|
|
127
|
+
if @riddl_opts[:secure]
|
|
128
|
+
server.start do |srv|
|
|
129
|
+
srv.ssl = true
|
|
130
|
+
srv.ssl_options = @riddl_opts[:secure_options]
|
|
131
|
+
end
|
|
132
|
+
else
|
|
133
|
+
server.start
|
|
124
134
|
end
|
|
125
|
-
else
|
|
126
|
-
server.start
|
|
127
|
-
end
|
|
128
135
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
136
|
+
if @riddl_opts[:custom_protocol] && !@riddl_opts[:http_only]
|
|
137
|
+
@riddl_opts[:custom_protocol].start
|
|
138
|
+
end
|
|
132
139
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
140
|
+
[:INT, :TERM].each do |signal|
|
|
141
|
+
Signal.trap(signal) do
|
|
142
|
+
if @riddl_opts[:cleanup]
|
|
143
|
+
@riddl_opts[:cleanup].call
|
|
144
|
+
end
|
|
145
|
+
EM.stop
|
|
137
146
|
end
|
|
138
|
-
EM.stop
|
|
139
147
|
end
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
148
|
+
[:HUP].each do |signal|
|
|
149
|
+
Signal.trap(signal) do
|
|
150
|
+
EM.stop
|
|
151
|
+
end
|
|
144
152
|
end
|
|
145
|
-
end
|
|
146
153
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
154
|
+
if @riddl_opts[:parallel]
|
|
155
|
+
EM.defer do
|
|
156
|
+
@riddl_opts[:parallel].call
|
|
157
|
+
end
|
|
150
158
|
end
|
|
151
159
|
end
|
|
160
|
+
rescue => e
|
|
161
|
+
if @riddl_opts[:custom_protocol] && !@riddl_opts[:http_only]
|
|
162
|
+
@riddl_opts[:custom_protocol].error_handling(e)
|
|
163
|
+
end
|
|
164
|
+
puts "Server (#{@riddl_opts[:cmdl_info]}) stopped due to connection error (PID:#{Process.pid})"
|
|
152
165
|
end
|
|
153
|
-
|
|
166
|
+
else # other servers like PUMA
|
|
167
|
+
Faye::WebSocket.ensure_reactor_running
|
|
168
|
+
|
|
154
169
|
if @riddl_opts[:custom_protocol] && !@riddl_opts[:http_only]
|
|
155
|
-
@riddl_opts[:custom_protocol].
|
|
170
|
+
@riddl_opts[:custom_protocol].start
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
Thread.new { @riddl_opts[:parallel].call } if @riddl_opts[:parallel]
|
|
174
|
+
|
|
175
|
+
begin
|
|
176
|
+
server.start do |launcher|
|
|
177
|
+
launcher.events.after_stopped { @riddl_opts[:cleanup].call if @riddl_opts[:cleanup] }
|
|
178
|
+
end
|
|
179
|
+
rescue => e
|
|
180
|
+
if @riddl_opts[:custom_protocol] && !@riddl_opts[:http_only]
|
|
181
|
+
@riddl_opts[:custom_protocol].error_handling(e)
|
|
182
|
+
end
|
|
183
|
+
puts "Server (#{@riddl_opts[:cmdl_info]}) stopped due to connection error (PID:#{Process.pid})"
|
|
156
184
|
end
|
|
157
|
-
puts "Server (#{@riddl_opts[:cmdl_info]}) stopped due to connection error (PID:#{Process.pid})"
|
|
158
185
|
end
|
|
159
186
|
end #}}}
|
|
160
187
|
|
|
@@ -237,6 +264,7 @@ module Riddl
|
|
|
237
264
|
@riddl_log = @riddl_logger || @riddl_env['rack.errors']
|
|
238
265
|
@riddl_res = Rack::Response.new
|
|
239
266
|
@riddl_status = 404
|
|
267
|
+
@riddl_async_response = nil
|
|
240
268
|
|
|
241
269
|
@riddl_pinfo = Riddl::Protocols::Utils::unescape(@riddl_env["PATH_INFO"].gsub(/\/+/,'/'))
|
|
242
270
|
@riddl_matching_path = @riddl_paths.find{ |e| @riddl_pinfo.match(e[1]).to_s.length == @riddl_pinfo.length }
|
|
@@ -294,7 +322,7 @@ module Riddl
|
|
|
294
322
|
end
|
|
295
323
|
end
|
|
296
324
|
end
|
|
297
|
-
throw :async
|
|
325
|
+
throw :async if @riddl_opts[:server].to_s == 'thin'
|
|
298
326
|
elsif @riddl_info[:env]['HTTP_ACCEPT'] == 'text/event-stream'
|
|
299
327
|
@riddl_info[:m] = @riddl_method = 'sse'
|
|
300
328
|
@riddl_message = @riddl.io_messages(@riddl_matching_path[0],'sse',@riddl_parameters,@riddl_headers)
|
|
@@ -313,7 +341,7 @@ module Riddl
|
|
|
313
341
|
end
|
|
314
342
|
end
|
|
315
343
|
end
|
|
316
|
-
throw :async
|
|
344
|
+
throw :async if @riddl_opts[:server].to_s == 'thin'
|
|
317
345
|
else
|
|
318
346
|
__call
|
|
319
347
|
end
|
|
@@ -321,6 +349,7 @@ module Riddl
|
|
|
321
349
|
@riddl_log.write "404: this resource for sure does not exist.\n"
|
|
322
350
|
@riddl_status = 404 # client requests wrong path
|
|
323
351
|
end
|
|
352
|
+
return @riddl_async_response if @riddl_async_response
|
|
324
353
|
if @riddl_exe
|
|
325
354
|
parts = Protocols::HTTP::Generator.new(@riddl_exe.response,@riddl_res).generate
|
|
326
355
|
@riddl_exe.headers.each do |n,h|
|
|
@@ -382,22 +411,14 @@ module Riddl
|
|
|
382
411
|
@riddl_headers.map { |key, value| [key.downcase.gsub('_','-'), value] }
|
|
383
412
|
]
|
|
384
413
|
w = what.new(@riddl_info.merge!(:a => args, :match => matching_path))
|
|
385
|
-
|
|
386
|
-
w.io.
|
|
414
|
+
sse = @riddl_opts[:server].to_s == 'thin' ? Riddl::Protocols::SSE::Thin : Riddl::Protocols::SSE::Generic
|
|
415
|
+
w.io = sse.new(w, @riddl_env)
|
|
416
|
+
@riddl_async_response = w.io.dispatch(data, @riddl_cross_site_xhr)
|
|
387
417
|
end
|
|
388
418
|
if what.class == Class && what.superclass == Riddl::WebSocketImplementation
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
data.query_string = @riddl_query_string
|
|
393
|
-
data.http_method = @riddl_env['REQUEST_METHOD']
|
|
394
|
-
data.body = @riddl_env['rack.input'].read
|
|
395
|
-
data.headers = Hash[
|
|
396
|
-
@riddl_headers.map { |key, value| [key.downcase.gsub('_','-'), value] }
|
|
397
|
-
]
|
|
398
|
-
w = what.new(@riddl_info.merge!(:a => args, :version => @riddl_env['HTTP_SEC_WEBSOCKET_VERSION'], :match => matching_path))
|
|
399
|
-
w.io = Riddl::Protocols::WebSocket.new(w, @riddl_env['thin.connection'])
|
|
400
|
-
w.io.dispatch(data)
|
|
419
|
+
w = what.new(@riddl_info.merge!(:a => args, :match => matching_path))
|
|
420
|
+
w.io = Riddl::Protocols::WebSocket.new(w, @riddl_env)
|
|
421
|
+
@riddl_async_response = w.io.dispatch
|
|
401
422
|
end
|
|
402
423
|
if what.class == Class && what.superclass == Riddl::Implementation
|
|
403
424
|
w = what.new(@riddl_info.merge!(:a => args, :match => matching_path))
|
data/lib/ruby/riddl/wrapper.rb
CHANGED
|
@@ -90,7 +90,8 @@ module Riddl
|
|
|
90
90
|
xml = Typhoeus.get(name, ssl_verifypeer: false).response_body
|
|
91
91
|
end
|
|
92
92
|
@doc = XML::Smart.string(xml)
|
|
93
|
-
rescue
|
|
93
|
+
rescue => e
|
|
94
|
+
raise SpecificationError, "#{name.inspect} is not well-formed XML: #{e.message}" if e.is_a?(Nokogiri::XML::SyntaxError) && !xml.to_s.strip.empty?
|
|
94
95
|
begin
|
|
95
96
|
@doc = XML::Smart.string(name)
|
|
96
97
|
rescue
|
|
@@ -99,11 +100,12 @@ module Riddl
|
|
|
99
100
|
end
|
|
100
101
|
end
|
|
101
102
|
|
|
102
|
-
@doc.register_namespace 'x', XINCLUDE
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
if @doc.register_namespace 'x', XINCLUDE
|
|
104
|
+
@doc.find('//x:include/@href').each do |i|
|
|
105
|
+
if i.value =~ /^http:\/\/(www\.)?riddl\.org(\/ns\/common-patterns\/.*)/
|
|
106
|
+
t = File.expand_path(File.dirname(__FILE__)) + $2
|
|
107
|
+
i.value = t if File.exist?(t)
|
|
108
|
+
end
|
|
107
109
|
end
|
|
108
110
|
end
|
|
109
111
|
fpath.nil? ? @doc.xinclude! : @doc.xinclude!(fpath)
|
|
@@ -119,13 +121,19 @@ module Riddl
|
|
|
119
121
|
rrds = XML::Smart::open_unprotected(RIDDL_DESCRIPTION_RESOURCE_SHOW)
|
|
120
122
|
rds.register_namespace('des','http://riddl.org/ns/description/1.0')
|
|
121
123
|
rrds.register_namespace('des','http://riddl.org/ns/description/1.0')
|
|
122
|
-
|
|
123
|
-
|
|
124
|
+
prepend = lambda do |node,what,allowed|
|
|
125
|
+
first = node.find(allowed.map{ |e| "des:#{e}" }.join('|')).first
|
|
126
|
+
first ? first.add_before(what) : node.add(what)
|
|
127
|
+
end
|
|
128
|
+
des_allowed = %w{message transformation resource}
|
|
129
|
+
res_allowed = %w{post get put patch delete request websocket sse resource}
|
|
130
|
+
prepend.call @doc.root, rds.find('/des:description/des:message'), des_allowed
|
|
131
|
+
prepend.call @doc.root, rrds.find('/des:description/des:message'), des_allowed
|
|
124
132
|
@doc.find("/des:description/des:resource").each do |r|
|
|
125
|
-
|
|
133
|
+
prepend.call r, rds.find('/des:description/des:resource/*'), res_allowed
|
|
126
134
|
end
|
|
127
135
|
@doc.find("/des:description//des:resource").each do |r|
|
|
128
|
-
|
|
136
|
+
prepend.call r, rrds.find('/des:description/des:resource/*'), res_allowed
|
|
129
137
|
end
|
|
130
138
|
end
|
|
131
139
|
if @is_declaration && get_description
|
|
@@ -247,13 +255,13 @@ module Riddl
|
|
|
247
255
|
def validate!
|
|
248
256
|
#{{{
|
|
249
257
|
if @is_description
|
|
250
|
-
xval = @doc.validate_against(XML::Smart.open_unprotected(DESCRIPTION_FILE))
|
|
258
|
+
xval = @doc.validate_against(XML::Smart.open_unprotected(DESCRIPTION_FILE)) { |err| puts err }
|
|
251
259
|
xchk = ResourceChecker.new(@doc).check
|
|
252
260
|
puts xchk.join("\n") unless xchk.empty?
|
|
253
261
|
return xval && xchk.empty?
|
|
254
262
|
end
|
|
255
263
|
if @is_declaration
|
|
256
|
-
xval = @doc.validate_against(XML::Smart.open_unprotected(DECLARATION_FILE))
|
|
264
|
+
xval = @doc.validate_against(XML::Smart.open_unprotected(DECLARATION_FILE)) { |err| puts err }
|
|
257
265
|
xchk = LayerChecker.new(@doc).check
|
|
258
266
|
puts xchk.join("\n") unless xchk.empty?
|
|
259
267
|
return xval && xchk.empty?
|
|
@@ -14,21 +14,23 @@
|
|
|
14
14
|
<data type="anyURI"/>
|
|
15
15
|
</attribute>
|
|
16
16
|
<ref name="riddl-description-other-atts"/>
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
17
|
+
<interleave>
|
|
18
|
+
<zeroOrMore>
|
|
19
|
+
<choice>
|
|
20
|
+
<element name="message">
|
|
21
|
+
<ref name="riddl-description-other-atts"/>
|
|
22
|
+
<ref name="riddl-message"/>
|
|
23
|
+
</element>
|
|
24
|
+
<element name="transformation">
|
|
25
|
+
<ref name="riddl-description-other-atts"/>
|
|
26
|
+
<ref name="riddl-transformation"/>
|
|
27
|
+
</element>
|
|
28
|
+
</choice>
|
|
29
|
+
</zeroOrMore>
|
|
30
|
+
<element name="resource">
|
|
31
|
+
<ref name="riddl-resource-dynamic"/>
|
|
32
|
+
</element>
|
|
33
|
+
</interleave>
|
|
32
34
|
</define>
|
|
33
35
|
|
|
34
36
|
<define name="riddl-message">
|
|
@@ -199,7 +201,6 @@
|
|
|
199
201
|
<data type="anyURI"/>
|
|
200
202
|
</attribute>
|
|
201
203
|
</optional>
|
|
202
|
-
<ref name="riddl-description-others"/>
|
|
203
204
|
</define>
|
|
204
205
|
|
|
205
206
|
<define name="riddl-resource-recursive-choice">
|
|
@@ -222,21 +223,28 @@
|
|
|
222
223
|
<data type="boolean"/>
|
|
223
224
|
</attribute>
|
|
224
225
|
</optional>
|
|
225
|
-
|
|
226
|
+
</define>
|
|
227
|
+
|
|
228
|
+
<define name="riddl-resource-body">
|
|
229
|
+
<interleave>
|
|
230
|
+
<ref name="riddl-description-others"/>
|
|
231
|
+
<ref name="riddl-resource-content"/>
|
|
232
|
+
<ref name="riddl-resource-sub"/>
|
|
233
|
+
</interleave>
|
|
226
234
|
</define>
|
|
227
235
|
|
|
228
236
|
<define name="riddl-resource-dynamic">
|
|
229
237
|
<ref name="riddl-resource-attributes"/>
|
|
230
|
-
<ref name="riddl-resource-content"/>
|
|
231
238
|
<ref name="riddl-resource-recursive-choice"/>
|
|
239
|
+
<ref name="riddl-resource-body"/>
|
|
232
240
|
</define>
|
|
233
241
|
<define name="riddl-resource-named">
|
|
234
242
|
<ref name="riddl-resource-attributes"/>
|
|
235
243
|
<attribute name="relative">
|
|
236
244
|
<ref name="riddl-datatype-relpath"/>
|
|
237
245
|
</attribute>
|
|
238
|
-
<ref name="riddl-resource-content"/>
|
|
239
246
|
<ref name="riddl-resource-recursive-choice"/>
|
|
247
|
+
<ref name="riddl-resource-body"/>
|
|
240
248
|
</define>
|
|
241
249
|
|
|
242
250
|
<define name="riddl-resource-sub">
|
data/riddl.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = "riddl"
|
|
3
|
-
s.version = "1.0.
|
|
3
|
+
s.version = "1.0.19"
|
|
4
4
|
s.platform = Gem::Platform::RUBY
|
|
5
5
|
s.license = "LGPL-3.0-or-later"
|
|
6
6
|
s.summary = "Restful Interface Description and Declaration Language: tools and client/server libs"
|
|
@@ -31,8 +31,8 @@ Gem::Specification.new do |s|
|
|
|
31
31
|
s.add_development_dependency 'rdf-smart', '>=0.0.160', '~>0'
|
|
32
32
|
s.add_runtime_dependency 'rack', '~>2.2'
|
|
33
33
|
s.add_runtime_dependency 'thin', '~>1.6'
|
|
34
|
+
s.add_runtime_dependency 'puma', '~>8.0'
|
|
34
35
|
s.add_runtime_dependency 'eventmachine', '>= 1.0.0', '~>1.0'
|
|
35
|
-
s.add_runtime_dependency 'em-websocket', '>= 0.5.2', '~>0'
|
|
36
36
|
s.add_runtime_dependency 'faye-websocket', '>= 0.1', '~>0'
|
|
37
37
|
s.add_runtime_dependency 'mime-types', '>= 3.0', '~>3'
|
|
38
38
|
s.add_runtime_dependency 'minitest', '>= 5.0.0', '~>5'
|
data/test/tc_sse.rb
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/smartrunner.rb')
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/ruby/riddl/client')
|
|
3
|
+
require 'net/http'
|
|
4
|
+
require 'timeout'
|
|
5
|
+
|
|
6
|
+
module SSEScenario
|
|
7
|
+
def test_sse
|
|
8
|
+
info = self.class::SERVER[0]
|
|
9
|
+
ep = Riddl::Client.interface(info.url, info.schema)
|
|
10
|
+
|
|
11
|
+
test = ep.resource('/')
|
|
12
|
+
status, res = test.get
|
|
13
|
+
assert status == 200
|
|
14
|
+
assert res.length == 1
|
|
15
|
+
assert res[0].mimetype == 'text/plain'
|
|
16
|
+
assert res[0].value.read == 'hello world'
|
|
17
|
+
|
|
18
|
+
uri = URI(info.url)
|
|
19
|
+
events = Queue.new
|
|
20
|
+
opened = Queue.new
|
|
21
|
+
|
|
22
|
+
reader = Thread.new do
|
|
23
|
+
begin
|
|
24
|
+
Net::HTTP.start(uri.host, info.port) do |http|
|
|
25
|
+
req = Net::HTTP::Get.new('/', { 'Accept' => 'text/event-stream' })
|
|
26
|
+
http.request(req) do |response|
|
|
27
|
+
opened << response.code
|
|
28
|
+
buffer = +''
|
|
29
|
+
response.read_body do |chunk|
|
|
30
|
+
buffer << chunk
|
|
31
|
+
while (idx = buffer.index("\r\n\r\n"))
|
|
32
|
+
events << buffer.slice!(0..idx + 3)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
rescue IOError, Errno::ECONNRESET
|
|
38
|
+
# expected once the reader thread is killed below
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
assert Timeout.timeout(5) { opened.pop } == '200'
|
|
43
|
+
|
|
44
|
+
# a plain GET on the same server broadcasts to every open SSE connection
|
|
45
|
+
# (examples/sse/server.rb's Bar#response) -- deterministic, no need to
|
|
46
|
+
# wait on the 15s heartbeat from the `parallel` block.
|
|
47
|
+
status, _res = test.get
|
|
48
|
+
assert status == 200
|
|
49
|
+
|
|
50
|
+
event = Timeout.timeout(5) { events.pop }
|
|
51
|
+
assert event == "data: some data\r\n\r\n"
|
|
52
|
+
|
|
53
|
+
reader.kill
|
|
54
|
+
reader.join
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class TestSSEThin < Minitest::Test
|
|
59
|
+
include ServerCase
|
|
60
|
+
include SSEScenario
|
|
61
|
+
|
|
62
|
+
SERVER = [
|
|
63
|
+
TestServerInfo.new(
|
|
64
|
+
File.expand_path(File.dirname(__FILE__) + '/../examples/sse/server.rb') + ' -o server=thin',
|
|
65
|
+
File.expand_path(File.dirname(__FILE__) + '/../examples/sse/description.xml')
|
|
66
|
+
)
|
|
67
|
+
]
|
|
68
|
+
NORUN = false
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
class TestSSEPuma < Minitest::Test
|
|
72
|
+
include ServerCase
|
|
73
|
+
include SSEScenario
|
|
74
|
+
|
|
75
|
+
SERVER = [
|
|
76
|
+
TestServerInfo.new(
|
|
77
|
+
File.expand_path(File.dirname(__FILE__) + '/../examples/sse/server.rb') + ' -o server=puma',
|
|
78
|
+
File.expand_path(File.dirname(__FILE__) + '/../examples/sse/description.xml')
|
|
79
|
+
)
|
|
80
|
+
]
|
|
81
|
+
NORUN = false
|
|
82
|
+
end
|
data/test/tc_websocket.rb
CHANGED
|
@@ -1,21 +1,11 @@
|
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/smartrunner.rb')
|
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/../lib/ruby/riddl/client')
|
|
3
3
|
require 'xml/smart'
|
|
4
|
-
require 'pp'
|
|
5
|
-
|
|
6
|
-
class TestWebsocket < Minitest::Test
|
|
7
|
-
include ServerCase
|
|
8
|
-
|
|
9
|
-
SERVER = [
|
|
10
|
-
TestServerInfo.new(
|
|
11
|
-
File.expand_path(File.dirname(__FILE__) + '/../examples/websocket/server.rb'),
|
|
12
|
-
File.expand_path(File.dirname(__FILE__) + '/../examples/websocket/description.xml')
|
|
13
|
-
)
|
|
14
|
-
]
|
|
15
|
-
NORUN = false
|
|
16
4
|
|
|
5
|
+
module WebSocketScenario
|
|
17
6
|
def test_websocket
|
|
18
|
-
|
|
7
|
+
info = self.class::SERVER[0]
|
|
8
|
+
ep = Riddl::Client.interface(info.url, info.schema)
|
|
19
9
|
|
|
20
10
|
test = ep.resource('/')
|
|
21
11
|
status, res = test.get
|
|
@@ -61,3 +51,29 @@ class TestWebsocket < Minitest::Test
|
|
|
61
51
|
|
|
62
52
|
end
|
|
63
53
|
end
|
|
54
|
+
|
|
55
|
+
class TestWebsocketThin < Minitest::Test
|
|
56
|
+
include ServerCase
|
|
57
|
+
include WebSocketScenario
|
|
58
|
+
|
|
59
|
+
SERVER = [
|
|
60
|
+
TestServerInfo.new(
|
|
61
|
+
File.expand_path(File.dirname(__FILE__) + '/../examples/websocket/server.rb') + ' -o server=thin',
|
|
62
|
+
File.expand_path(File.dirname(__FILE__) + '/../examples/websocket/description.xml')
|
|
63
|
+
)
|
|
64
|
+
]
|
|
65
|
+
NORUN = false
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
class TestWebsocketPuma < Minitest::Test
|
|
69
|
+
include ServerCase
|
|
70
|
+
include WebSocketScenario
|
|
71
|
+
|
|
72
|
+
SERVER = [
|
|
73
|
+
TestServerInfo.new(
|
|
74
|
+
File.expand_path(File.dirname(__FILE__) + '/../examples/websocket/server.rb') + ' -o server=puma',
|
|
75
|
+
File.expand_path(File.dirname(__FILE__) + '/../examples/websocket/description.xml')
|
|
76
|
+
)
|
|
77
|
+
]
|
|
78
|
+
NORUN = false
|
|
79
|
+
end
|
data/tools/riddlcheck
CHANGED
|
@@ -21,7 +21,12 @@ if ARGV.length == 0 || !File.exist?(ARGV[0])
|
|
|
21
21
|
end
|
|
22
22
|
fname = ARGV[0]
|
|
23
23
|
|
|
24
|
-
riddl =
|
|
24
|
+
riddl = begin
|
|
25
|
+
Riddl::Wrapper::new(fname)
|
|
26
|
+
rescue Riddl::SpecificationError => e
|
|
27
|
+
puts e.message
|
|
28
|
+
exit 1
|
|
29
|
+
end
|
|
25
30
|
|
|
26
31
|
if riddl.description?
|
|
27
32
|
puts 'RIDDL description found.'
|
|
@@ -29,8 +34,9 @@ elsif riddl.declaration?
|
|
|
29
34
|
puts 'RIDDL declaration found.'
|
|
30
35
|
else
|
|
31
36
|
puts 'Neither a RIDDL description, nor a RIDDL declaration.'
|
|
32
|
-
exit
|
|
37
|
+
exit 1
|
|
33
38
|
end
|
|
34
39
|
|
|
35
40
|
messages = riddl.validate!
|
|
36
41
|
puts messages ? "RIDDL looks valid." : "RIDDL not valid."
|
|
42
|
+
exit 1 unless messages
|
data/tools/riddlprocess
CHANGED
|
@@ -27,15 +27,20 @@ if ARGV.length == 0 || !File.exist?(ARGV[0]) || dowhat.nil?
|
|
|
27
27
|
end
|
|
28
28
|
fname = ARGV[0]
|
|
29
29
|
|
|
30
|
-
riddl =
|
|
30
|
+
riddl = begin
|
|
31
|
+
Riddl::Wrapper.new(fname)
|
|
32
|
+
rescue Riddl::SpecificationError => e
|
|
33
|
+
puts e.message
|
|
34
|
+
exit 1
|
|
35
|
+
end
|
|
31
36
|
|
|
32
37
|
unless riddl.declaration?
|
|
33
38
|
puts 'Not a RIDDL declaration.'
|
|
34
|
-
exit
|
|
39
|
+
exit 1
|
|
35
40
|
end
|
|
36
41
|
unless riddl.validate!
|
|
37
42
|
puts "Does not conform to specification."
|
|
38
|
-
exit
|
|
43
|
+
exit 1
|
|
39
44
|
end
|
|
40
45
|
|
|
41
46
|
d = riddl.declaration
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: riddl
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.19
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Juergen 'eTM' Mangler
|
|
@@ -115,45 +115,39 @@ dependencies:
|
|
|
115
115
|
- !ruby/object:Gem::Version
|
|
116
116
|
version: '1.6'
|
|
117
117
|
- !ruby/object:Gem::Dependency
|
|
118
|
-
name:
|
|
118
|
+
name: puma
|
|
119
119
|
requirement: !ruby/object:Gem::Requirement
|
|
120
120
|
requirements:
|
|
121
|
-
- - ">="
|
|
122
|
-
- !ruby/object:Gem::Version
|
|
123
|
-
version: 1.0.0
|
|
124
121
|
- - "~>"
|
|
125
122
|
- !ruby/object:Gem::Version
|
|
126
|
-
version: '
|
|
123
|
+
version: '8.0'
|
|
127
124
|
type: :runtime
|
|
128
125
|
prerelease: false
|
|
129
126
|
version_requirements: !ruby/object:Gem::Requirement
|
|
130
127
|
requirements:
|
|
131
|
-
- - ">="
|
|
132
|
-
- !ruby/object:Gem::Version
|
|
133
|
-
version: 1.0.0
|
|
134
128
|
- - "~>"
|
|
135
129
|
- !ruby/object:Gem::Version
|
|
136
|
-
version: '
|
|
130
|
+
version: '8.0'
|
|
137
131
|
- !ruby/object:Gem::Dependency
|
|
138
|
-
name:
|
|
132
|
+
name: eventmachine
|
|
139
133
|
requirement: !ruby/object:Gem::Requirement
|
|
140
134
|
requirements:
|
|
141
135
|
- - ">="
|
|
142
136
|
- !ruby/object:Gem::Version
|
|
143
|
-
version: 0.
|
|
137
|
+
version: 1.0.0
|
|
144
138
|
- - "~>"
|
|
145
139
|
- !ruby/object:Gem::Version
|
|
146
|
-
version: '0'
|
|
140
|
+
version: '1.0'
|
|
147
141
|
type: :runtime
|
|
148
142
|
prerelease: false
|
|
149
143
|
version_requirements: !ruby/object:Gem::Requirement
|
|
150
144
|
requirements:
|
|
151
145
|
- - ">="
|
|
152
146
|
- !ruby/object:Gem::Version
|
|
153
|
-
version: 0.
|
|
147
|
+
version: 1.0.0
|
|
154
148
|
- - "~>"
|
|
155
149
|
- !ruby/object:Gem::Version
|
|
156
|
-
version: '0'
|
|
150
|
+
version: '1.0'
|
|
157
151
|
- !ruby/object:Gem::Dependency
|
|
158
152
|
name: faye-websocket
|
|
159
153
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -325,7 +319,6 @@ files:
|
|
|
325
319
|
- examples/declaration-test/declaration2.xml
|
|
326
320
|
- examples/declaration-test/goal/goal.txt
|
|
327
321
|
- examples/declaration-test/goal/goal.xml
|
|
328
|
-
- examples/declaration-test/main.log
|
|
329
322
|
- examples/declaration-test/main.rb
|
|
330
323
|
- examples/declaration-test/main.xml
|
|
331
324
|
- examples/declaration-test/over.xml
|
|
@@ -531,6 +524,7 @@ files:
|
|
|
531
524
|
- test/tc_library.rb
|
|
532
525
|
- test/tc_producer.rb
|
|
533
526
|
- test/tc_properties.rb
|
|
527
|
+
- test/tc_sse.rb
|
|
534
528
|
- test/tc_websocket.rb
|
|
535
529
|
- tools/flash-policy-server.rb
|
|
536
530
|
- tools/riddlcheck
|
|
@@ -539,7 +533,7 @@ homepage: http://github.com/etm/riddl/
|
|
|
539
533
|
licenses:
|
|
540
534
|
- LGPL-3.0-or-later
|
|
541
535
|
metadata:
|
|
542
|
-
documentation_uri: https://gemdocs.org/gems/riddl/1.0.
|
|
536
|
+
documentation_uri: https://gemdocs.org/gems/riddl/1.0.19/
|
|
543
537
|
rdoc_options: []
|
|
544
538
|
require_paths:
|
|
545
539
|
- lib/ruby
|
|
@@ -567,4 +561,5 @@ test_files:
|
|
|
567
561
|
- test/tc_library.rb
|
|
568
562
|
- test/tc_producer.rb
|
|
569
563
|
- test/tc_properties.rb
|
|
564
|
+
- test/tc_sse.rb
|
|
570
565
|
- test/tc_websocket.rb
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# Logfile created on 2013-05-21 22:59:18 +0200 by logger.rb/31641
|
|
2
|
-
Main: 127.0.0.1 - - [21/May/2013 23:04:19] "GET / HTTP/1.1" 200 - 0.0376
|
|
3
|
-
Main: 127.0.0.1 - - [21/May/2013 23:04:19] "GET /favicon.ico HTTP/1.1" 404 - 0.0001
|
|
4
|
-
Main: 127.0.0.1 - - [21/May/2013 23:04:19] "GET /favicon.ico HTTP/1.1" 404 - 0.0001
|
|
5
|
-
Main: 127.0.0.1 - - [21/May/2013 23:04:45] "GET /?a=1 HTTP/1.1" 200 - 0.0321
|
|
6
|
-
Main: 127.0.0.1 - - [21/May/2013 23:04:49] "GET /?b=1 HTTP/1.1" 200 - 0.0056
|
|
7
|
-
Main: 127.0.0.1 - - [21/May/2013 23:04:52] "GET /?b=2 HTTP/1.1" 200 - 0.0055
|
|
8
|
-
Main: 127.0.0.1 - - [21/May/2013 23:04:57] "GET /?c=2 HTTP/1.1" 200 - 0.0056
|
|
9
|
-
Main: 127.0.0.1 - - [21/May/2013 23:05:00] "GET /?d=2 HTTP/1.1" 200 - 0.0053
|
|
10
|
-
Main: 127.0.0.1 - - [21/May/2013 23:05:08] "GET /?e=2 HTTP/1.1" 200 - 0.0052
|
|
11
|
-
Main: 127.0.0.1 - - [21/May/2013 23:07:26] "GET /?a=2 HTTP/1.1" 200 - 0.0510
|
|
12
|
-
Main: 127.0.0.1 - - [21/May/2013 23:08:22] "GET /?a=2 HTTP/1.1" 200 - 0.0334
|
|
13
|
-
Main: 127.0.0.1 - - [21/May/2013 23:08:50] "GET /?a=2 HTTP/1.1" 200 - 0.0322
|
|
14
|
-
Main: 127.0.0.1 - - [21/May/2013 23:09:14] "GET /?a=2 HTTP/1.1" 200 - 0.0324
|
|
15
|
-
Main: 127.0.0.1 - - [21/May/2013 23:09:49] "GET /?a=2 HTTP/1.1" 200 - 0.0321
|
|
16
|
-
Main: 127.0.0.1 - - [21/May/2013 23:48:23] "GET /?a=2 HTTP/1.1" 200 - 0.0485
|
|
17
|
-
Main: 127.0.0.1 - - [21/May/2013 23:51:30] "GET /?a=2 HTTP/1.1" 200 - 0.0326
|
|
18
|
-
Main: 127.0.0.1 - - [21/May/2013 23:52:03] "GET /?a=2 HTTP/1.1" 200 - 0.0311
|
|
19
|
-
Main: 127.0.0.1 - - [21/May/2013 23:53:37] "GET /?a=2 HTTP/1.1" 200 - 0.0337
|
|
20
|
-
Main: 127.0.0.1 - - [21/May/2013 23:55:32] "GET /?a=2 HTTP/1.1" 200 - 0.0316
|
|
21
|
-
127.0.0.1 - - [21/May/2013 23:55:32] "GET /?a=2 HTTP/1.1" 200 1 0.0321
|
|
22
|
-
Main: 127.0.0.1 - - [21/May/2013 23:55:49] "GET /?a=2 HTTP/1.1" 200 - 0.0324
|
|
23
|
-
Main: 127.0.0.1 - - [21/May/2013 23:59:45] "GET /?a=2 HTTP/1.1" 200 - 0.0114
|
|
24
|
-
Main: 127.0.0.1 - - [22/May/2013 00:00:23] "GET /?a=2 HTTP/1.1" 200 - 0.0114
|
|
25
|
-
Main: 127.0.0.1 - - [22/May/2013 00:00:31] "GET /?a=2 HTTP/1.1" 200 - 0.0074
|
|
26
|
-
Main: 127.0.0.1 - - [22/May/2013 00:01:13] "GET /?a=2 HTTP/1.1" 200 - 0.0316
|
|
27
|
-
Main: 127.0.0.1 - - [22/May/2013 00:02:24] "GET /?a=2 HTTP/1.1" 200 - 0.0114
|
|
28
|
-
Main: 127.0.0.1 - - [22/May/2013 00:02:59] "GET /?a=2 HTTP/1.1" 200 - 0.0156
|
|
29
|
-
Main: 127.0.0.1 - - [22/May/2013 00:14:10] "GET /?a=2 HTTP/1.1" 200 - 0.0112
|
|
30
|
-
Main: 127.0.0.1 - - [22/May/2013 00:14:11] "GET /?a=2 HTTP/1.1" 200 - 0.0062
|
|
31
|
-
Main: 127.0.0.1 - - [22/May/2013 00:18:11] "GET /?a=2 HTTP/1.1" 200 - 0.0115
|
|
32
|
-
Main: 127.0.0.1 - - [22/May/2013 00:18:14] "GET /?a=2 HTTP/1.1" 200 - 0.0054
|
|
33
|
-
Main: 127.0.0.1 - - [22/May/2013 00:19:07] "GET /?a=2 HTTP/1.1" 200 - 0.0368
|
|
34
|
-
Main: 127.0.0.1 - - [22/May/2013 00:19:31] "GET /?a=2 HTTP/1.1" 200 - 0.0321
|
|
35
|
-
Main: 127.0.0.1 - - [22/May/2013 00:19:34] "GET /?a=2 HTTP/1.1" 200 - 0.0104
|
|
36
|
-
Main: 127.0.0.1 - - [22/May/2013 00:20:01] "GET /?a=2 HTTP/1.1" 200 - 0.0323
|
|
37
|
-
Main: 127.0.0.1 - - [22/May/2013 00:20:01] "GET /?a=2 HTTP/1.1" 200 - 0.0094
|
|
38
|
-
Main: 127.0.0.1 - - [22/May/2013 00:20:01] "GET /?a=2 HTTP/1.1" 200 - 0.0051
|
|
39
|
-
Main: 127.0.0.1 - - [22/May/2013 00:21:14] "GET /?a=2 HTTP/1.1" 200 - 0.0485
|
|
40
|
-
Main: 127.0.0.1 - - [22/May/2013 00:21:15] "GET /?a=2 HTTP/1.1" 200 - 0.0064
|
|
41
|
-
Main: 127.0.0.1 - - [22/May/2013 00:21:15] "GET /?a=2 HTTP/1.1" 200 - 0.0094
|
|
42
|
-
Main: 127.0.0.1 - - [22/May/2013 00:22:12] "GET /?a=2 HTTP/1.1" 200 - 0.0327
|
|
43
|
-
Main: 127.0.0.1 - - [22/May/2013 00:22:36] "GET /?a=2 HTTP/1.1" 200 - 0.0316
|
|
44
|
-
Main: 127.0.0.1 - - [22/May/2013 00:22:53] "GET /?a=2 HTTP/1.1" 200 - 0.0480
|
|
45
|
-
127.0.0.1 - - [22/May/2013 00:22:53] "GET /?a=2 HTTP/1.1" 200 1 0.0488
|
|
46
|
-
Main::: 127.0.0.1 - - [22/May/2013 00:26:52] "GET /?a=2 HTTP/1.1" 200 1 0.0332
|
|
47
|
-
Main::: 127.0.0.1 - - [22/May/2013 00:27:16] "GET / HTTP/1.1" 200 - 0.0326
|
|
48
|
-
Main::: 127.0.0.1 - - [22/May/2013 00:27:21] "GET / HTTP/1.1" 200 - 0.0054
|
|
49
|
-
Main::: 127.0.0.1 - - [22/May/2013 00:28:05] "GET /?a=1&b=2 HTTP/1.1" 200 7 0.0396
|
|
50
|
-
Main::: 127.0.0.1 - - [22/May/2013 00:28:35] "GET /?a=1&b=2 HTTP/1.1" 501 - 0.0334
|
|
51
|
-
Main::: 501: the get parameters are not matching anything in the description.Main::: 127.0.0.1 - - [22/May/2013 00:31:19] "GET /?a=1&b=2 HTTP/1.1" 501 - 0.0347
|
|
52
|
-
Main::: 501: the get parameters are not matching anything in the description.
|
|
53
|
-
Main::: 127.0.0.1 - - [22/May/2013 00:32:10] "GET /?a=1&b=2 HTTP/1.1" 501 - 0.0321
|
|
54
|
-
Main::: 501: the get parameters are not matching anything in the description.
|
|
55
|
-
Main::: 127.0.0.1 - - [22/May/2013 00:37:50] "GET /?a=1&b=2 HTTP/1.1" 501 - 0.0328
|
|
56
|
-
Main: 127.0.0.1 - - [22/May/2013 00:38:45] "GET /?a=1&b=2 HTTP/1.1" 200 7 0.0331
|
|
57
|
-
Main: 127.0.0.1 - - [22/May/2013 00:38:49] "GET /?a=1 HTTP/1.1" 200 1 0.0067
|