riddl 0.125 → 0.127

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 260b0959b5e3cd03e5346a8e6002e6e7ab35ac81a90c099fabed18667b724f51
4
- data.tar.gz: 163523a732236a6e81fce5976437e2e7610f2a3fd171e2425b7eac36e7f6fe32
3
+ metadata.gz: '0695959f6c714b4aca4c11debdcd59d22fefbbe6c11f69400c2b0ebd252d43fc'
4
+ data.tar.gz: cabfaef2d61eb9cd5010af81f891684dce71f761255e65531ef146362b6b884a
5
5
  SHA512:
6
- metadata.gz: e6a4e14075147239fd64cf140c2d5feb563c2076ac7ffe2fd3d799ac7d66c58e44bcb3945a676a5e04d255e23c0c4a4bcd86283a88ae9292c3a3e938a1de0d45
7
- data.tar.gz: 89f7414265c9764de654494b43b736a234a62663abd01ec88ef1bf7e26dcbdb3a7a7c3399360c105930097ff08b21491f1acec58fd9aa0144e381856691dd4ee
6
+ metadata.gz: 5d53d1d0a1aba73908811c361dfeed70e79dcec182b5c6c20863e9c1d9e7c5886c022d78dc4f97277c7519cf155a7abbb136a2b79852e64830151b73b53bf6ff
7
+ data.tar.gz: 442afaa166e57b02f1d29a262e693c3a5f7843e56fdbe98fe8c77f4087b94c31f58876a5a53eb83565a385e473b1b0263bc4e4a8f936896c1435fa6e0a788cee
@@ -0,0 +1,118 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../constants')
2
+ require File.expand_path(File.dirname(__FILE__) + '/../utils')
3
+ require 'stringio'
4
+
5
+ module Riddl
6
+ module Protocols
7
+ module HTTP
8
+ class Generator
9
+ def initialize(params,headers)
10
+ @params = params
11
+ @headers = headers
12
+ end
13
+
14
+ def generate(mode=:output)
15
+ if @params.is_a?(Array) && @params.length == 1
16
+ body(@params[0],mode)
17
+ elsif @params.class == Riddl::Parameter::Simple || @params.class == Riddl::Parameter::Complex
18
+ body(@params,mode)
19
+ elsif @params.is_a?(Array) && @params.length > 1
20
+ multipart(mode)
21
+ else
22
+ if mode == :output
23
+ @headers['Content-Type'] = 'text/plain'
24
+ StringIO.new('','r+b')
25
+ else
26
+ StringIO.new('','r+b')
27
+ end
28
+ end
29
+ end
30
+
31
+ def body(r,mode)
32
+ tmp = StringIO.new('','r+b')
33
+ case r
34
+ when Riddl::Parameter::Simple
35
+ if mode == :output
36
+ tmp.write r.value
37
+ @headers['Content-Type'] = 'text/plain'
38
+ @headers['Content-ID'] = r.name
39
+ @headers['RIDDL-TYPE'] = 'simple'
40
+ end
41
+ if mode == :input
42
+ @headers['Content-Type'] = 'application/x-www-form-urlencoded'
43
+ tmp.write Riddl::Protocols::Utils::escape(r.name) + '=' + Riddl::Protocols::Utils::escape(r.value)
44
+ end
45
+ when Riddl::Parameter::Complex
46
+ tmp.write(r.value.respond_to?(:read) ? r.value.read : r.value)
47
+ @headers['Content-Type'] = r.mimetype + r.mimextra
48
+ @headers['RIDDL-TYPE'] = 'complex'
49
+ if r.filename.nil?
50
+ @headers['Content-ID'] = r.name
51
+ else
52
+ @headers['Content-Disposition'] = "riddl-data; name=\"#{r.name}\"; filename=\"#{r.filename}\""
53
+ end
54
+ end
55
+ tmp.flush
56
+ tmp.rewind
57
+ tmp
58
+ end
59
+ private :body
60
+
61
+ def multipart(mode)
62
+ tmp = StringIO.new('','r+b')
63
+ scount = ccount = 0
64
+ @params.each do |r|
65
+ case r
66
+ when Riddl::Parameter::Simple
67
+ scount += 1
68
+ when Riddl::Parameter::Complex
69
+ ccount += 1
70
+ end
71
+ end
72
+ if scount > 0 && ccount == 0
73
+ @headers['Content-Type'] = 'application/x-www-form-urlencoded'
74
+ res = []
75
+ @params.each do |r|
76
+ case r
77
+ when Riddl::Parameter::Simple
78
+ res << Riddl::Protocols::Utils::escape(r.name) + '=' + Riddl::Protocols::Utils::escape(r.value)
79
+ end
80
+ end
81
+ tmp.write res.join('&')
82
+ else
83
+ if scount + ccount > 0
84
+ @headers['Content-Type'] = "multipart/#{mode == :input ? 'form-data' : 'mixed'}; boundary=\"#{BOUNDARY}\""
85
+ @params.each do |r|
86
+ case r
87
+ when Riddl::Parameter::Simple
88
+ tmp.write '--' + BOUNDARY + EOL
89
+ tmp.write 'RIDDL-TYPE: simple' + EOL
90
+ tmp.write "Content-Disposition: #{mode == :input ? 'form-data' : 'riddl-data'}; name=\"#{r.name}\"" + EOL
91
+ tmp.write EOL
92
+ tmp.write r.value
93
+ tmp.write EOL
94
+ when Riddl::Parameter::Complex
95
+ tmp.write '--' + BOUNDARY + EOL
96
+ tmp.write 'RIDDL-TYPE: complex' + EOL
97
+ tmp.write "Content-Disposition: #{mode == :input ? 'form-data' : 'riddl-data'}; name=\"#{r.name}\""
98
+ tmp.write r.filename.nil? ? '; filename=""' + EOL : "; filename=\"#{r.filename}\"" + EOL
99
+ tmp.write 'Content-Transfer-Encoding: binary' + EOL
100
+ tmp.write 'Content-Type: ' + r.mimetype + r.mimextra + EOL
101
+ tmp.write EOL
102
+ tmp.write(r.value.respond_to?(:read) ? r.value.read : r.value)
103
+ tmp.write EOL
104
+ end
105
+ end
106
+ tmp.write '--' + BOUNDARY + EOL
107
+ end
108
+ end
109
+ tmp.flush
110
+ tmp.rewind
111
+ tmp
112
+ end
113
+ private :multipart
114
+
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,205 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../constants')
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../parameter')
3
+ require File.expand_path(File.dirname(__FILE__) + '/../utils')
4
+
5
+ module Riddl
6
+ module Protocols
7
+ module HTTP
8
+ class Parser
9
+ MULTIPART_CONTENT_TYPES = [
10
+ #{{{
11
+ 'multipart/form-data',
12
+ 'multipart/related',
13
+ 'multipart/mixed'
14
+ #}}}
15
+ ].freeze
16
+ FORM_CONTENT_TYPES = [
17
+ #{{{
18
+ 'application/x-www-form-urlencoded'
19
+ #}}}
20
+ ].freeze
21
+
22
+ def parse_content(input,ctype,content_length,content_disposition,content_id,riddl_type)
23
+ #{{{
24
+ # fixing for chunked?
25
+
26
+ ctype = nil if riddl_type == 'simple'
27
+ filename = content_disposition[/ filename="?([^\";]*)"?/ni, 1]
28
+ name = content_disposition[/ name="?([^\";]*)"?/ni, 1] || content_id
29
+
30
+ if ctype || filename
31
+ body = Parameter::Tempfile.new("RiddlMultipart")
32
+ body.binmode if body.respond_to?(:binmode)
33
+ else
34
+ body = ''
35
+ end
36
+
37
+ if content_length == 0
38
+ bufsize = 16384
39
+ until input.eof?
40
+ c = input.read(bufsize)
41
+ raise EOFError, "bad content body" if c.nil? || c.empty?
42
+ body << c
43
+ content_length -= c.size
44
+ end
45
+ body << input.read
46
+ else
47
+ bufsize = 16384
48
+ until content_length <= 0
49
+ c = input.read(bufsize < content_length ? bufsize : content_length)
50
+ raise EOFError, "bad content body" if c.nil? || c.empty?
51
+ body << c
52
+ content_length -= c.size
53
+ end
54
+ end
55
+ body.rewind if body.respond_to?(:binmode)
56
+
57
+ add_to_params(name,body,filename,ctype,nil) if body.length > 0
58
+ #}}}
59
+ end
60
+ private :parse_content
61
+
62
+ def parse_multipart(input,content_type,content_length)
63
+ #{{{
64
+ content_type =~ %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|n
65
+ boundary = "--#{$1}"
66
+
67
+ boundary_size = boundary.size + EOL.size
68
+ content_length -= boundary_size
69
+ status = input.read(boundary_size)
70
+ raise EOFError, "bad content body" unless status == boundary + EOL
71
+
72
+ rx = /(?:#{EOL})?#{Regexp.quote boundary}(#{EOL}|--)/n
73
+
74
+ buf = ""
75
+ bufsize = 16384
76
+ loop do
77
+ head = nil
78
+ body = ''
79
+ filename = ctype = name = nil
80
+
81
+ until head && buf =~ rx
82
+ if !head && i = buf.index(EOL+EOL)
83
+ head = buf.slice!(0, i+2) # First \r\n
84
+ buf.slice!(0, 2) # Second \r\n
85
+
86
+ filename = head[/Content-Disposition:.* filename="?([^\";]*)"?/ni, 1]
87
+ ctype = head[/Content-Type: (.*)#{EOL}/ni, 1]
88
+ name = head[/Content-Disposition:.*\s+name="?([^\";]*)"?/ni, 1] || head[/Content-ID:\s*([^#{EOL}]*)/ni, 1]
89
+
90
+ if ctype || filename
91
+ body = Parameter::Tempfile.new("RiddlMultipart")
92
+ body.binmode if body.respond_to?(:binmode)
93
+ end
94
+
95
+ next
96
+ end
97
+
98
+ # Save the read body part.
99
+ if head && (boundary_size+4 < buf.size)
100
+ body << buf.slice!(0, buf.size - (boundary_size+4))
101
+ end
102
+
103
+ c = input.read(bufsize < content_length ? bufsize : content_length)
104
+ raise EOFError, "bad content body" if c.nil? || c.empty?
105
+ content_length -= c.size
106
+
107
+ buf << c
108
+ end
109
+
110
+ # Save the rest.
111
+ if i = buf.index(rx)
112
+ body << buf.slice!(0, i)
113
+ buf.slice!(0, boundary_size+2)
114
+ content_length = -1 if $1 == "--"
115
+ end
116
+
117
+ p name
118
+ p body
119
+ p filename
120
+ p ctype
121
+ p head
122
+ p '----'
123
+
124
+ add_to_params(name,body,filename == '' ? nil : filename,ctype,head)
125
+
126
+ break if buf.empty? || content_length == -1
127
+ end
128
+ #}}}
129
+ end
130
+ private :parse_multipart
131
+
132
+ def add_to_params(name,body,filename,ctype,head)
133
+ #{{{
134
+ if filename == ""
135
+ # filename is blank which means no file has been selected
136
+ elsif filename && ctype
137
+ body.rewind
138
+
139
+ # Take the basename of the upload's original filename.
140
+ # This handles the full Windows paths given by Internet Explorer
141
+ # (and perhaps other broken user agents) without affecting
142
+ # those which give the lone filename.
143
+ filename =~ /^(?:.*[:\\\/])?(.*)/m
144
+ filename = $1
145
+
146
+ @params << Parameter::Complex.new(name, ctype, body, filename, head)
147
+ elsif !filename && ctype
148
+ body.rewind
149
+
150
+ # Generic multipart cases, not coming from a form
151
+ @params << Parameter::Complex.new(name, ctype, body, nil, head)
152
+ else
153
+ @params << Parameter::Simple.new(name, body, :body)
154
+ end
155
+ #}}}
156
+ end
157
+ private :add_to_params
158
+
159
+ def parse_nested_query(qs, type)
160
+ #{{{
161
+ (qs || '').split(/[#{D}] */n).each do |p|
162
+ k, v = Riddl::Protocols::Utils::unescape(p).split('=', 2)
163
+ @params << Parameter::Simple.new(k,v,type)
164
+ end
165
+ #}}}
166
+ end
167
+ private :parse_nested_query
168
+
169
+ def initialize(query_string,input,content_type,content_length,content_disposition,content_id,riddl_type)
170
+ #{{{
171
+ # rewind because in some cases it is not at start (when multipart without length)
172
+
173
+ begin
174
+ input.rewind if input.respond_to?(:rewind)
175
+ rescue Errno::ESPIPE
176
+ # Handles exceptions raised by input streams that cannot be rewound
177
+ # such as when using plain CGI under Apache
178
+ end
179
+
180
+ media_type = content_type && content_type.split(/\s*[;,]\s*/, 2).first.downcase
181
+ @params = Riddl::Parameter::Array.new
182
+ parse_nested_query(query_string,:query)
183
+ if MULTIPART_CONTENT_TYPES.include?(media_type)
184
+ parse_multipart(input,content_type,content_length.to_i)
185
+ elsif FORM_CONTENT_TYPES.include?(media_type)
186
+ # sub is a fix for Safari Ajax postings that always append \0
187
+ parse_nested_query(input.read.sub(/\0\z/, ''),:body)
188
+ else
189
+ parse_content(input,content_type,content_length.to_i,content_disposition||'',content_id||'',riddl_type||'')
190
+ end
191
+
192
+ begin
193
+ input.rewind if input.respond_to?(:rewind)
194
+ rescue Errno::ESPIPE
195
+ # Handles exceptions raised by input streams that cannot be rewound
196
+ # such as when using plain CGI under Apache
197
+ end
198
+ #}}}
199
+ end
200
+
201
+ attr_reader :params
202
+ end
203
+ end
204
+ end
205
+ end
data/riddl.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "riddl"
3
- s.version = "0.125"
3
+ s.version = "0.127"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.license = "LGPL-3.0"
6
6
  s.summary = "restful interface description and declaration language: tools and client/server libs"
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.required_ruby_version = '>=2.2.0'
24
24
 
25
- s.add_runtime_dependency 'daemonite', '~>0.6', '>=0.6.0'
25
+ s.add_runtime_dependency 'daemonite', '~>0.7', '>=0.7.0'
26
26
  s.add_runtime_dependency 'typhoeus', '~>1.3'
27
27
  s.add_runtime_dependency 'xml-smart', '>=0.4.3', '~>0'
28
28
  s.add_runtime_dependency 'rdf-smart', '>=0.0.160', '~>0'
@@ -34,5 +34,5 @@ Gem::Specification.new do |s|
34
34
  s.add_runtime_dependency 'mime-types', '>= 3.0', '~>3'
35
35
  s.add_runtime_dependency 'minitest', '>= 5.0.0', '~>5'
36
36
  s.add_runtime_dependency 'charlock_holmes', '>= 0.7', '~>0'
37
- s.add_runtime_dependency 'redis', '~> 4.0'
37
+ s.add_runtime_dependency 'redis', '~> 5.0'
38
38
  end
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.125'
4
+ version: '0.127'
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: 2023-02-19 00:00:00.000000000 Z
13
+ date: 2023-03-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: daemonite
@@ -18,20 +18,20 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '0.6'
21
+ version: '0.7'
22
22
  - - ">="
23
23
  - !ruby/object:Gem::Version
24
- version: 0.6.0
24
+ version: 0.7.0
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
28
28
  requirements:
29
29
  - - "~>"
30
30
  - !ruby/object:Gem::Version
31
- version: '0.6'
31
+ version: '0.7'
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 0.6.0
34
+ version: 0.7.0
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: typhoeus
37
37
  requirement: !ruby/object:Gem::Requirement
@@ -240,14 +240,14 @@ dependencies:
240
240
  requirements:
241
241
  - - "~>"
242
242
  - !ruby/object:Gem::Version
243
- version: '4.0'
243
+ version: '5.0'
244
244
  type: :runtime
245
245
  prerelease: false
246
246
  version_requirements: !ruby/object:Gem::Requirement
247
247
  requirements:
248
248
  - - "~>"
249
249
  - !ruby/object:Gem::Version
250
- version: '4.0'
250
+ version: '5.0'
251
251
  description: rest service interface definition, mixing, and evolution. supports mixed
252
252
  http and xmpp servers.
253
253
  email: juergen.mangler@gmail.com
@@ -459,8 +459,10 @@ files:
459
459
  - lib/ruby/riddl/ns/description/1.0/description.rng
460
460
  - lib/ruby/riddl/option.rb
461
461
  - lib/ruby/riddl/parameter.rb
462
+ - lib/ruby/riddl/protocols/generator.rb
462
463
  - lib/ruby/riddl/protocols/http/generator.rb
463
464
  - lib/ruby/riddl/protocols/http/parser.rb
465
+ - lib/ruby/riddl/protocols/parser.rb
464
466
  - lib/ruby/riddl/protocols/sse.rb
465
467
  - lib/ruby/riddl/protocols/utils.rb
466
468
  - lib/ruby/riddl/protocols/websocket.rb