phprpc 3.0.4 → 3.0.5

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.
@@ -4,8 +4,8 @@
4
4
  # #
5
5
  # cgi_server.rb #
6
6
  # #
7
- # Release 3.0.4 #
8
- # Copyright (c) 2005-2008 by Team-PHPRPC #
7
+ # Release 3.0.5 #
8
+ # Copyright by Team-PHPRPC #
9
9
  # #
10
10
  # WebSite: http://www.phprpc.org/ #
11
11
  # http://www.phprpc.net/ #
@@ -23,7 +23,7 @@
23
23
  #
24
24
  # PHPRPC CGIServer library.
25
25
  #
26
- # Copyright (C) 2005-2008 Ma Bingyao <andot@ujn.edu.cn>
26
+ # Copyright: Ma Bingyao <andot@ujn.edu.cn>
27
27
  # Version: 3.0
28
28
  # LastModified: Sep 9, 2008
29
29
  # This library is free. You can redistribute it and/or modify it.
@@ -31,9 +31,9 @@
31
31
  require "phprpc/base_server"
32
32
 
33
33
  module PHPRPC
34
-
34
+
35
35
  class CGIServer < BaseServer
36
-
36
+
37
37
  def start()
38
38
  cgi = CGI::new
39
39
  header, body = call!(ENV, cgi)
@@ -4,8 +4,8 @@
4
4
  # #
5
5
  # client.rb #
6
6
  # #
7
- # Release 3.0.4 #
8
- # Copyright (c) 2005-2008 by Team-PHPRPC #
7
+ # Release 3.0.5 #
8
+ # Copyright by Team-PHPRPC #
9
9
  # #
10
10
  # WebSite: http://www.phprpc.org/ #
11
11
  # http://www.phprpc.net/ #
@@ -23,9 +23,9 @@
23
23
  #
24
24
  # PHPRPC Client library.
25
25
  #
26
- # Copyright (C) 2005-2008 Ma Bingyao <andot@ujn.edu.cn>
26
+ # Copyright: Ma Bingyao <andot@ujn.edu.cn>
27
27
  # Version: 3.0
28
- # LastModified: Oct 6, 2008
28
+ # LastModified: Mar 10, 2009
29
29
  # This library is free. You can redistribute it and/or modify it.
30
30
 
31
31
  require "net/http"
@@ -35,9 +35,10 @@ require "digest/md5"
35
35
  require "php/formator"
36
36
  require "crypt/xxtea"
37
37
  require "powmod"
38
+ require "thread"
38
39
 
39
40
  module PHPRPC
40
-
41
+
41
42
  class Error < Exception
42
43
  attr_accessor :number
43
44
  end
@@ -46,22 +47,34 @@ module PHPRPC
46
47
 
47
48
  VERSION = '3.00'
48
49
 
50
+ @@cookie = ''
51
+ @@cookies = {}
52
+ @@sid = 0
53
+ @@mutex = Mutex.new
54
+
49
55
  def initialize(url = nil)
56
+ @clientID = "ruby" + rand(1 << 32).to_s + Time.now.to_i.to_s + @@sid.to_s
57
+ @@sid += 1
50
58
  Net::HTTP.version_1_2
51
- @httpclient = nil
59
+ @httpclients = []
52
60
  @http = Net::HTTP
53
61
  @uri = nil
54
62
  if url then
55
63
  @uri = URI.parse(url)
64
+ if @uri.query.nil? then
65
+ @uri.query = "phprpc_id=" + @clientID
66
+ else
67
+ @uri.query = @uri.query + "&phprpc_id=" + @clientID
68
+ end
56
69
  end
70
+ @mutex = Mutex.new
57
71
  @timeout = 30
58
72
  @output = ''
59
73
  @warning = nil
60
74
  @key = nil
61
75
  @keylength = 128
62
76
  @encryptmode = 0
63
- @cookie = ''
64
- @cookies = {}
77
+ @keyexchanged = false;
65
78
  @charset = 'utf-8'
66
79
  @server_version = nil
67
80
  end
@@ -70,11 +83,15 @@ module PHPRPC
70
83
  if url then
71
84
  close
72
85
  @uri = URI.parse(url)
86
+ if @uri.query.nil? then
87
+ @uri.query = "phprpc_id=" + @clientID
88
+ else
89
+ @uri.query = @uri.query + "&phprpc_id=" + @clientID
90
+ end
73
91
  @key = nil
