riddl 0.100.7 → 0.100.8
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/declaration-server-distributed/properties.xml +1 -1
- data/examples/declaration-server-distributed/xsls/test/properties.xsl +1 -1
- data/examples/declaration-server-hybrid/properties.xml +1 -1
- data/examples/declaration-server-local/properties.xml +1 -1
- data/examples/downloadify/downloadify.xml +1 -1
- data/examples/flickr/Exif/riddl.jpg +1 -1
- data/examples/flickr/Flickr/riddl.png +1 -1
- data/examples/flickr/riddl.jpg +1 -1
- data/examples/notifications/producer.main.xml +1 -1
- data/examples/properties/properties.xml +1 -1
- data/examples/propnew/properties.xml +1 -1
- data/examples/sse/description.xml +12 -0
- data/examples/sse/sample.html +42 -0
- data/examples/sse/server.rb +35 -0
- data/examples/websocket/client.rb +11 -10
- data/examples/websocket/description.xml +1 -1
- data/examples/websocket/sample.html +4 -4
- data/examples/websocket/server.rb +9 -17
- data/examples/xmpp/properties.xml +1 -1
- data/lib/ruby/riddl/implementation.rb +38 -2
- data/lib/ruby/riddl/ns/description/1.0/description.rng +3 -0
- data/lib/ruby/riddl/protocols/sse.rb +68 -0
- data/lib/ruby/riddl/protocols/websocket.rb +11 -9
- data/lib/ruby/riddl/server.rb +36 -1
- data/lib/ruby/riddl/wrapper.rb +6 -0
- data/lib/ruby/riddl/wrapper/description/access.rb +11 -0
- data/lib/ruby/riddl/wrapper/description/resource.rb +21 -10
- data/ns/description/1.0/description.rng +3 -0
- data/riddl.gemspec +1 -1
- metadata +43 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51374489eb136360002005e40fcbc95fb39c76b0ed785a6140aedc5258e01538
|
4
|
+
data.tar.gz: 4771ee6bbb1ab85645bdaf3748ca67c3a5520cb6e92c46289b1373f6463c876a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3f3feb3c42040b91ec54052d9b00ba516af3829526a927fca71c2a4bd74ddf0aa99627029b98ca10ac18b32322c70ea7eea655e1dcf0eb98b0f79f387ba94f4
|
7
|
+
data.tar.gz: f35203debbd526246e2ccca14f277045031117f9169ad915f4e5d84a283188d615a9f1764f59f4cd250f1e7a0268a16a0248e7bf1250474adfbf799c5392281f
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../../ns/common-patterns/properties/1.0/properties.xml
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../properties.xsl
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../../ns/common-patterns/properties/1.0/properties.xml
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../../ns/common-patterns/properties/1.0/properties.xml
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../../lib/ruby/riddl/ns/common-patterns/downloadify/1.0/downloadify.xml
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../../../contrib/riddl.jpg
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../../../contrib/riddl.png
|
data/examples/flickr/riddl.jpg
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../../contrib/riddl.jpg
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../../ns/common-patterns/notifications-producer/1.0/producer.xml
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../../ns/common-patterns/properties/1.0/properties.xml
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../../ns/common-patterns/properties/1.0/properties.xml
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<description datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://riddl.org/ns/description/1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
|
2
|
+
|
3
|
+
<message name="hello">
|
4
|
+
<parameter name="return" mimetype="text/plain"/>
|
5
|
+
</message>
|
6
|
+
|
7
|
+
<resource>
|
8
|
+
<get in="*" out="hello"/>
|
9
|
+
<sse/>
|
10
|
+
</resource>
|
11
|
+
|
12
|
+
</description>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
4
|
+
<title>Sample of riddl serversent events support</title>
|
5
|
+
|
6
|
+
<script type="text/javascript">
|
7
|
+
function init() {
|
8
|
+
es = new EventSource('http://localhost:9292/');
|
9
|
+
es.onopen = function() {
|
10
|
+
output("onopen");
|
11
|
+
};
|
12
|
+
es.onmessage = function(e) {
|
13
|
+
output("onmessage: " + e.data);
|
14
|
+
};
|
15
|
+
es.onerror = function() {
|
16
|
+
output("onerror/onclose");
|
17
|
+
};
|
18
|
+
}
|
19
|
+
|
20
|
+
function onCloseClick() {
|
21
|
+
output("onclose");
|
22
|
+
es.close();
|
23
|
+
}
|
24
|
+
|
25
|
+
function output(str) {
|
26
|
+
var log = document.getElementById("log");
|
27
|
+
var escaped = str.replace(/&/, "&").replace(/</, "<").
|
28
|
+
replace(/>/, ">").replace(/"/, """); // "
|
29
|
+
log.innerHTML = escaped + "<br>" + log.innerHTML;
|
30
|
+
}
|
31
|
+
</script>
|
32
|
+
</head>
|
33
|
+
<body onload="init();">
|
34
|
+
<p>
|
35
|
+
Also try: curl -N -H "Accept:text/event-stream" http://localhost:9292/
|
36
|
+
</p>
|
37
|
+
<form onsubmit="onSubmit(); return false;">
|
38
|
+
<button onclick="onCloseClick(); return false;">close</button>
|
39
|
+
</form>
|
40
|
+
<div id="log"></div>
|
41
|
+
</body>
|
42
|
+
</html>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'pp'
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/server')
|
4
|
+
|
5
|
+
class Bar < Riddl::Implementation
|
6
|
+
def response
|
7
|
+
Riddl::Parameter::Complex.new("return","text/plain","hello world")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Echo < Riddl::SSEImplementation
|
12
|
+
def onopen
|
13
|
+
puts "Connection established"
|
14
|
+
Thread.new do
|
15
|
+
1.upto 10 do |i|
|
16
|
+
send("oasch #{i}")
|
17
|
+
sleep 1
|
18
|
+
end
|
19
|
+
close
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def onclose
|
24
|
+
puts "Connection closed"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Riddl::Server.new(File.dirname(__FILE__) + '/description.xml', :port => 9292) do
|
29
|
+
cross_site_xhr true
|
30
|
+
|
31
|
+
on resource do
|
32
|
+
run Bar if get '*'
|
33
|
+
run Echo if sse
|
34
|
+
end
|
35
|
+
end.loop!
|
@@ -1,30 +1,31 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require File.join(__dir__, '../../lib/ruby/riddl/client')
|
2
3
|
|
3
|
-
ep = Riddl::Client.interface('http://localhost:9292/',File.
|
4
|
+
ep = Riddl::Client.interface('http://localhost:9292/',File.join(__dir__,'/description.xml'))
|
4
5
|
|
5
6
|
test = ep.resource('/')
|
6
7
|
|
7
8
|
test.ws do |conn|
|
8
|
-
conn.
|
9
|
+
conn.on :open do
|
9
10
|
### called on connection
|
10
|
-
conn.
|
11
|
-
conn.
|
11
|
+
conn.send "Hello world"
|
12
|
+
conn.send "done"
|
12
13
|
end
|
13
14
|
|
14
|
-
conn.
|
15
|
+
conn.on :error do |e|
|
15
16
|
### called on error
|
16
17
|
puts "Got error: #{e}"
|
17
18
|
end
|
18
19
|
|
19
|
-
conn.
|
20
|
+
conn.on :message do |msg|
|
20
21
|
### called when server responds
|
21
|
-
puts "<#{msg}>"
|
22
|
+
puts "<#{msg.data}>"
|
22
23
|
if msg.data == "done"
|
23
|
-
conn.
|
24
|
+
conn.close
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
|
-
conn.
|
28
|
+
conn.on :close do
|
28
29
|
### called on disconnect
|
29
30
|
puts "gone"
|
30
31
|
EM::stop_event_loop
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<head>
|
3
3
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
4
4
|
<title>Sample of riddl websocket support</title>
|
5
|
-
|
5
|
+
|
6
6
|
<script type="text/javascript">
|
7
7
|
function init() {
|
8
8
|
var Socket = "MozWebSocket" in window ? MozWebSocket : WebSocket;
|
@@ -18,7 +18,7 @@
|
|
18
18
|
output("onclose");
|
19
19
|
};
|
20
20
|
}
|
21
|
-
|
21
|
+
|
22
22
|
function onSubmit() {
|
23
23
|
var input = document.getElementById("input");
|
24
24
|
// You can send message to the Web Socket using ws.send.
|
@@ -27,11 +27,11 @@
|
|
27
27
|
input.value = "";
|
28
28
|
input.focus();
|
29
29
|
}
|
30
|
-
|
30
|
+
|
31
31
|
function onCloseClick() {
|
32
32
|
ws.close();
|
33
33
|
}
|
34
|
-
|
34
|
+
|
35
35
|
function output(str) {
|
36
36
|
var log = document.getElementById("log");
|
37
37
|
var escaped = str.replace(/&/, "&").replace(/</, "<").
|
@@ -3,17 +3,21 @@ require 'pp'
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/server')
|
4
4
|
|
5
5
|
class Bar < Riddl::Implementation
|
6
|
-
def response
|
6
|
+
def response
|
7
7
|
Riddl::Parameter::Complex.new("return","text/plain","hello world")
|
8
|
-
end
|
8
|
+
end
|
9
9
|
end
|
10
10
|
|
11
|
-
$socket = []
|
12
|
-
|
13
11
|
class Echo < Riddl::WebSocketImplementation
|
14
12
|
def onopen
|
15
|
-
$socket << self
|
16
13
|
puts "Connection established"
|
14
|
+
Thread.new do
|
15
|
+
1.upto 10 do |i|
|
16
|
+
send("oasch #{i}")
|
17
|
+
sleep 1
|
18
|
+
end
|
19
|
+
close
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
def onmessage(data)
|
@@ -23,22 +27,10 @@ class Echo < Riddl::WebSocketImplementation
|
|
23
27
|
end
|
24
28
|
|
25
29
|
def onclose
|
26
|
-
$socket.delete(self)
|
27
30
|
puts "Connection closed"
|
28
31
|
end
|
29
32
|
end
|
30
33
|
|
31
|
-
Thread.new do
|
32
|
-
i = 1
|
33
|
-
while true
|
34
|
-
$socket.each do |sock|
|
35
|
-
sock.send("oasch #{i}")
|
36
|
-
end
|
37
|
-
i+=1
|
38
|
-
sleep 2
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
34
|
Riddl::Server.new(File.dirname(__FILE__) + '/description.xml', :port => 9292) do
|
43
35
|
cross_site_xhr true
|
44
36
|
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../../ns/common-patterns/properties/1.0/properties.xml
|
@@ -25,6 +25,42 @@ module Riddl
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
class SSEImplementation
|
29
|
+
def initialize(ws)
|
30
|
+
@ws = ws
|
31
|
+
@r = ws[:r] # the matching resource path
|
32
|
+
@s = ws[:s] # the matching resource path schema
|
33
|
+
@match = ws[:match] # the path of the branch matching, important for recursive
|
34
|
+
@env = ws[:env] # environment (all headers)
|
35
|
+
@a = ws[:a] # args to run command
|
36
|
+
end
|
37
|
+
|
38
|
+
def onopen;end
|
39
|
+
def onclose;end
|
40
|
+
def onerror(err);end
|
41
|
+
|
42
|
+
def send(data)
|
43
|
+
self.io.send_with_id 'data', data
|
44
|
+
end
|
45
|
+
def send_with_id(id,data)
|
46
|
+
self.io.send_with_id id, data
|
47
|
+
end
|
48
|
+
|
49
|
+
def io=(connection)
|
50
|
+
@ws[:io] = connection
|
51
|
+
end
|
52
|
+
def io
|
53
|
+
@ws[:io]
|
54
|
+
end
|
55
|
+
def closed?
|
56
|
+
@ws[:io].closed?
|
57
|
+
end
|
58
|
+
|
59
|
+
def close
|
60
|
+
@ws[:io].close
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
28
64
|
class WebSocketImplementation
|
29
65
|
def initialize(ws)
|
30
66
|
@ws = ws
|
@@ -52,10 +88,10 @@ module Riddl
|
|
52
88
|
end
|
53
89
|
def closed?
|
54
90
|
@ws[:io].closed?
|
55
|
-
end
|
91
|
+
end
|
56
92
|
|
57
93
|
def close
|
58
|
-
|
94
|
+
@ws[:io].close_connection
|
59
95
|
end
|
60
96
|
end
|
61
97
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Riddl
|
2
|
+
module Protocols
|
3
|
+
class SSE
|
4
|
+
class Error < RuntimeError; end
|
5
|
+
|
6
|
+
class ParserData
|
7
|
+
attr_accessor :headers, :request_path, :query_string, :http_method, :body, :request_url
|
8
|
+
end
|
9
|
+
|
10
|
+
class DeferrableBody
|
11
|
+
include EventMachine::Deferrable
|
12
|
+
|
13
|
+
def call(body)
|
14
|
+
body.each do |chunk|
|
15
|
+
@body_callback.call(chunk)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def each(&blk)
|
20
|
+
@body_callback = blk
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def send_with_id(id, data)
|
25
|
+
EM.next_tick do
|
26
|
+
@body.call [ "#{id}: #{data}" + EOL + EOL ]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def close
|
31
|
+
EM.next_tick do
|
32
|
+
@body.succeed
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def trigger_on_open(); @closed = false; @app.onopen; end
|
37
|
+
def trigger_on_close; @closed = true; @app.onclose; end
|
38
|
+
|
39
|
+
def initialize(app, env)
|
40
|
+
@app = app
|
41
|
+
@env = env
|
42
|
+
@env['async.close'].callback { trigger_on_close }
|
43
|
+
@body = DeferrableBody.new
|
44
|
+
@closed = true
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def dispatch(data,cross_site_xhr)
|
49
|
+
headers = {
|
50
|
+
'Content-Type' => 'text/event-stream',
|
51
|
+
'Cache-Control' => 'no-cache'
|
52
|
+
}
|
53
|
+
if @env['HTTP_ORIGIN'] && cross_site_xhr
|
54
|
+
headers['Access-Control-Allow-Origin'] = '*'
|
55
|
+
headers['Access-Control-Max-Age'] = '0'
|
56
|
+
end
|
57
|
+
EventMachine::next_tick {
|
58
|
+
@env['async.callback'].call [200, headers, @body]
|
59
|
+
trigger_on_open
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def closed?
|
64
|
+
@closed
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -48,8 +48,8 @@ module EventMachine
|
|
48
48
|
process(@headers, data.body)
|
49
49
|
end
|
50
50
|
end
|
51
|
-
end
|
52
|
-
end
|
51
|
+
end
|
52
|
+
end
|
53
53
|
|
54
54
|
module Riddl
|
55
55
|
module Protocols
|
@@ -59,7 +59,7 @@ module Riddl
|
|
59
59
|
class ParserData
|
60
60
|
attr_accessor :headers, :request_path, :query_string, :http_method, :body, :request_url
|
61
61
|
def match(what)
|
62
|
-
@body =~ what
|
62
|
+
@body =~ what
|
63
63
|
end
|
64
64
|
def upgrade?
|
65
65
|
true
|
@@ -72,17 +72,19 @@ module Riddl
|
|
72
72
|
instance
|
73
73
|
end
|
74
74
|
|
75
|
-
def send_data(
|
75
|
+
def send_data(data)
|
76
76
|
EM.next_tick do
|
77
|
-
@socket.send_data(
|
78
|
-
end
|
77
|
+
@socket.send_data(data) unless closed?
|
78
|
+
end
|
79
79
|
end
|
80
80
|
|
81
81
|
def close_connection(*args)
|
82
82
|
EM.next_tick do
|
83
|
-
|
84
|
-
|
85
|
-
|
83
|
+
unless closed?
|
84
|
+
@socket.close_connection(*args)
|
85
|
+
trigger_on_close
|
86
|
+
end
|
87
|
+
end
|
86
88
|
end
|
87
89
|
|
88
90
|
def trigger_on_message(msg); @app.onmessage(msg); end
|
data/lib/ruby/riddl/server.rb
CHANGED
@@ -4,6 +4,7 @@ require File.expand_path(File.dirname(__FILE__) + '/protocols/http/parser')
|
|
4
4
|
require File.expand_path(File.dirname(__FILE__) + '/protocols/http/generator')
|
5
5
|
require File.expand_path(File.dirname(__FILE__) + '/protocols/utils')
|
6
6
|
require File.expand_path(File.dirname(__FILE__) + '/protocols/websocket')
|
7
|
+
require File.expand_path(File.dirname(__FILE__) + '/protocols/sse')
|
7
8
|
require File.expand_path(File.dirname(__FILE__) + '/header')
|
8
9
|
require File.expand_path(File.dirname(__FILE__) + '/parameter')
|
9
10
|
require File.expand_path(File.dirname(__FILE__) + '/error')
|
@@ -246,7 +247,7 @@ module Riddl
|
|
246
247
|
:match => []
|
247
248
|
}
|
248
249
|
|
249
|
-
if @riddl_info[:env][
|
250
|
+
if @riddl_info[:env]['HTTP_CONNECTION'] =~ /Upgrade/ && @riddl_info[:env]['HTTP_UPGRADE'] =~ /\AWebSocket\z/i
|
250
251
|
# TODO raise error when declaration and route or (not route and non-local interface)
|
251
252
|
# raise SpecificationError, 'RIDDL description does not conform to specification' unless @riddl.validate!
|
252
253
|
@riddl_info[:m] = @riddl_method = 'websocket'
|
@@ -267,6 +268,25 @@ module Riddl
|
|
267
268
|
end
|
268
269
|
end
|
269
270
|
throw :async
|
271
|
+
elsif @riddl_info[:env]['HTTP_ACCEPT'] == 'text/event-stream'
|
272
|
+
@riddl_info[:m] = @riddl_method = 'sse'
|
273
|
+
@riddl_message = @riddl.io_messages(@riddl_matching_path[0],'sse',@riddl_parameters,@riddl_headers)
|
274
|
+
if @riddl.description?
|
275
|
+
instance_exec(@riddl_info, &@riddl_interfaces[nil])
|
276
|
+
elsif @riddl.declaration?
|
277
|
+
# one ws connection, no overlay
|
278
|
+
unless @riddl_message.nil?
|
279
|
+
if @riddl_interfaces.key? @riddl_message.interface.name
|
280
|
+
@riddl_info[:r] = @riddl_message.interface.real_path(@riddl_pinfo).sub(/^\//,'').split('/')
|
281
|
+
@riddl_info[:h]['RIDDL_DECLARATION_PATH'] = @riddl_pinfo
|
282
|
+
@riddl_info[:h]['RIDDL_DECLARATION_RESOURCE'] = @riddl_message.interface.top
|
283
|
+
@riddl_info[:s] = @riddl_message.interface.sub.sub(/\//,'').split('/')
|
284
|
+
@riddl_info.merge!(:match => matching_path)
|
285
|
+
instance_exec(@riddl_info, &@riddl_interfaces[@riddl_message.interface.name])
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
throw :async
|
270
290
|
else
|
271
291
|
__call
|
272
292
|
end
|
@@ -321,6 +341,20 @@ module Riddl
|
|
321
341
|
|
322
342
|
def run(what,*args)# {{{
|
323
343
|
return if @riddl_path == ''
|
344
|
+
if what.class == Class && what.superclass == Riddl::SSEImplementation
|
345
|
+
data = Riddl::Protocols::SSE::ParserData.new
|
346
|
+
data.request_path = @riddl_pinfo
|
347
|
+
data.request_url = @riddl_pinfo + '?' + @riddl_query_string
|
348
|
+
data.query_string = @riddl_query_string
|
349
|
+
data.http_method = @riddl_env['REQUEST_METHOD']
|
350
|
+
data.body = @riddl_env['rack.input'].read
|
351
|
+
data.headers = Hash[
|
352
|
+
@riddl_headers.map { |key, value| [key.downcase.gsub('_','-'), value] }
|
353
|
+
]
|
354
|
+
w = what.new(@riddl_info.merge!(:a => args, :match => matching_path))
|
355
|
+
w.io = Riddl::Protocols::SSE.new(w, @riddl_env)
|
356
|
+
w.io.dispatch(data, @riddl_cross_site_xhr)
|
357
|
+
end
|
324
358
|
if what.class == Class && what.superclass == Riddl::WebSocketImplementation
|
325
359
|
data = Riddl::Protocols::WebSocket::ParserData.new
|
326
360
|
data.request_path = @riddl_pinfo
|
@@ -363,6 +397,7 @@ module Riddl
|
|
363
397
|
def put(min='*'); return false if @riddl_message.nil?; @riddl_path == '/' + @riddl_info[:s].join('/') && @riddl_message.in && min == @riddl_message.in.name && @riddl_method == 'put' end
|
364
398
|
def patch(min='*'); return false if @riddl_message.nil?; @riddl_path == '/' + @riddl_info[:s].join('/') && @riddl_message.in && min == @riddl_message.in.name && @riddl_method == 'patch' end
|
365
399
|
def websocket; return false if @riddl_message.nil?; @riddl_path == '/' + @riddl_info[:s].join('/') && @riddl_method == 'websocket' end
|
400
|
+
def sse; return false if @riddl_message.nil?; @riddl_path == '/' + @riddl_info[:s].join('/') && @riddl_method == 'sse' end
|
366
401
|
def resource(rname=nil); return rname.nil? ? '{}' : rname end
|
367
402
|
|
368
403
|
def matching_path #{{{
|
data/lib/ruby/riddl/wrapper.rb
CHANGED
@@ -194,6 +194,9 @@ module Riddl
|
|
194
194
|
r.select{|o|o.class==Riddl::Wrapper::Description::WebSocket}.each do |o|
|
195
195
|
return IOMessages.new(nil,nil,nil,nil)
|
196
196
|
end
|
197
|
+
r.select{|o|o.class==Riddl::Wrapper::Description::SSE}.each do |o|
|
198
|
+
return IOMessages.new(nil,nil,nil,nil)
|
199
|
+
end
|
197
200
|
end
|
198
201
|
if @is_declaration
|
199
202
|
r = req[operation]
|
@@ -213,6 +216,9 @@ module Riddl
|
|
213
216
|
r.select{|o|o.result.class==Riddl::Wrapper::Description::WebSocket}.each do |o|
|
214
217
|
return IOMessages.new(nil,nil,nil,o.result.interface)
|
215
218
|
end
|
219
|
+
r.select{|o|o.result.class==Riddl::Wrapper::Description::SSE}.each do |o|
|
220
|
+
return IOMessages.new(nil,nil,nil,o.result.interface)
|
221
|
+
end
|
216
222
|
end
|
217
223
|
end
|
218
224
|
return nil
|
@@ -110,6 +110,17 @@ module Riddl
|
|
110
110
|
end
|
111
111
|
end# }}}
|
112
112
|
|
113
|
+
class SSE < AccessBase# {{{
|
114
|
+
def initialize(interface,custom=[])
|
115
|
+
@custom = custom
|
116
|
+
@interface = interface
|
117
|
+
end
|
118
|
+
def visualize; ""; end
|
119
|
+
def hash
|
120
|
+
0
|
121
|
+
end
|
122
|
+
end# }}}
|
123
|
+
|
113
124
|
end
|
114
125
|
end
|
115
126
|
end
|
@@ -17,33 +17,36 @@ module Riddl
|
|
17
17
|
|
18
18
|
def add_access_methods(des,desres,index,interface)
|
19
19
|
#{{{
|
20
|
-
desres.find("des:*[not(name()='resource') and not(name()='websocket') and @in and not(@in='*')]").each do |m|
|
20
|
+
desres.find("des:*[not(name()='resource') and not(name()='websocket') and not(name()='sse') and @in and not(@in='*')]").each do |m|
|
21
21
|
method = m.attributes['method'] || m.qname.name
|
22
22
|
add_request_in_out(index,interface,des,method,m.attributes['in'],m.attributes['out'],m.find('*|text()'))
|
23
23
|
end
|
24
|
-
desres.find("des:*[not(name()='resource') and not(name()='websocket') and @pass and not(@pass='*')]").each do |m|
|
24
|
+
desres.find("des:*[not(name()='resource') and not(name()='websocket') and not(name()='sse') and @pass and not(@pass='*')]").each do |m|
|
25
25
|
method = m.attributes['method'] || m.qname.name
|
26
26
|
add_request_in_out(index,interface,des,method,m.attributes['pass'],m.attributes['pass'],m.find('*|text()'))
|
27
27
|
end
|
28
|
-
desres.find("des:*[not(name()='resource') and not(name()='websocket') and @transformation]").each do |m|
|
28
|
+
desres.find("des:*[not(name()='resource') and not(name()='websocket') and not(name()='sse') and @transformation]").each do |m|
|
29
29
|
method = m.attributes['method'] || m.qname.name
|
30
30
|
add_request_transform(index,interface,des,method,m.attributes['transformation'],m.find('*|text()'))
|
31
31
|
end
|
32
|
-
desres.find("des:*[not(name()='resource') and not(name()='websocket') and @in and @in='*']").each do |m|
|
32
|
+
desres.find("des:*[not(name()='resource') and not(name()='websocket') and not(name()='sse') and @in and @in='*']").each do |m|
|
33
33
|
method = m.attributes['method'] || m.qname.name
|
34
34
|
add_request_star_out(index,interface,des,method,m.attributes['out'],m.find('*|text()'))
|
35
35
|
end
|
36
|
-
desres.find("des:*[not(name()='resource') and not(name()='websocket') and not(@in) and not(@pass)]").each do |m|
|
36
|
+
desres.find("des:*[not(name()='resource') and not(name()='websocket') and not(name()='sse') and not(@in) and not(@pass)]").each do |m|
|
37
37
|
method = m.attributes['method'] || m.qname.name
|
38
38
|
add_request_star_out(index,interface,des,method,m.attributes['out'],m.find('*|text()'))
|
39
39
|
end
|
40
|
-
desres.find("des:*[not(name()='resource') and not(name()='websocket') and @pass and @pass='*']").each do |m|
|
40
|
+
desres.find("des:*[not(name()='resource') and not(name()='websocket') and not(name()='sse') and @pass and @pass='*']").each do |m|
|
41
41
|
method = m.attributes['method'] || m.qname.name
|
42
42
|
add_request_pass(index,interface,method,m.find('*|text()'))
|
43
43
|
end
|
44
|
-
desres.find("des:*[
|
44
|
+
desres.find("des:*[name()='websocket']").each do |m|
|
45
45
|
add_websocket(index,interface,m.find('*|text()'))
|
46
46
|
end
|
47
|
+
desres.find("des:*[name()='sse']").each do |m|
|
48
|
+
add_sse(index,interface,m.find('*|text()'))
|
49
|
+
end
|
47
50
|
@role = desres.find("string(@role)")
|
48
51
|
@role = nil if @role.strip == ''
|
49
52
|
#}}}
|
@@ -56,6 +59,7 @@ module Riddl
|
|
56
59
|
end
|
57
60
|
|
58
61
|
# TODO add websockets
|
62
|
+
# TODO add SSE
|
59
63
|
|
60
64
|
def remove_access_methods(des,filter,index)
|
61
65
|
#{{{
|
@@ -246,7 +250,7 @@ module Riddl
|
|
246
250
|
def description_xml_string_analyse(messages,t,k,m)
|
247
251
|
#{{{
|
248
252
|
result = ''
|
249
|
-
if %w{get post put patch delete websocket}.include?(k)
|
253
|
+
if %w{get post put patch delete websocket sse}.include?(k)
|
250
254
|
result << t + "<#{k} "
|
251
255
|
else
|
252
256
|
result << t + "<request method=\"#{k}\" "
|
@@ -276,7 +280,7 @@ module Riddl
|
|
276
280
|
m.custom.each do |e|
|
277
281
|
result << e.dump + "\n"
|
278
282
|
end
|
279
|
-
if %w{get post put patch delete websocket}.include?(k)
|
283
|
+
if %w{get post put patch delete websocket sse}.include?(k)
|
280
284
|
result << t + "</#{k}>"
|
281
285
|
else
|
282
286
|
result << t + "</request>\n"
|
@@ -387,7 +391,14 @@ module Riddl
|
|
387
391
|
@access_methods['websocket'][index] ||= []
|
388
392
|
@access_methods['websocket'][index] << WebSocket.new(interface,custom)
|
389
393
|
end
|
390
|
-
private :
|
394
|
+
private :add_websocket
|
395
|
+
|
396
|
+
def add_sse(index,interface,custom)
|
397
|
+
@access_methods['sse'] ||= []
|
398
|
+
@access_methods['sse'][index] ||= []
|
399
|
+
@access_methods['sse'][index] << SSE.new(interface,custom)
|
400
|
+
end
|
401
|
+
private :add_sse
|
391
402
|
#}}}
|
392
403
|
|
393
404
|
attr_reader :resources,:path,:access_methods,:composition,:recursive,:role
|
data/riddl.gemspec
CHANGED
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: 0.100.
|
4
|
+
version: 0.100.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Juergen 'eTM' Mangler
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: tools
|
12
12
|
cert_chain: []
|
13
|
-
date: 2019-
|
13
|
+
date: 2019-11-14 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: daemonite
|
@@ -44,42 +44,42 @@ dependencies:
|
|
44
44
|
name: xml-smart
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- - ">="
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: 0.3.6
|
50
47
|
- - "~>"
|
51
48
|
- !ruby/object:Gem::Version
|
52
49
|
version: '0'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.3.6
|
53
53
|
type: :runtime
|
54
54
|
prerelease: false
|
55
55
|
version_requirements: !ruby/object:Gem::Requirement
|
56
56
|
requirements:
|
57
|
-
- - ">="
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version: 0.3.6
|
60
57
|
- - "~>"
|
61
58
|
- !ruby/object:Gem::Version
|
62
59
|
version: '0'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.3.6
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
64
|
name: rdf-smart
|
65
65
|
requirement: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- - ">="
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: 0.0.160
|
70
67
|
- - "~>"
|
71
68
|
- !ruby/object:Gem::Version
|
72
69
|
version: '0'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 0.0.160
|
73
73
|
type: :runtime
|
74
74
|
prerelease: false
|
75
75
|
version_requirements: !ruby/object:Gem::Requirement
|
76
76
|
requirements:
|
77
|
-
- - ">="
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
version: 0.0.160
|
80
77
|
- - "~>"
|
81
78
|
- !ruby/object:Gem::Version
|
82
79
|
version: '0'
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.0.160
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rack
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -132,62 +132,62 @@ dependencies:
|
|
132
132
|
name: em-websocket
|
133
133
|
requirement: !ruby/object:Gem::Requirement
|
134
134
|
requirements:
|
135
|
-
- - ">="
|
136
|
-
- !ruby/object:Gem::Version
|
137
|
-
version: 0.4.0
|
138
135
|
- - "~>"
|
139
136
|
- !ruby/object:Gem::Version
|
140
137
|
version: '0'
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: 0.4.0
|
141
141
|
type: :runtime
|
142
142
|
prerelease: false
|
143
143
|
version_requirements: !ruby/object:Gem::Requirement
|
144
144
|
requirements:
|
145
|
-
- - ">="
|
146
|
-
- !ruby/object:Gem::Version
|
147
|
-
version: 0.4.0
|
148
145
|
- - "~>"
|
149
146
|
- !ruby/object:Gem::Version
|
150
147
|
version: '0'
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: 0.4.0
|
151
151
|
- !ruby/object:Gem::Dependency
|
152
152
|
name: faye-websocket
|
153
153
|
requirement: !ruby/object:Gem::Requirement
|
154
154
|
requirements:
|
155
|
-
- - ">="
|
156
|
-
- !ruby/object:Gem::Version
|
157
|
-
version: '0.1'
|
158
155
|
- - "~>"
|
159
156
|
- !ruby/object:Gem::Version
|
160
157
|
version: '0'
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0.1'
|
161
161
|
type: :runtime
|
162
162
|
prerelease: false
|
163
163
|
version_requirements: !ruby/object:Gem::Requirement
|
164
164
|
requirements:
|
165
|
-
- - ">="
|
166
|
-
- !ruby/object:Gem::Version
|
167
|
-
version: '0.1'
|
168
165
|
- - "~>"
|
169
166
|
- !ruby/object:Gem::Version
|
170
167
|
version: '0'
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0.1'
|
171
171
|
- !ruby/object:Gem::Dependency
|
172
172
|
name: mime-types
|
173
173
|
requirement: !ruby/object:Gem::Requirement
|
174
174
|
requirements:
|
175
|
-
- - ">="
|
176
|
-
- !ruby/object:Gem::Version
|
177
|
-
version: '2.4'
|
178
175
|
- - "~>"
|
179
176
|
- !ruby/object:Gem::Version
|
180
177
|
version: '2'
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '2.4'
|
181
181
|
type: :runtime
|
182
182
|
prerelease: false
|
183
183
|
version_requirements: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
|
-
- - ">="
|
186
|
-
- !ruby/object:Gem::Version
|
187
|
-
version: '2.4'
|
188
185
|
- - "~>"
|
189
186
|
- !ruby/object:Gem::Version
|
190
187
|
version: '2'
|
188
|
+
- - ">="
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: '2.4'
|
191
191
|
- !ruby/object:Gem::Dependency
|
192
192
|
name: minitest
|
193
193
|
requirement: !ruby/object:Gem::Requirement
|
@@ -212,22 +212,22 @@ dependencies:
|
|
212
212
|
name: charlock_holmes
|
213
213
|
requirement: !ruby/object:Gem::Requirement
|
214
214
|
requirements:
|
215
|
-
- - ">="
|
216
|
-
- !ruby/object:Gem::Version
|
217
|
-
version: '0.7'
|
218
215
|
- - "~>"
|
219
216
|
- !ruby/object:Gem::Version
|
220
217
|
version: '0'
|
218
|
+
- - ">="
|
219
|
+
- !ruby/object:Gem::Version
|
220
|
+
version: '0.7'
|
221
221
|
type: :runtime
|
222
222
|
prerelease: false
|
223
223
|
version_requirements: !ruby/object:Gem::Requirement
|
224
224
|
requirements:
|
225
|
-
- - ">="
|
226
|
-
- !ruby/object:Gem::Version
|
227
|
-
version: '0.7'
|
228
225
|
- - "~>"
|
229
226
|
- !ruby/object:Gem::Version
|
230
227
|
version: '0'
|
228
|
+
- - ">="
|
229
|
+
- !ruby/object:Gem::Version
|
230
|
+
version: '0.7'
|
231
231
|
- !ruby/object:Gem::Dependency
|
232
232
|
name: redis
|
233
233
|
requirement: !ruby/object:Gem::Requirement
|
@@ -399,6 +399,9 @@ files:
|
|
399
399
|
- examples/propnew/server.properties.schema
|
400
400
|
- examples/propnew/server.properties.xml
|
401
401
|
- examples/propnew/test
|
402
|
+
- examples/sse/description.xml
|
403
|
+
- examples/sse/sample.html
|
404
|
+
- examples/sse/server.rb
|
402
405
|
- examples/twitter/README
|
403
406
|
- examples/twitter/client.rb
|
404
407
|
- examples/twitter/declaration.xml
|
@@ -458,6 +461,7 @@ files:
|
|
458
461
|
- lib/ruby/riddl/parameter.rb
|
459
462
|
- lib/ruby/riddl/protocols/http/generator.rb
|
460
463
|
- lib/ruby/riddl/protocols/http/parser.rb
|
464
|
+
- lib/ruby/riddl/protocols/sse.rb
|
461
465
|
- lib/ruby/riddl/protocols/utils.rb
|
462
466
|
- lib/ruby/riddl/protocols/websocket.rb
|
463
467
|
- lib/ruby/riddl/roles.rb
|
@@ -544,8 +548,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
544
548
|
- !ruby/object:Gem::Version
|
545
549
|
version: '0'
|
546
550
|
requirements: []
|
547
|
-
|
548
|
-
rubygems_version: 2.7.6
|
551
|
+
rubygems_version: 3.0.3
|
549
552
|
signing_key:
|
550
553
|
specification_version: 4
|
551
554
|
summary: 'restful interface description and declaration language: tools and client/server
|