riddl 0.99.255 → 0.99.256

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
  SHA1:
3
- metadata.gz: 7efd3c192b59759fc3904bfc114c582fd0779419
4
- data.tar.gz: 81df50479b20de911d2359f3b6341866946a4e48
3
+ metadata.gz: 234355d07a1365d8c3edad0985f8fbed5c1020b1
4
+ data.tar.gz: eeedfe05639e119ff574ecaef299e4fe792786aa
5
5
  SHA512:
6
- metadata.gz: 28a20fdcf4e8dac7197e6a5c0db2893066cefe24ce7f1fe192efe89e7097e28588ae148854343c07874506248e2a03298532b04897226025e568ea1e38e77750
7
- data.tar.gz: f425f6c7ca302bd9972e2fffd67483063674a6b00f328fc85dc84df470e08bc08c89a423aed4d571ce9f524653c7c237b2fd564ff4ed04485a750fce1255df45
6
+ metadata.gz: 8746dda65d1ecfb226db477340b060ca803392ddf40d1228299c39a670afdd6fb004bb579ed1cfeab379c9d7dbfc2af06a4688405de26132d713eb4e149095fa
7
+ data.tar.gz: fccc19fdd4ca57f9673ece1c9a071c85d1188fc52a3b9c76461424232b3d08fe06590e5738d88fcf30c4bbc640ec7217d5241bb10874ed4b6fce1fb274bb552f
@@ -11,6 +11,6 @@
11
11
  </endpoints>
12
12
  <handlerwrapper>Test</handlerwrapper>
13
13
  <description>lala</description>
14
- <state>running</state>
14
+ <state>stopped</state>
15
15
  <transformation>xxx</transformation>
16
16
  </properties>
@@ -1,11 +1,7 @@
1
- gem 'blather'
2
-
3
1
  require File.expand_path(File.dirname(__FILE__) + '/wrapper')
4
2
  require File.expand_path(File.dirname(__FILE__) + '/error')
5
3
  require File.expand_path(File.dirname(__FILE__) + '/protocols/http/generator')
6
4
  require File.expand_path(File.dirname(__FILE__) + '/protocols/http/parser')
7
- require File.expand_path(File.dirname(__FILE__) + '/protocols/xmpp/generator')
8
- require File.expand_path(File.dirname(__FILE__) + '/protocols/xmpp/parser')
9
5
  require File.expand_path(File.dirname(__FILE__) + '/protocols/utils')
10
6
  require File.expand_path(File.dirname(__FILE__) + '/header')
11
7
  require File.expand_path(File.dirname(__FILE__) + '/option')
@@ -13,7 +9,6 @@ require File.expand_path(File.dirname(__FILE__) + '/option')
13
9
  require 'net/https'
14
10
  require 'eventmachine'
15
11
  require 'em-websocket-client'
16
- require 'blather/client/client'
17
12
  require 'uri'
18
13
  require 'openssl'
19
14
  require 'digest/md5'
@@ -47,7 +42,7 @@ unless Module.constants.include?('CLIENT_INCLUDED')
47
42
  \A
48
43
 
49
44
  # protocol identifier
