phprpc 3.0.0

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.
@@ -0,0 +1,46 @@
1
+ ############################################################
2
+ # #
3
+ # The implementation of PHPRPC Protocol 3.0 #
4
+ # #
5
+ # cgi_server.rb #
6
+ # #
7
+ # Release 3.0.0 #
8
+ # Copyright (c) 2005-2008 by Team-PHPRPC #
9
+ # #
10
+ # WebSite: http://www.phprpc.org/ #
11
+ # http://www.phprpc.net/ #
12
+ # http://www.phprpc.com/ #
13
+ # http://sourceforge.net/projects/php-rpc/ #
14
+ # #
15
+ # Authors: Ma Bingyao <andot@ujn.edu.cn> #
16
+ # #
17
+ # This file may be distributed and/or modified under the #
18
+ # terms of the GNU Lesser General Public License (LGPL) #
19
+ # version 3.0 as published by the Free Software Foundation #
20
+ # and appearing in the included file LICENSE. #
21
+ # #
22
+ ############################################################
23
+ #
24
+ # PHPRPC CGIServer library.
25
+ #
26
+ # Copyright (C) 2005-2008 Ma Bingyao <andot@ujn.edu.cn>
27
+ # Version: 3.0
28
+ # LastModified: Sep 9, 2008
29
+ # This library is free. You can redistribute it and/or modify it.
30
+
31
+ require "phprpc/base_server"
32
+
33
+ module PHPRPC
34
+
35
+ class CGIServer < BaseServer
36
+
37
+ def start()
38
+ cgi = CGI::new
39
+ header, body = call!(ENV, cgi)
40
+ header['type'] = header['Content-Type']
41
+ cgi.out(header) { body }
42
+ end
43
+
44
+ end # class CGIServer
45
+
46
+ end # module PHPRPC
@@ -0,0 +1,268 @@
1
+ ############################################################
2
+ # #
3
+ # The implementation of PHPRPC Protocol 3.0 #
4
+ # #
5
+ # client.rb #
6
+ # #
7
+ # Release 3.0.0 #
8
+ # Copyright (c) 2005-2008 by Team-PHPRPC #
9
+ # #
10
+ # WebSite: http://www.phprpc.org/ #
11
+ # http://www.phprpc.net/ #
12
+ # http://www.phprpc.com/ #
13
+ # http://sourceforge.net/projects/php-rpc/ #
14
+ # #
15
+ # Authors: Ma Bingyao <andot@ujn.edu.cn> #
16
+ # #
17
+ # This file may be distributed and/or modified under the #
18
+ # terms of the GNU Lesser General Public License (LGPL) #
19
+ # version 3.0 as published by the Free Software Foundation #
20
+ # and appearing in the included file LICENSE. #
21
+ # #
22
+ ############################################################
23
+ #
24
+ # PHPRPC Client library.
25
+ #
26
+ # Copyright (C) 2005-2008 Ma Bingyao <andot@ujn.edu.cn>
27
+ # Version: 3.0
28
+ # LastModified: Sep 15, 2008
29
+ # This library is free. You can redistribute it and/or modify it.
30
+
31
+ require "net/http"
32
+ require "net/https"
33
+ require "uri"
34
+ require "digest/md5"
35
+ require "php/formator"
36
+ require "crypt/xxtea"
37
+ require "powmod"
38
+
39
+ module PHPRPC
40
+
41
+ class Error < Exception
42
+ attr_accessor :number
43
+ end
44
+
45
+ class Client
46
+
47
+ VERSION = '3.00'
48
+
49
+ def initialize(url = nil)
50
+ Net::HTTP.version_1_2
51
+ @httpclient = nil
52
+ @http = Net::HTTP
53
+ if url then
54
+ @uri = URI.parse(url)
55
+ end
56
+ @timeout = 30
57
+ @output = ''
58
+ @warning = nil
59
+ @key = nil
60
+ @keylength = 128
61
+ @encryptmode = 0
62
+ @cookie = ''
63
+ @cookies = {}
64
+ @charset = 'utf-8'
65
+ @username = nil
66
+ @password = nil
67
+ @server_version = nil
68
+ end
69
+
70
+ def use_service(url, username = nil, password = nil)
71
+ close
72
+ @httpclient = nil
73
+ @uri = URI.parse(url)
74
+ @key = nil
75
+ @keylength = 128
76
+ @encryptmode = 0
77
+ @cookie = ''
78
+ @cookies = {}
79
+ @charset = 'utf-8'
80
+ @username = username
81
+ @password = password
82
+ Proxy.new(self)
83
+ end
84
+
85
+ def set_proxy(p_addr, p_port = nil, p_user = nil, p_pass = nil)
86
+ close
87
+ @httpclient = nil
88
+ @http = Net::HTTP::Proxy(p_addr, p_port, p_user, p_pass)
89
+ end
90
+
91
+ def proxy=(proxy)
92
+ close
93
+ @httpclient = nil
94
+ @http = case proxy
95
+ when Net::HTTP then
96
+ proxy
97
+ when String then
98
+ uri = URI.parse(proxy)
99
+ Net::HTTP::Proxy(uri.host, uri.port, uri.user, uri.password)
100
+ else
101
+ proxy.superclass == Net::HTTP ? proxy : Net::HTTP
102
+ end
103
+ end
104
+
105
+ attr_reader :keylength
106
+
107
+ def keylength=(val)
108
+ @keylength = val if @key.nil?
109
+ end
110
+
111
+ attr_reader :encryptmode
112
+
113
+ def encryptmode=(val)
114
+ @encryptmode = ((val >= 0) and (val <= 3)) ? val.floor : 0;
115
+ end
116
+
117
+ attr_accessor :charset, :timeout
118
+
119
+ attr_reader :output, :warning
120
+
121
+ def invoke(methodname, args, byref = false)
122
+ begin
123
+ _key_exchange()
124
+ request = "phprpc_func=#{methodname}"
125
+ request << '&phprpc_args=' << [_encrypt(PHP::Formator.serialize(args), 1)].pack('m').delete!("\n").gsub('+', '%2B') if args.size > 0
126
+ request << "&phprpc_encrypt=#{@encryptmode}"
127
+ request << '&phprpc_ref=false' if not byref
128
+ result = _post(request)
129
+ if result.key?('phprpc_errstr') and result.key?('phprpc_errno') then
130
+ @warning = PHPRPC::Error.new(result['phprpc_errstr'].unpack('m')[0])
131
+ @warning.number = result['phprpc_errno'].to_i
132
+ elsif result.key?('phprpc_functions') then
133
+ @warning = PHPRPC::Error.new("PHPRPC server haven't received then POST data!")
134
+ @warning.number = 1
135
+ else
136
+ @warning = PHPRPC::Error.new("PHPRPC server occured unknown error!")
137
+ @warning.number = 1
138
+ end
139
+ if result.key?('phprpc_output') then
140
+ @output = result['phprpc_output'].unpack('m')[0]
141
+ @output = _decrypt(@output, 3) if @server_version >= 3
142
+ else
143
+ @output = ''
144
+ end
145
+ if result.key?('phprpc_result') then
146
+ PHP::Formator.unserialize(_decrypt(result['phprpc_arg'].unpack('m')[0], 1)).each { |key, value|
147
+ args[key] = value
148
+ } if result.key?('phprpc_args')
149
+ PHP::Formator.unserialize(_decrypt(result['phprpc_result'].unpack('m')[0], 2))
150
+ else
151
+ @warning
152
+ end
153
+ rescue PHPRPC::Error => e
154
+ return e
155
+ rescue Exception => ex
156
+ e = PHPRPC::Error.new(ex.message)
157
+ e.number = 1
158
+ return e
159
+ end
160
+ end
161
+
162
+ def close
163
+ @httpclient.finish if (not @httpclient.nil?) and @httpclient.started?
164
+ end
165
+
166
+ private
167
+
168
+ def _raise_error(number, message)
169
+ error = Error.new(message)
170
+ error.number = number
171
+ raise error
172
+ end
173
+
174
+ def _post(req)
175
+ if @httpclient.nil? then
176
+ @httpclient = @http.new(@uri.host, @uri.port)
177
+ @httpclient.use_ssl = (@uri.scheme == 'https')
178
+ @httpclient.start
179
+ end
180
+ headers = {
181
+ 'Cookie' => @cookie,
182
+ 'User-Agent' => "PHPRPC 3.0 Client for Ruby (#{RUBY_VERSION})",
183
+ 'Cache-Control' => 'no-cache',
184
+ 'Content-Type' => "application/x-www-form-urlencoded; charset=#{@charset}",
185
+ 'Content-Length' => req.size.to_s,
186
+ 'Connection' => 'keep-alive',
187
+ }
188
+ headers.delete('Cookie') if @cookie.nil? or @cookie.empty?
189
+ resp, data = @httpclient.request_post(@uri.path, req, headers)
190
+ if resp.code == '200' then
191
+ if resp.key?('x-powered-by') then
192
+ @server_version = nil
193
+ resp['x-powered-by'].split(', ').each { |value|
194
+ @server_version = value[14..-1].to_f if value[0, 13] == 'PHPRPC Server'
195
+ }
196
+ _raise_error(1, 'Illegal PHPRPC server.') if @server_version.nil?
197
+ else
198
+ _raise_error(1, 'Illegal PHPRPC server.')
199
+ end
200
+ resp['content-type'].split(', ').each { |value|
201
+ @charset = value[20..-1] if value[/^text\/plain; charset=/i]
202
+ }
203
+ if resp.key?('set-cookie') then
204
+ resp['set-cookie'].split(/[;,]\s?/).each { |pairs|
205
+ name, value = pairs.split('=', 2)
206
+ values ||= ''
207
+ @cookies[name] = value unless ['domain', 'expires', 'path', 'secure'].include?(name)
208
+ }
209
+ @cookie = ''
210
+ @cookies.each { |name, value|
211
+ @cookie << "#{name}=#{value}; "
212
+ }
213
+ end
214
+ result = {}
215
+ data.split(/;\r\n/).each { |line|
216
+ result.store(*line.match(/^(phprpc_[a-z]+)="(.*)"$/)[1, 2])
217
+ }
218
+ return result
219
+ else
220
+ _raise_error(resp.code.to_i, resp.message)
221
+ end
222
+ end
223
+
224
+ def _key_exchange
225
+ if (@key.nil?) and (@encryptmode != 0) then
226
+ result = _post("phprpc_encrypt=true&phprpc_keylen=#{@keylength.to_s}")
227
+ @keylength = result.key?('phprpc_keylen') ? result['phprpc_keylen'].to_i : 128
228
+ if result.key?('phprpc_encrypt') then
229
+ encrypt = PHP::Formator.unserialize(result['phprpc_encrypt'].unpack("m")[0])
230
+ x = rand(1 << (@keylength - 1)) or (1 << (@keylength - 2))
231
+ key = Math.powmod(encrypt['y'].to_i, x, encrypt['p'].to_i)
232
+ @key = (@keylength == 128) ? [key.to_s(16).rjust(32, '0')].pack('H*') : Digest::MD5.digest(key.to_s)
233
+ y = Math.powmod(encrypt['g'].to_i, x, encrypt['p'].to_i)
234
+ _post("phprpc_encrypt=#{y}")
235
+ else
236
+ @key = nil
237
+ @encryptmode = 0
238
+ end
239
+ end
240
+ end
241
+
242
+ def _encrypt(str, level)
243
+ ((not @key.nil?) and (@encryptmode >= level)) ? Crypt::XXTEA.encrypt(str, @key) : str
244
+ end
245
+
246
+ def _decrypt(str, level)
247
+ ((not @key.nil?) and (@encryptmode >= level)) ? Crypt::XXTEA.decrypt(str, @key) : str
248
+ end
249
+
250
+ def method_missing(methodname, *args)
251
+ self.invoke(methodname, args)
252
+ end
253
+
254
+ class Proxy
255
+
256
+ def initialize(phprpc_client)
257
+ @phprpc_client = phprpc_client
258
+ end
259
+
260
+ def method_missing(methodname, *args)
261
+ @phprpc_client.invoke(methodname, args)
262
+ end
263
+
264
+ end # class Proxy
265
+
266
+ end # class Client
267
+
268
+ end # module PHPRPC
@@ -0,0 +1,89 @@
1
+ ############################################################
2
+ # #
3
+ # The implementation of PHPRPC Protocol 3.0 #
4
+ # #
5
+ # ebb_server.rb #
6
+ # #
7
+ # Release 3.0.0 #
8
+ # Copyright (c) 2005-2008 by Team-PHPRPC #
9
+ # #
10
+ # WebSite: http://www.phprpc.org/ #
11
+ # http://www.phprpc.net/ #
12
+ # http://www.phprpc.com/ #
13
+ # http://sourceforge.net/projects/php-rpc/ #
14
+ # #
15
+ # Authors: Ma Bingyao <andot@ujn.edu.cn> #
16
+ # #
17
+ # This file may be distributed and/or modified under the #
18
+ # terms of the GNU Lesser General Public License (LGPL) #
19
+ # version 3.0 as published by the Free Software Foundation #
20
+ # and appearing in the included file LICENSE. #
21
+ # #
22
+ ############################################################
23
+ #
24
+ # PHPRPC EbbServer library.
25
+ #
26
+ # Copyright (C) 2005-2008 Ma Bingyao <andot@ujn.edu.cn>
27
+ # Version: 3.0
28
+ # LastModified: Sep 14, 2008
29
+ # This library is free. You can redistribute it and/or modify it.
30
+
31
+ require 'ebb_ffi'
32
+ require 'ebb'
33
+ require "phprpc/base_server"
34
+
35
+ module PHPRPC
36
+ class EbbServer < BaseServer
37
+
38
+ def initialize(options = {})
39
+ super()
40
+ @options = {
41
+ :port => 3000,
42
+ :session_mode => :file,
43
+ :path => "/",
44
+ :expire_after => 1800,
45
+ }.update(options)
46
+ @opts = OptionParser.new
47
+ @opts.banner = "Usage: #{@opts.program_name} ebb [options]"
48
+ @opts.separator ""
49
+ @opts.separator "Server options:"
50
+ @opts.on('-p', '--port PORT', Integer, "Which port to bind to (default: #{@options[:port]})") { |port| @options[:port] = port }
51
+ @opts.on('--ssl_cert FILE', String, "SSL certificate file") { |file| @options[:ssl_cert] = file }
52
+ @opts.on('--ssl_key FILE', String, "SSL key file") { |file| @options[:ssl_key] = file }
53
+ @opts.separator ""
54
+ @opts.separator "Session options:"
55
+ @opts.on('-s', '--session-mode MODE', [:file, :memcache, :pool], "Select Session mode (file, memcache, pool)", "(default: #{@options[:session_mode].to_s})") { |mode| @options[:session_mode] = mode }
56
+ @opts.on('-e','--expire-after TIME', Integer, "Session expire after (default: #{@options[:expire_after]})") { |time| @options[:expire_after] = time }
57
+ @opts.on('-m','--memcache_server SERVER', String, "Memcache server used by session in", "memcache mode (default: localhost:11211)") { |server| @options[:memcache_server] = server }
58
+ @opts.on('--prefix PATH', String, "Mount the PHPRPC Server under PATH", "(start with /)") { |path| @options[:path] = path }
59
+ @opts.separator ""
60
+ @opts.separator "Common options:"
61
+ @opts.on_tail("-D", "--debug", "Set debbuging on") { self.debug = true }
62
+ @opts.on_tail('-?', '-h', '--help', "Show this help message.") { puts @opts; exit }
63
+ @opts.on_tail('-v', '--version', "Show version") { puts Ebb::VERSION_STRING; exit }
64
+ begin
65
+ @opts.parse!(ARGV)
66
+ rescue OptionParser::ParseError
67
+ puts @opts
68
+ exit
69
+ end
70
+ end
71
+
72
+ def start()
73
+ app = self
74
+ if [:memcache, :pool].include?(@options[:session_mode]) then
75
+ begin
76
+ require 'rack'
77
+ if @options[:session_mode] == :memcache then
78
+ app = Rack::Session::Memcache.new(self, @options)
79
+ else
80
+ app = Rack::Session::Pool.new(self, @options)
81
+ end
82
+ rescue Exception
83
+ app = self
84
+ end
85
+ end
86
+ Ebb.start_server(app, @options)
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,50 @@
1
+ ############################################################
2
+ # #
3
+ # The implementation of PHPRPC Protocol 3.0 #
4
+ # #
5
+ # fake_server.rb #
6
+ # #
7
+ # Release 3.0.0 #
8
+ # Copyright (c) 2005-2008 by Team-PHPRPC #
9
+ # #
10
+ # WebSite: http://www.phprpc.org/ #
11
+ # http://www.phprpc.net/ #
12
+ # http://www.phprpc.com/ #
13
+ # http://sourceforge.net/projects/php-rpc/ #
14
+ # #
15
+ # Authors: Ma Bingyao <andot@ujn.edu.cn> #
16
+ # #
17
+ # This file may be distributed and/or modified under the #
18
+ # terms of the GNU Lesser General Public License (LGPL) #
19
+ # version 3.0 as published by the Free Software Foundation #
20
+ # and appearing in the included file LICENSE. #
21
+ # #
22
+ ############################################################
23
+ #
24
+ # PHPRPC FakeServer library.
25
+ #
26
+ # Copyright (C) 2005-2008 Ma Bingyao <andot@ujn.edu.cn>
27
+ # Version: 3.0
28
+ # LastModified: Sep 13, 2008
29
+ # This library is free. You can redistribute it and/or modify it.
30
+
31
+ require 'optparse'
32
+
33
+ module PHPRPC
34
+ class FakeServer
35
+
36
+ def initialize
37
+ @opts = OptionParser.new
38
+ @opts.banner = "Usage: #{@opts.program_name} [ServerName] [options]"
39
+ @opts.separator ""
40
+ @opts.separator "ServerName: (mongrel, thin, fcgi, scgi, lsapi, ebb, webrick)"
41
+ @opts.separator ""
42
+ @opts.separator "options:"
43
+ @opts.on_tail('-?', '-h', '--help', "Show this help message.", "Show more messages with ServerName.") { puts @opts; exit }
44
+ puts @opts
45
+ exit
46
+ end
47
+
48
+ end # class FakeServer
49
+
50
+ end