74
92
  @keylength = 128
75
93
  @encryptmode = 0
76
- @cookie = ''
77
- @cookies = {}
94
+ @keyexchanged = false;
78
95
  @charset = 'utf-8'
79
96
  @uri.user = username unless username.nil?
80
97
  @uri.password = password unless password.nil?
@@ -113,68 +130,101 @@ module PHPRPC
113
130
  end
114
131
 
115
132
  attr_accessor :charset, :timeout
116
-
133
+
117
134
  attr_reader :output, :warning
118
135
 
119
- def invoke(methodname, args, byref = false)
136
+ def invoke(methodname, args, byref = false, encryptmode = nil, &block)
137
+ if block_given? then
138
+ Thread.start {
139
+ data = _invoke(methodname, args, byref, encryptmode)
140
+ case block.arity
141
+ when 0: yield
142
+ when 1: yield data[:result]
143
+ when 2: yield data[:result], args
144
+ when 3: yield data[:result], args, data[:output]
145
+ when 4: yield data[:result], args, data[:output], data[:warning]
146
+ end
147
+ }
148
+ else
149
+ data = _invoke(methodname, args, byref, encryptmode)
150
+ @warning = data[:warning]
151
+ @output = data[:output]
152
+ data[:result]
153
+ end
154
+ end
155
+
156
+ def close
157
+ loop do
158
+ httpclient = @httpclients.shift
159
+ break if httpclient.nil?
160
+ httpclient.finish if httpclient.started?
161
+ end
162
+ end
163
+
164
+ private
165
+
166
+ def _invoke(methodname, args, byref = false, encryptmode = nil)
167
+ data = {}
120
168
  begin
121
- _key_exchange()
169
+ encryptmode = @encryptmode if encryptmode.nil?
170
+ @mutex.synchronize {
171
+ encryptmode = _key_exchange(encryptmode)
172
+ }
122
173
  request = "phprpc_func=#{methodname}"
123
- request << '&phprpc_args=' << [_encrypt(PHP::Formator.serialize(args), 1)].pack('m').delete!("\n").gsub('+', '%2B') if args.size > 0
124
- request << "&phprpc_encrypt=#{@encryptmode}"
174
+ request << '&phprpc_args=' << [_encrypt(PHP::Formator.serialize(args), 1, encryptmode)].pack('m').delete!("\n").gsub('+', '%2B') if args.size > 0
175
+ request << "&phprpc_encrypt=#{encryptmode}"
125
176
  request << '&phprpc_ref=false' unless byref
126
177
  result = _post(request)
127
178
  if result.key?('phprpc_errstr') and result.key?('phprpc_errno') then
128
- @warning = PHPRPC::Error.new(result['phprpc_errstr'].unpack('m')[0])
129
- @warning.number = result['phprpc_errno'].to_i
179
+ warning = PHPRPC::Error.new(result['phprpc_errstr'].unpack('m')[0])
180
+ warning.number = result['phprpc_errno'].to_i
130
181
  elsif result.key?('phprpc_functions') then
131
- @warning = PHPRPC::Error.new("PHPRPC server haven't received then POST data!")
132
- @warning.number = 1
182
+ warning = PHPRPC::Error.new("PHPRPC server haven't received the POST data!")
183
+ warning.number = 1
133
184
  else
134
- @warning = PHPRPC::Error.new("PHPRPC server occured unknown error!")
135
- @warning.number = 1
185
+ warning = PHPRPC::Error.new("PHPRPC server occured unknown error!")
186
+ warning.number = 1
136
187
  end
188
+ data[:warning] = warning
137
189
  if result.key?('phprpc_output') then
138
- @output = result['phprpc_output'].unpack('m')[0]
139
- @output = _decrypt(@output, 3) if @server_version >= 3
190
+ output = result['phprpc_output'].unpack('m')[0]
191
+ output = _decrypt(output, 3, encryptmode) if @server_version >= 3
140
192
  else
141
- @output = ''
193
+ output = ''
142
194
  end
195
+ data[:output] = output
143
196
  if result.key?('phprpc_result') then