50
- (?:(?:https?|xmpp)://)
45
+ (?:(?:https?|[a-z]{4})://)
51
46
 
52
47
  # user:pass authentication
53
48
  (?:\S+(?::\S*)?@)?
@@ -93,26 +88,8 @@ unless Module.constants.include?('CLIENT_INCLUDED')
93
88
  if @base !~ RIDDL_URL_PATTERN
94
89
  raise ConnectionError, 'An RFC 3986 URI as target is required. Pro tip: (http|https|xmpp)://...'
95
90
  end
96
- if URI.parse(@base).scheme == 'xmpp' && !((@options[:jid] && @options[:pass]) || @options[:xmpp].is_a?(Blather::Client))
97
- raise ConnectionError, 'XMPP connections need jid/pass or Blather::client object passed as options to be successful.'
98
- end
99
- if URI.parse(@base).scheme == 'xmpp' && @options[:jid] && @options[:pass]
100
- sig = SignalWait.new
101
- Thread::abort_on_exception = true
102
- Thread.new do
103
- begin
104
- EM.send EM.reactor_running? ? :defer : :run do
105
- client = Blather::Client.setup @options[:jid], @options[:pass]
106
- client.register_handler(:ready) { sig.continue }
107
- client.connect
108
- @options[:xmpp] = client
109
- sig.continue
110
- end
111
- rescue
112
- raise ConnectionError, 'XMPP connection not successful.'
113
- end
114
- end
115
- sig.wait 2
91
+ if @options[:custom_protocol]
92
+ @options[:custom_protocol] = @options[:custom_protocol].new(@base,@options)
116
93
  end
117
94
  unless riddl.nil?
118
95
  @wrapper = (riddl.class == Riddl::Wrapper ? riddl : Riddl::Wrapper::new(riddl))
@@ -127,10 +104,6 @@ unless Module.constants.include?('CLIENT_INCLUDED')
127
104
  end
128
105
  attr_reader :base
129
106
 
130
- def close_xmpp
131
- @options[:xmpp].close if @options[:xmpp]
132
- end
133
-
134
107
  def self::location(base,options={})
135
108
  new(base,nil,options)
136
109
  end
@@ -409,56 +382,12 @@ unless Module.constants.include?('CLIENT_INCLUDED')
409
382
  end
410
383
  return res.code.to_i, response, response_headers
411
384
  #}}}
412
- elsif url.class == URI::Generic && url.scheme.downcase == 'xmpp'
413
- #{{{
414
- req = Riddl::Client::XMPPRequest.new(riddl_method,url.user + "@" + url.host,url.path,parameters,headers,qs,ack)
415
- return req.simulate if simulate
416
-
417
- sig = SignalWait.new
418
- stanza = req.stanza
419
-
420
- @options[:debug].puts(stanza) if @options[:debug]
421
-
422
- status = 404
423
- response = []
424
- response_headers = {}
425
- if ack
426
- @options[:xmpp].write_with_handler(stanza) do |raw|
427
- res = XML::Smart::Dom::Element.new(raw).parent
428
- @options[:debug].puts(res.to_s) if @options[:debug]
429
- res.register_namespace 'xr', Riddl::Protocols::XMPP::XR_NS
430
- if res.find('/message/error').empty?
431
- status = 200
432
- response_headers = {}
433
- res.find('/message/xr:header').each do |e|
434
- response_headers[e.attributes['name']] = e.text
435
- end
436
- response = Protocols::XMPP::Parser.new('', res).params
437
- else
438
- res.register_namespace 'se', Blather::StanzaError::STANZA_ERR_NS
439
- err = res.find('string(/message/error/se:text)')
440
- status = (err.match(/\d+/)[0] || 209).to_i
441
- end
442
- sig.continue
443
- end
444
- sig.wait
445
- else
446
- status = 200
447
- @options[:xmpp].write stanza
448
-
449
- # xmpp writes in next_tick so we have to fucking wait also a tick
450
- # to ensure that all shit has been written. fuck. not the best
451
- # solution, but scripts may preemtively quit if we dont do it. if
452
- # anybody knows a better solution, please tell me.
453
-
454
- ### UPDATE todo, we produce deadlocks here, rethink this mess
455
- # EM.next_tick { sig.continue }
456
- # sig.wait
385
+ else
386
+ if @options[:custom_protocol]
387
+ return @options[:custom_protocol].handle(url,riddl_method,parameters,headers,qs,simulate,ack)
457
388
  end
458
- return status, response, response_headers
459
- #}}}
460
389
  end
461
- raise URIError, "not a valid URI (http, https, xmpp are accepted)"
390
+ raise URIError, "not a valid URI (http, https, ... are accepted)"
462
391
  end #}}}
463
392
  private :make_request
464
393
 
@@ -489,25 +418,6 @@ unless Module.constants.include?('CLIENT_INCLUDED')
489
418
  end
490
419
  end # }}}
491
420
 
492
- class XMPPRequest #{{{
493
- attr_reader :stanza
494
-
495
- def initialize(method, to, path, parameters, headers, qs, ack)
496
- path = (path.strip == '' ? '' : path)
497
- path += "/?#{qs}" unless qs == ''
498
- path.gsub!(/\/+/,'/')
499
- @stanza = Protocols::XMPP::Generator.new(method,parameters,headers,ack).generate
500
- @stanza.to = to + path
501
- end
502
-
503
- def simulate
504
- sock = StringIO.new('')
505
- sock.write @stanza.to_s
506
- sock.rewind
507
- [nil, sock, []]
508
- end
509
- end #}}}
510
-
511
421
  end
512
422
 
513
423
  end
@@ -1,11 +1,7 @@
1
- gem 'blather'
2
-
3
1
  require File.expand_path(File.dirname(__FILE__) + '/constants')
4
2
  require File.expand_path(File.dirname(__FILE__) + '/implementation')
5
3
  require File.expand_path(File.dirname(__FILE__) + '/protocols/http/parser')
6
4
  require File.expand_path(File.dirname(__FILE__) + '/protocols/http/generator')
7
- require File.expand_path(File.dirname(__FILE__) + '/protocols/xmpp/parser')
8
- require File.expand_path(File.dirname(__FILE__) + '/protocols/xmpp/generator')
9
5
  require File.expand_path(File.dirname(__FILE__) + '/protocols/utils')
10
6
  require File.expand_path(File.dirname(__FILE__) + '/protocols/websocket')
11
7
  require File.expand_path(File.dirname(__FILE__) + '/header')
@@ -20,7 +16,7 @@ require 'rack/content_length'
20
16
  require 'rack/chunked'
21
17
  require 'securerandom'
22
18
  require 'psych.rb'
23
- require 'blather/client/client'
19
+
24
20
 
25
21
  module Riddl
26
22
 
@@ -133,7 +129,10 @@ module Riddl
133
129
  )
134
130
 
135
131
  puts "Server (#{@riddl_opts[:url]}) started as PID:#{Process.pid}"
136
- puts "XMPP support (#{@riddl_xmpp_jid}) active" if @riddl_xmpp_jid && @riddl_xmpp_pass && !@riddl_opts[:http_only]
132
+ if @riddl_opts[:custom_protocol] && !@riddl_opts[:http_only]
133
+ @riddl_opts[:custom_protocol] = @riddl_opts[:custom_protocol].new(@riddl_opts)
134
+ puts @riddl_opts[:custom_protocol].support if @riddl_opts[:custom_protocol].support
135
+ end
137
136
  Process.daemon(@riddl_opts[:basepath]) unless @riddl_opts[:verbose]
138
137
  Dir.chdir(@riddl_opts[:basepath])
139
138
  ::Kernel::at_exit do
@@ -150,29 +149,8 @@ module Riddl
150
149
  server.start
151
150
  end
152
151
 
153
- @riddl_opts[:xmpp] = nil
154
- if @riddl_xmpp_jid && @riddl_xmpp_pass && !@riddl_opts[:http_only]
155
- xmpp = Blather::Client.setup @riddl_xmpp_jid, @riddl_xmpp_pass
156
- @riddl_opts[:xmpp] = xmpp
157
- xmpp.register_handler(:message, '/message/ns:operation', :ns => 'http://riddl.org/ns/xmpp-rest') do |m|
158
- began_at = Time.now
159
- instance = dup
160
- instance.__xmpp_call(xmpp,m)
161
- now = Time.now
162
- instance.riddl_log.write Rack::CommonLogger::FORMAT % [
163
- @riddl_xmpp_jid || "-",
164
- m.from || "-",
165
- now.strftime("%d/%b/%Y %H:%M:%S"),
166
- instance.riddl_method.upcase,
167
- instance.riddl_pinfo,
168
- '',
169
- 'XMPP',
170
- instance.riddl_status,
171
- '?',
172
- now - began_at
173
- ]
174
- end
175
- xmpp.connect
152
+ if @riddl_opts[:custom_protocol] && !@riddl_opts[:http_only]
153
+ @riddl_opts[:custom_protocol].start
176
154
  end
177
155
 
178
156
  [:INT, :TERM].each do |signal|
@@ -184,11 +162,10 @@ module Riddl
184
162
  end
185
163
 
186
164
  rescue => e
187
- if e.is_a?(Blather::Stream::ConnectionFailed)
188
- puts "Server (#{@riddl_xmpp_jid}) stopped due to connection error (PID:#{Process.pid})"
189
- else
190
- puts "Server (#{@riddl_opts[:url]}) stopped due to connection error (PID:#{Process.pid})"
165
+ if @riddl_opts[:custom_protocol] && !@riddl_opts[:http_only]
166
+ @riddl_opts[:custom_protocol].error_handling(e)
191
167
  end
168
+ puts "Server (#{@riddl_opts[:url]}) stopped due to connection error (PID:#{Process.pid})"
192
169
  end
193
170
  end #}}}
194
171
 
@@ -327,62 +304,6 @@ module Riddl
327
304
  end
328
305
  end #}}}
329
306
 
330
- def __xmpp_call(env,raw) #{{{
331
- @riddl_log = @riddl_logger || STDOUT
332
-
333
- @riddl_env = XML::Smart::Dom::Element.new(raw).parent
334
- @riddl_env.register_namespace 'xr', Riddl::Protocols::XMPP::XR_NS
335
- @riddl_res = env
336
- @riddl_status = 404
337
-
338
- @riddl_pinfo = ('/' + @riddl_env.root.attributes['to'].sub(/^[^\/]+/,'')).gsub(/\/+/,'/')
339
- @riddl_pinfo.gsub!(/\?(.*)/).each do
340
- @riddl_query_string = $1; ''
341
- end
342
- @riddl_matching_path = @riddl_paths.find{ |e| @riddl_pinfo.match(e[1]).to_s.length == @riddl_pinfo.length }
343
-
344
- if @riddl_matching_path
345
- @riddl_method = @riddl_env.find('string(/message/xr:operation)').downcase
346
-
347
- @riddl_headers = {}
348
- @riddl_env.find('/message/xr:header').each do |e|
349
- @riddl_headers[e.attributes['name']] = e.text
350
- end
351
- @riddl_parameters = Protocols::XMPP::Parser.new(
352
- @riddl_query_string,
353
- @riddl_env
354
- ).params
355
-
356
- @riddl_path = '/'
357
- @riddl_info = {
358
- :h => @riddl_headers,
359
- :p => @riddl_parameters,
360
- :r => @riddl_pinfo.sub(/^\//,'').split('/').map{|e|Protocols::Utils::unescape(e)},
361
- :s => @riddl_matching_path[0].sub(/\//,'').split('/'),
362
- :m => @riddl_method,
363
- :env => Hash[@riddl_env.root.attributes.map{|a| [a.qname.name, a.value] }].merge({ 'riddl.transport' => 'xmpp', 'xmpp' => @riddl_res }),
364
- :match => []
365
- }
366
-
367
- __call
368
- else
369
- @riddl_log.write "404: this resource for sure does not exist.\n"
370
- @riddl_status = 404 # client requests wrong path
371
- end
372
-
373
- stanza = if @riddl_exe && @riddl_status >= 200 && @riddl_status < 300
374
- return if @riddl_message.out.nil?
375
- Protocols::XMPP::Generator.new(@riddl_status,@riddl_exe.response,@riddl_exe.headers).generate
376
- else
377
- Protocols::XMPP::Error.new(@riddl_status).generate
378
- end
379
-
380
- stanza.from = raw.to
381
- stanza.to = raw.from
382
- stanza.id = raw.id
383
- @riddl_res.write stanza
384
- end #}}}
385
-
386
307
  def __http_call(env) #{{{
387
308
  @riddl_env = env
388
309
  @riddl_env['rack.logger'] = @riddl_logger if @riddl_logger
@@ -419,7 +340,7 @@ module Riddl
419
340
  :r => @riddl_pinfo.sub(/^\//,'').split('/').map{|e|Protocols::Utils::unescape(e)},
420
341
  :s => @riddl_matching_path[0].sub(/\//,'').split('/'),
421
342
  :m => @riddl_method,
422
- :env => @riddl_env.reject{|k,v| k =~ /^rack\./}.merge({'riddl.transport' => 'http', 'xmpp' => @riddl_opts[:xmpp]}),
343
+ :env => @riddl_env.reject{|k,v| k =~ /^rack\./}.merge({'riddl.transport' => 'http', 'custom_protocol' => @riddl_opts[:custom_protocol]}),
423
344
  :match => []
424
345
  }
425
346
 
@@ -464,11 +385,6 @@ module Riddl
464
385
  def process_out(pout)# {{{
465
386
  @riddl_process_out = pout
466
387
  end# }}}
467
- def xmpp(jid,pass)# {{{
468
- @riddl_xmpp_jid = jid
469
- @riddl_xmpp_pass = pass
470
- @riddl_opts[:jid] = jid
471
- end# }}}
472
388
  def cross_site_xhr(csxhr)# {{{
473
389
  @riddl_cross_site_xhr = csxhr
474
390
  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.99.255"
3
+ s.version = "0.99.256"
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"
@@ -32,7 +32,6 @@ Gem::Specification.new do |s|
32
32
  s.add_runtime_dependency 'em-websocket-client', '>= 0.1', '~>0'
33
33
  s.add_runtime_dependency 'mime-types', '>= 2.4', '~>2'
34
34
  s.add_runtime_dependency 'minitest', '>= 5.0.0', '~>5'
35
- s.add_runtime_dependency 'blather', '~>1.2'
36
35
  s.add_runtime_dependency 'charlock_holmes', '>= 0.7', '~>0'
37
36
  s.add_runtime_dependency 'redis', '>= 3.3.0', '~>3.3'
38
37
  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.99.255
4
+ version: 0.99.256
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: 2017-11-16 00:00:00.000000000 Z
13
+ date: 2017-12-01 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: xml-smart
@@ -180,20 +180,6 @@ dependencies:
180
180
  - - "~>"
181
181
  - !ruby/object:Gem::Version
182
182
  version: '5'
183
- - !ruby/object:Gem::Dependency
184
- name: blather
185
- requirement: !ruby/object:Gem::Requirement
186
- requirements:
187
- - - "~>"
188
- - !ruby/object:Gem::Version
189
- version: '1.2'
190
- type: :runtime
191
- prerelease: false
192
- version_requirements: !ruby/object:Gem::Requirement
193
- requirements:
194
- - - "~>"
195
- - !ruby/object:Gem::Version
196
- version: '1.2'
197
183
  - !ruby/object:Gem::Dependency
198
184
  name: charlock_holmes
199
185
  requirement: !ruby/object:Gem::Requirement
@@ -441,8 +427,6 @@ files:
441
427
  - lib/ruby/riddl/protocols/http/parser.rb
442
428
  - lib/ruby/riddl/protocols/utils.rb
443
429
  - lib/ruby/riddl/protocols/websocket.rb
444
- - lib/ruby/riddl/protocols/xmpp/generator.rb
445
- - lib/ruby/riddl/protocols/xmpp/parser.rb
446
430
  - lib/ruby/riddl/roles.rb
447
431
  - lib/ruby/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Faccess_token.rb
448
432
  - lib/ruby/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Fon_behalf.rb
@@ -1,169 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../constants')
2
- require File.expand_path(File.dirname(__FILE__) + '/../utils')
3
- require 'blather/client/client'
4
- require 'securerandom'
5
-
6
- module Riddl
7
- module Protocols
8
- module XMPP
9
- XR_NS = 'http://riddl.org/ns/xmpp-rest'.freeze
10
-
11
- class Stanza < Blather::Stanza
12
- def self.new
13
- node = super :message
14
- node.type = :normal
15
- node.id = SecureRandom.uuid
16
- node
17
- end
18
- end
19
-
20
- class Error
21
- MAPPING = {
22
- 302 => ['redirect' , 'modify' , '302 Redirect' ],
23
- 400 => ['bad-request' , 'modify' , '400 Bad Request' ],
24
- 401 => ['not-authorized' , 'auth' , '401 Not Authorized ' ],
25
- 402 => ['payment-required' , 'auth' , '402 Payment Required' ],
26
- 403 => ['forbidden' , 'auth' , '403 Forbidden' ],
27
- 404 => ['item-not-found' , 'cancel' , '404 Not Found' ],
28
- 405 => ['not-allowed' , 'cancel' , '405 Not Allowed' ],
29
- 406 => ['not-acceptable' , 'modify' , '406 Not Acceptable' ],
30
- 407 => ['registration-required' , 'auth' , '407 Registration Required' ],
31
- 408 => ['remote-server-timeout' , 'wait' , '408 Request Timeout' ],
32
- 409 => ['conflict' , 'cancel' , '409 Conflict' ],
33
- 500 => ['internal-server-error' , 'wait' , '500 Internal Server Error' ],
34
- 501 => ['feature-not-implemented' , 'cancel' , '501 Not Implemented' ],
35
- 502 => ['service-unavailable' , 'wait' , '502 Remote Server Error' ],
36
- 503 => ['service-unavailable' , 'cancel' , '503 Service Unavailable' ],
37
- 504 => ['remote-server-timeout' , 'wait' , '504 Remote Server Timeout' ],
38
- 510 => ['service-unavailable' , 'cancel' , '510 Disconnected' ]
39
- }.freeze
40
- UNDEFINED = [
41
- 'undefined-condition', 'modify'
42
- ].freeze
43
-
44
- def initialize(err)
45
- m = Stanza.new
46
- @stanza = if MAPPING[err]
47
- Blather::StanzaError.new(m,*MAPPING[err]).to_node
48
- else
49
- Blather::StanzaError.new(m,*UNDEFINED,'#{err} see http://www.iana.org/assignments/http-status-codes/http-status-codes.xml').to_node
50
- end
51
- end
52
-
53
- def generate
54
- @stanza
55
- end
56
- end
57
-
58
- class Generator
59
- def initialize(what,params,headers,ack=false)
60
- @params = params
61
- @stanza = Stanza.new
62
- @node = XML::Smart::Dom::Element.new(@stanza)
63
- if what.is_a?(Fixnum)
64
- @node.add('ok').namespaces.add(nil,XR_NS)
65
- else
66
- @node.add('operation',what,:ack=>ack).namespaces.add(nil,XR_NS)
67
- end
68
- headers.each do |k,v|
69
- @node.add('header',v,:name => k).namespaces.add(nil,XR_NS)
70
- end
71
- end
72
-
73
- def generate(mode=:output)
74
- if @params.is_a?(Array) && @params.length == 1
75
- body(@params[0],mode)
76
- elsif @params.class == Riddl::Parameter::Simple || @params.class == Riddl::Parameter::Complex
77
- body(@params,mode)
78
- elsif @params.is_a?(Array) && @params.length > 1
79
- multipart(mode)
80
- else
81
- @stanza
82
- end
83
- end
84
-
85
- def body(r,mode)
86
- case r
87
- when Riddl::Parameter::Simple
88
- if mode == :output
89
- n = @node.add('part',r.value)
90
- n.namespaces.add(nil,XR_NS)
91
- n.attributes['content-type'] = 'text/plain'
92
- n.attributes['content-id'] = r.name
93
- n.attributes['RIDDL-TYPE'] = 'simple'
94
- end
95
- if mode == :input
96
- n = @node.add('part')
97
- n.namespaces.add(nil,XR_NS)
98
- n.attributes['content-type'] = 'application/x-www-form-urlencoded'
99
- n.text = Riddl::Protocols::Utils::escape(r.name) + '=' + Riddl::Protocols::Utils::escape(r.value)
100
- end
101
- when Riddl::Parameter::Complex
102
- n = @node.add('part')
103
- n.namespaces.add(nil,XR_NS)
104
- n.text = (r.value.respond_to?(:read) ? r.value.read : r.value)
105
- n.attributes['content-type'] = r.mimetype + r.mimextra
106
- n.attributes['RIDDL-TYPE'] = 'complex'
107
- if r.filename.nil?
108
- n.attributes['content-id'] = r.name
109
- else
110
- n.attributes['content-disposition'] = "riddl-data; name=\"#{r.name}\"; filename=\"#{r.filename}\""
111
- end
112
- end
113
- @stanza
114
- end
115
- private :body
116
-
117
- def multipart(mode)
118
- scount = ccount = 0
119
- @params.each do |r|
120
- case r
121
- when Riddl::Parameter::Simple
122
- scount += 1
123
- when Riddl::Parameter::Complex
124
- ccount += 1
125
- end
126
- end
127
- if scount > 0 && ccount == 0
128
- n = @node.add('part')
129
- n.namespaces.add(nil,XR_NS)
130
- n.attributes['content-type'] = 'application/x-www-form-urlencoded'
131
- res = []
132
- @params.each do |r|
133
- case r
134
- when Riddl::Parameter::Simple
135
- res << Riddl::Protocols::Utils::escape(r.name) + '=' + Riddl::Protocols::Utils::escape(r.value)
136
- end
137
- end
138
- n.text = res.join('&')
139
- else
140
- if scount + ccount > 0
141
- @params.each do |r|
142
- case r
143
- when Riddl::Parameter::Simple
144
- n = @node.add('part')
145
- n.namespaces.add(nil,XR_NS)
146
- n.attributes['RIDDL-TYPE'] = 'simple'
147
- n.attributes['content-type'] = 'text/plain'
148
- n.attributes['content-disposition'] = "#{mode == :input ? 'form-data' : 'riddl-data'}; name=\"#{r.name}\""
149
- n.text = r.value
150
- when Riddl::Parameter::Complex
151
- n = @node.add('part')
152
- n.namespaces.add(nil,XR_NS)
153
- n.attributes['RIDDL-TYPE'] = 'complex'
154
- n.attributes['content-disposition'] = "#{mode == :input ? 'form-data' : 'riddl-data'}; name=\"#{r.name}\"#{r.filename.nil? ? '' : "; filename=\"#{r.filename}\""}"
155
- n.attributes['content-transfer-encoding'] = 'binary'
156
- n.attributes['content-type'] = r.mimetype + r.mimextra
157
- n.text = (r.value.respond_to?(:read) ? r.value.read : r.value)
158
- end
159
- end
160
- end
161
- end
162
- @stanza
163
- end
164
- private :multipart
165
-
166
- end
167
- end
168
- end
169
- end
@@ -1,110 +0,0 @@
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 XMPP
8
- class Parser
9
- FORM_CONTENT_TYPES = [
10
- #{{{
11
- 'application/x-www-form-urlencoded'
12
- #}}}
13
- ].freeze
14
-
15
- STD_ATTRIBUTES = [
16
- #{{{
17
- 'content-type',
18
- 'content-disposition',
19
- 'content-id',
20
- 'content-transfer-type',
21
- 'RIDDL-TYPE',
22
- #}}}
23
- ].freeze
24
-
25
- def parse_part(input,head,ctype,content_disposition,content_id,riddl_type)
26
- #{{{
27
- head = Hash[
28
- head.map do |h|
29
- STD_ATTRIBUTES.include?(h.qname.name) ? nil : [h.qname.name, h.value]
30
- end.compact
31
- ]
32
- ctype = nil if riddl_type == 'simple'
33
- filename = content_disposition[/ filename="?([^\";]*)"?/ni, 1]
34
- name = content_disposition[/ name="?([^\";]*)"?/ni, 1] || content_id
35
-
36
- if ctype || filename
37
- body = Parameter::Tempfile.new("RiddlMultipart")
38
- body.binmode if body.respond_to?(:binmode)
39
- else
40
- body = ''
41
- end
42
-
43
- input.each { |i| body << i.dump }
44
- body.rewind if body.respond_to?(:binmode)
45
-
46
- add_to_params(name,body,filename,ctype,head)
47
- #}}}
48
- end
49
-
50
- def add_to_params(name,body,filename,ctype,head)
51
- #{{{
52
- if filename == ""
53
- # filename is blank which means no file has been selected
54
- elsif filename && ctype
55
- body.rewind
56
-
57
- # Take the basename of the upload's original filename.
58
- # This handles the full Windows paths given by Internet Explorer
59
- # (and perhaps other broken user agents) without affecting
60
- # those which give the lone filename.
61
- filename =~ /^(?:.*[:\\\/])?(.*)/m
62
- filename = $1
63
-
64
- @params << Parameter::Complex.new(name, ctype, body, filename, head)
65
- elsif !filename && ctype
66
- body.rewind
67
-
68
- # Generic multipart cases, not coming from a form
69
- @params << Parameter::Complex.new(name, ctype, body, nil, head)
70
- else
71
- @params << Parameter::Simple.new(name, body, :body)
72
- end
73
- #}}}
74
- end
75
- private :add_to_params
76
-
77
- def parse_nested_query(qs, type)
78
- #{{{
79
- (qs || '').split(/[#{D}] */n).each do |p|
80
- k, v = Riddl::Protocols::Utils::unescape(p).split('=', 2)
81
- @params << Parameter::Simple.new(k,v,type)
82
- end
83
- #}}}
84
- end
85
- private :parse_nested_query
86
-
87
- def initialize(query_string,input)
88
- #{{{
89
- @params = Riddl::Parameter::Array.new
90
-
91
- parse_nested_query(query_string,:query)
92
-
93
- input.find('/message/xr:part').each do |p|
94
- content_type = p.attributes['content-type'] || nil
95
- media_type = content_type && content_type.split(/\s*[;,]\s*/, 2).first.downcase
96
- if FORM_CONTENT_TYPES.include?(media_type)
97
- # sub is a fix for Safari Ajax postings that always append \0
98
- parse_nested_query(p.text.sub(/\0\z/, ''),:body)
99
- else
100
- parse_part(p.children,p.attributes,content_type,p.attributes['content-disposition']||'',p.attributes['content-id']||'',p.attributes['RIDDL-TYPE']||'')
101
- end
102
- end
103
- #}}}
104
- end
105
-
106
- attr_reader :params
107
- end
108
- end
109
- end
110
- end