riddl 0.99.255 → 0.99.256

Sign up to get free protection for your applications and to get access to all the features.
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