144
- PHP::Formator.unserialize(_decrypt(result['phprpc_arg'].unpack('m')[0], 1)).each { |key, value|
197
+ PHP::Formator.unserialize(_decrypt(result['phprpc_arg'].unpack('m')[0], 1, encryptmode)).each { |key, value|
145
198
  args[key] = value
146
199
  } if result.key?('phprpc_args')
147
- PHP::Formator.unserialize(_decrypt(result['phprpc_result'].unpack('m')[0], 2))
200
+ data[:result] = PHP::Formator.unserialize(_decrypt(result['phprpc_result'].unpack('m')[0], 2, encryptmode))
148
201
  else
149
- @warning
202
+ data[:result] = warning
150
203
  end
151
204
  rescue PHPRPC::Error => e
152
- return e
205
+ data[:result] = e
153
206
  rescue Exception => ex
154
207
  e = PHPRPC::Error.new(ex.message)
155
208
  e.number = 1
156
- return e
209
+ data[:result] = e
210
+ ensure
211
+ return data
157
212
  end
158
213
  end
159
-
160
- def close
161
- @httpclient.finish if (not @httpclient.nil?) and @httpclient.started?
162
- @httpclient = nil
163
- end
164
-
165
- private
166
214
 
167
215
  def _raise_error(number, message)
168
216
  error = Error.new(message)
169
217
  error.number = number
170
218
  raise error
171
219
  end
172
-
220
+
173
221
  def _post(req)
174
- if @httpclient.nil? then
175
- @httpclient = @http.new(@uri.host, @uri.port)
176
- @httpclient.use_ssl = (@uri.scheme == 'https')
177
- @httpclient.start
222
+ httpclient = @httpclients.shift
223
+ if httpclient.nil? then
224
+ httpclient = @http.new(@uri.host, @uri.port)
225
+ httpclient.use_ssl = (@uri.scheme == 'https')
226
+ #httpclient.set_debug_output $stderr
227
+ httpclient.start
178
228
  end
179
229
  headers = {
180
230
  'User-Agent' => "PHPRPC 3.0 Client for Ruby (#{RUBY_VERSION})",
@@ -183,16 +233,18 @@ module PHPRPC
183
233
  'Content-Length' => req.size.to_s,
184
234
  'Connection' => 'keep-alive',
185
235
  }
186
- headers['Cookie'] = @cookie unless @cookie.empty?
236
+ headers['Cookie'] = @@cookie unless @@cookie.empty?
187
237
  headers['Authorization'] = 'Basic ' << ["#{@uri.user}:#{@uri.password}"].pack('m').delete!("\n") unless @uri.user.nil? or @uri.password.nil?
188
- resp, data = @httpclient.request_post(@uri.path, req, headers)
238
+ resp, data = httpclient.request_post(@uri.path + '?' + @uri.query, req, headers)
239
+ @httpclients.push(httpclient)
189
240
  if resp.code == '200' then
190
241
  if resp.key?('x-powered-by') then
191
- @server_version = nil
242
+ server_version = nil
192
243
  resp['x-powered-by'].split(', ').each { |value|
193
- @server_version = value[14..-1].to_f if value[0, 13] == 'PHPRPC Server'
244
+ server_version = value[14..-1].to_f if value[0, 13] == 'PHPRPC Server'
194
245
  }
195
- _raise_error(1, 'Illegal PHPRPC server.') if @server_version.nil?
246
+ _raise_error(1, 'Illegal PHPRPC server.') if server_version.nil?
247
+ @server_version = server_version
196
248
  else
197
249
  _raise_error(1, 'Illegal PHPRPC server.')
198
250
  end
@@ -200,14 +252,16 @@ module PHPRPC
200
252
  @charset = value[20..-1] if value[/^text\/plain; charset=/i]
201
253
  }
202
254
  if resp.key?('set-cookie') then
203
- resp['set-cookie'].split(/[;,]\s?/).each { |pairs|
204
- name, value = pairs.split('=', 2)
205
- values ||= ''
206
- @cookies[name] = value unless ['domain', 'expires', 'path', 'secure'].include?(name)
207
- }
208
- @cookie = ''
209
- @cookies.each { |name, value|
210
- @cookie << "#{name}=#{value}; "
255
+ @@mutex.synchronize {
256
+ resp['set-cookie'].split(/[;,]\s?/).each { |pairs|
257
+ name, value = pairs.split('=', 2)
258
+ values ||= ''
259
+ @@cookies[name] = value unless ['domain', 'expires', 'path', 'secure'].include?(name)
260
+ }
261
+ @@cookie = ''
262
+ @@cookies.each { |name, value|
263
+ @@cookie << "#{name}=#{value}; "
264
+ }
211
265
  }
212
266
  end
213
267
  result = {}
@@ -220,44 +274,47 @@ module PHPRPC
220
274
  end
221
275
  end
222
276
 
223
- def _key_exchange
224
- if (@key.nil?) and (@encryptmode != 0) then
225
- result = _post("phprpc_encrypt=true&phprpc_keylen=#{@keylength.to_s}")
226
- @keylength = result.key?('phprpc_keylen') ? result['phprpc_keylen'].to_i : 128
227
- if result.key?('phprpc_encrypt') then
228
- encrypt = PHP::Formator.unserialize(result['phprpc_encrypt'].unpack("m")[0])
229
- x = rand(1 << (@keylength - 1)) or (1 << (@keylength - 2))
230
- key = Math.powmod(encrypt['y'].to_i, x, encrypt['p'].to_i)
231
- @key = (@keylength == 128) ? [key.to_s(16).rjust(32, '0')].pack('H*') : Digest::MD5.digest(key.to_s)
232
- y = Math.powmod(encrypt['g'].to_i, x, encrypt['p'].to_i)
233
- _post("phprpc_encrypt=#{y}")
234
- else
235
- @key = nil
236
- @encryptmode = 0
237
- end
277
+ def _key_exchange(encryptmode)
278
+ return encryptmode if (!@key.nil?) or (encryptmode == 0)
279
+ return 0 if (@key.nil?) and (@keyexchanged)
280
+ result = _post("phprpc_encrypt=true&phprpc_keylen=#{@keylength.to_s}")
281
+ @keylength = result.key?('phprpc_keylen') ? result['phprpc_keylen'].to_i : 128
282
+ if result.key?('phprpc_encrypt') then
283
+ encrypt = PHP::Formator.unserialize(result['phprpc_encrypt'].unpack("m")[0])
284
+ x = rand(1 << (@keylength - 1)) or (1 << (@keylength - 2))
285
+ key = Math.powmod(encrypt['y'].to_i, x, encrypt['p'].to_i)
286
+ @key = (@keylength == 128) ? [key.to_s(16).rjust(32, '0')].pack('H*') : Digest::MD5.digest(key.to_s)
287
+ y = Math.powmod(encrypt['g'].to_i, x, encrypt['p'].to_i)
288
+ _post("phprpc_encrypt=#{y}")
289
+ else
290
+ @key = nil
291
+ @keyexchanged = true
292
+ @encryptmode = 0
293
+ encryptmode = 0
238
294
  end
295
+ return encryptmode
239
296
  end
240
-
241
- def _encrypt(str, level)
242
- ((not @key.nil?) and (@encryptmode >= level)) ? Crypt::XXTEA.encrypt(str, @key) : str
297
+
298
+ def _encrypt(str, level, encryptmode)
299
+ ((not @key.nil?) and (encryptmode >= level)) ? Crypt::XXTEA.encrypt(str, @key) : str
243
300
  end
244
-
245
- def _decrypt(str, level)
246
- ((not @key.nil?) and (@encryptmode >= level)) ? Crypt::XXTEA.decrypt(str, @key) : str
301
+
302
+ def _decrypt(str, level, encryptmode)
303
+ ((not @key.nil?) and (encryptmode >= level)) ? Crypt::XXTEA.decrypt(str, @key) : str
247
304
  end
248
-
249
- def method_missing(methodname, *args)
250
- self.invoke(methodname, args)
305
+
306
+ def method_missing(methodname, *args, &block)
307
+ self.invoke(methodname, args, &block)
251
308
  end
252
309
 
253
310
  class Proxy
254
311
 
255
312
  def initialize(phprpc_client)
256
- @phprpc_client = phprpc_client
313
+ @phprpc_client = phprpc_client
257
314
  end
258
315
 
259
- def method_missing(methodname, *args)
260
- @phprpc_client.invoke(methodname, args)
316
+ def method_missing(methodname, *args, &block)
317
+ @phprpc_client.invoke(methodname, args, &block)
261
318
  end
262
319
 
263
320
  end # class Proxy
@@ -4,8 +4,8 @@
4
4
  # #
5
5
  # ebb_server.rb #
6
6
  # #
7
- # Release 3.0.4 #
8
- # Copyright (c) 2005-2008 by Team-PHPRPC #
7
+ # Release 3.0.5 #
8
+ # Copyright by Team-PHPRPC #
9
9
  # #
10
10
  # WebSite: http://www.phprpc.org/ #
11
11
  # http://www.phprpc.net/ #
@@ -23,7 +23,7 @@
23
23
  #
24
24
  # PHPRPC EbbServer library.
25
25
  #
26
- # Copyright (C) 2005-2008 Ma Bingyao <andot@ujn.edu.cn>
26
+ # Copyright: Ma Bingyao <andot@ujn.edu.cn>
27
27
  # Version: 3.0
28
28
  # LastModified: Sep 14, 2008
29
29
  # This library is free. You can redistribute it and/or modify it.
@@ -34,14 +34,14 @@ require "phprpc/base_server"
34
34
 
35
35
  module PHPRPC
36
36
  class EbbServer < BaseServer
37
-
37
+
38
38
  def initialize(options = {})
39
39
  super()
40
40
  @options = {
41
41
  :port => 3000,
42
42
  :session_mode => :file,
43
43
  :path => "/",
44
- :expire_after => 1800,
44
+ :expire_after => 1800,
45
45
  }.update(options)
46
46
  @opts = OptionParser.new
47
47
  @opts.banner = "Usage: #{@opts.program_name} ebb [options]"
@@ -4,8 +4,8 @@
4
4
  # #
5
5
  # fake_server.rb #
6
6
  # #
7
- # Release 3.0.4 #
8
- # Copyright (c) 2005-2008 by Team-PHPRPC #
7
+ # Release 3.0.5 #
8
+ # Copyright by Team-PHPRPC #
9
9
  # #
10
10
  # WebSite: http://www.phprpc.org/ #
11
11
  # http://www.phprpc.net/ #
@@ -23,7 +23,7 @@
23
23
  #
24
24
  # PHPRPC FakeServer library.
25
25
  #
26
- # Copyright (C) 2005-2008 Ma Bingyao <andot@ujn.edu.cn>
26
+ # Copyright: Ma Bingyao <andot@ujn.edu.cn>
27
27
  # Version: 3.0
28
28
  # LastModified: Sep 13, 2008
29
29
  # This library is free. You can redistribute it and/or modify it.
@@ -4,8 +4,8 @@
4
4
  # #
5
5
  # fcgi_server.rb #
6
6
  # #
7
- # Release 3.0.4 #
8
- # Copyright (c) 2005-2008 by Team-PHPRPC #
7
+ # Release 3.0.5 #
8
+ # Copyright by Team-PHPRPC #
9
9
  # #
10
10
  # WebSite: http://www.phprpc.org/ #
11
11
  # http://www.phprpc.net/ #
@@ -23,7 +23,7 @@
23
23
  #
24
24
  # PHPRPC FCGIServer library.
25
25
  #
26
- # Copyright (C) 2005-2008 Ma Bingyao <andot@ujn.edu.cn>
26
+ # Copyright: Ma Bingyao <andot@ujn.edu.cn>
27
27
  # Version: 3.0
28
28
  # LastModified: Sep 14, 2008
29
29
  # This library is free. You can redistribute it and/or modify it.
@@ -34,19 +34,19 @@ require 'phprpc/base_server'
34
34
  module PHPRPC
35
35
 
36
36
  class FCGIServer < BaseServer
37
-
37
+
38
38
  def initialize(options = {})
39
39
  super()
40
40
  @options = {
41
41
  :session_mode => :file,
42
42
  :path => "/",
43
- :expire_after => 1800,
43
+ :expire_after => 1800,
44
44
  }.update(options)
45
45
  @opts = OptionParser.new
46
46
  @opts.banner = "Usage: #{@opts.program_name} fcgi [options]"
47
47
  @opts.separator ""
48
48
  @opts.separator "Server options:"
49
- @opts.on('-a', '--address IP', String, "Bind FCGI to the specified ip.") { |ip| @options[:host] = ip }
49
+ @opts.on('-a', '--address IP', String, "Bind FCGI to the specified ip.") { |ip| @options[:host] = ip }
50
50
  @opts.on('-p', '--port PORT', Integer, "Run FCGI on the specified port.") { |port| @options[:port] = port }
51
51
  @opts.separator ""
52
52
  @opts.separator "Session options:"
@@ -63,7 +63,7 @@ module PHPRPC
63
63
  rescue OptionParser::ParseError
64
64
  puts @opts
65
65
  exit
66
- end
66
+ end
67
67
  end
68
68
 
69
69
  def start()