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.
- data/AUTHORS +13 -0
- data/LICENSE +165 -0
- data/README +46 -0
- data/examples/client.rb +15 -0
- data/examples/server.rb +17 -0
- data/lib/crypt/xxtea.rb +112 -0
- data/lib/dhparams/1024.dhp +1 -0
- data/lib/dhparams/128.dhp +1 -0
- data/lib/dhparams/1536.dhp +1 -0
- data/lib/dhparams/160.dhp +1 -0
- data/lib/dhparams/192.dhp +1 -0
- data/lib/dhparams/2048.dhp +1 -0
- data/lib/dhparams/256.dhp +1 -0
- data/lib/dhparams/3072.dhp +1 -0
- data/lib/dhparams/4096.dhp +1 -0
- data/lib/dhparams/512.dhp +1 -0
- data/lib/dhparams/768.dhp +1 -0
- data/lib/dhparams/96.dhp +1 -0
- data/lib/php/formator.rb +454 -0
- data/lib/phprpc.rb +65 -0
- data/lib/phprpc/base_server.rb +392 -0
- data/lib/phprpc/cgi_server.rb +46 -0
- data/lib/phprpc/client.rb +268 -0
- data/lib/phprpc/ebb_server.rb +89 -0
- data/lib/phprpc/fake_server.rb +50 -0
- data/lib/phprpc/fcgi_server.rb +125 -0
- data/lib/phprpc/lsapi_server.rb +101 -0
- data/lib/phprpc/mongrel_server.rb +168 -0
- data/lib/phprpc/scgi_server.rb +134 -0
- data/lib/phprpc/server.rb +55 -0
- data/lib/phprpc/thin_server.rb +161 -0
- data/lib/phprpc/webrick_server.rb +139 -0
- data/lib/powmod.rb +39 -0
- metadata +91 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
############################################################
|
2
|
+
# #
|
3
|
+
# The implementation of PHPRPC Protocol 3.0 #
|
4
|
+
# #
|
5
|
+
# fcgi_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 FCGIServer 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 'fcgi'
|
32
|
+
require 'phprpc/base_server'
|
33
|
+
|
34
|
+
module PHPRPC
|
35
|
+
|
36
|
+
class FCGIServer < BaseServer
|
37
|
+
|
38
|
+
def initialize(options = {})
|
39
|
+
super()
|
40
|
+
@options = {
|
41
|
+
:session_mode => :file,
|
42
|
+
:path => "/",
|
43
|
+
:expire_after => 1800,
|
44
|
+
}.update(options)
|
45
|
+
@opts = OptionParser.new
|
46
|
+
@opts.banner = "Usage: #{@opts.program_name} fcgi [options]"
|
47
|
+
@opts.separator ""
|
48
|
+
@opts.separator "Server options:"
|
49
|
+
@opts.on('-a', '--address IP', String, "Bind FCGI to the specified ip.") { |ip| @options[:host] = ip }
|
50
|
+
@opts.on('-p', '--port PORT', Integer, "Run FCGI on the specified port.") { |port| @options[:port] = port }
|
51
|
+
@opts.separator ""
|
52
|
+
@opts.separator "Session options:"
|
53
|
+
@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 }
|
54
|
+
@opts.on('-e','--expire-after TIME', Integer, "Session expire after (default: #{@options[:expire_after]})") { |time| @options[:expire_after] = time }
|
55
|
+
@opts.on('-m','--memcache_server SERVER', String, "Memcache server used by session in", "memcache mode (default: localhost:11211)") { |server| @options[:memcache_server] = server }
|
56
|
+
@opts.on('--prefix PATH', String, "Mount the PHPRPC Server under PATH", "(start with /)") { |path| @options[:path] = path }
|
57
|
+
@opts.separator ""
|
58
|
+
@opts.separator "Common options:"
|
59
|
+
@opts.on_tail('-D', '--debug', "Set debbuging on") { self.debug = true }
|
60
|
+
@opts.on_tail('-?', '-h', '--help', "Show this help message.") { puts @opts; exit }
|
61
|
+
begin
|
62
|
+
@opts.parse!(ARGV)
|
63
|
+
rescue OptionParser::ParseError
|
64
|
+
puts @opts
|
65
|
+
exit
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def start()
|
70
|
+
app = self
|
71
|
+
if [:memcache, :pool].include?(@options[:session_mode]) then
|
72
|
+
begin
|
73
|
+
require 'rack'
|
74
|
+
if @options[:session_mode] == :memcache then
|
75
|
+
app = Rack::Session::Memcache.new(self, @options)
|
76
|
+
else
|
77
|
+
app = Rack::Session::Pool.new(self, @options)
|
78
|
+
end
|
79
|
+
rescue Exception
|
80
|
+
app = self
|
81
|
+
end
|
82
|
+
end
|
83
|
+
begin
|
84
|
+
if @options[:port] then
|
85
|
+
@options[:host] = '0.0.0.0' if @options[:host].nil?
|
86
|
+
puts "## PHPRPC FCGI Server 3.0.0"
|
87
|
+
STDIN.reopen(TCPServer.new(@options[:host], @options[:port]))
|
88
|
+
puts "## Listening on #{@options[:host]}:#{@options[:port]}, CTRL+C to stop"
|
89
|
+
end
|
90
|
+
trap(:INT) { exit }
|
91
|
+
FCGI.each { |request|
|
92
|
+
env = request.env
|
93
|
+
env["rack.input"] = request.in
|
94
|
+
env["rack.multithread"] = false # this variable only used for rack pool session on debug mode
|
95
|
+
env["rack.url_scheme"] = ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
|
96
|
+
env["QUERY_STRING"] ||= ""
|
97
|
+
env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
|
98
|
+
env["REQUEST_PATH"] ||= "/"
|
99
|
+
status, headers, body = app.call(env)
|
100
|
+
begin
|
101
|
+
out = request.out
|
102
|
+
out.print "Status: #{status}\r\n"
|
103
|
+
headers.each { |k, v|
|
104
|
+
out.print "#{k}: #{v}\r\n"
|
105
|
+
}
|
106
|
+
out.print "\r\n"
|
107
|
+
out.flush
|
108
|
+
out.print body
|
109
|
+
out.flush
|
110
|
+
ensure
|
111
|
+
request.finish
|
112
|
+
end
|
113
|
+
}
|
114
|
+
rescue SystemExit
|
115
|
+
exit
|
116
|
+
rescue Exception => e
|
117
|
+
puts "## #{@options[:host]}:#{@options[:port]} #{e.message}"
|
118
|
+
puts @opts
|
119
|
+
exit
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
end # class FCGIServer
|
124
|
+
|
125
|
+
end # module PHPRPC
|
@@ -0,0 +1,101 @@
|
|
1
|
+
############################################################
|
2
|
+
# #
|
3
|
+
# The implementation of PHPRPC Protocol 3.0 #
|
4
|
+
# #
|
5
|
+
# lsapi_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 LSAPIServer 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 "phprpc/base_server"
|
32
|
+
|
33
|
+
module PHPRPC
|
34
|
+
|
35
|
+
class LSAPIServer < BaseServer
|
36
|
+
|
37
|
+
def initialize(options = {})
|
38
|
+
super()
|
39
|
+
@options = {
|
40
|
+
:session_mode => :file,
|
41
|
+
:path => "/",
|
42
|
+
:expire_after => 1800,
|
43
|
+
}.update(options)
|
44
|
+
@opts = OptionParser.new
|
45
|
+
@opts.banner = "Usage: #{@opts.program_name} lsapi [options]"
|
46
|
+
@opts.separator ""
|
47
|
+
@opts.separator "Session options:"
|
48
|
+
@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 }
|
49
|
+
@opts.on('-e','--expire-after TIME', Integer, "Session expire after (default: #{@options[:expire_after]})") { |time| @options[:expire_after] = time }
|
50
|
+
@opts.on('-m','--memcache_server SERVER', String, "Memcache server used by session in", "memcache mode (default: localhost:11211)") { |server| @options[:memcache_server] = server }
|
51
|
+
@opts.on('--prefix PATH', String, "Mount the PHPRPC Server under PATH", "(start with /)") { |path| @options[:path] = path }
|
52
|
+
@opts.separator ""
|
53
|
+
@opts.separator "Common options:"
|
54
|
+
@opts.on_tail("-D", "--debug", "Set debbuging on") { self.debug = true }
|
55
|
+
@opts.on_tail('-?', '-h', '--help', "Show this help message.") { puts @opts; exit }
|
56
|
+
begin
|
57
|
+
@opts.parse!(ARGV)
|
58
|
+
rescue OptionParser::ParseError
|
59
|
+
puts @opts
|
60
|
+
exit
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def start
|
65
|
+
app = self
|
66
|
+
if [:memcache, :pool].include?(@options[:session_mode]) then
|
67
|
+
begin
|
68
|
+
require 'rack'
|
69
|
+
if @options[:session_mode] == :memcache then
|
70
|
+
app = Rack::Session::Memcache.new(self, @options)
|
71
|
+
else
|
72
|
+
app = Rack::Session::Pool.new(self, @options)
|
73
|
+
end
|
74
|
+
rescue Exception
|
75
|
+
app = self
|
76
|
+
end
|
77
|
+
end
|
78
|
+
require 'lsapi'
|
79
|
+
while LSAPI.accept != nil
|
80
|
+
env = ENV.to_hash
|
81
|
+
env["rack.input"] = STDIN
|
82
|
+
env["rack.multithread"] = false
|
83
|
+
env["rack.url_scheme"] = ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
|
84
|
+
env["QUERY_STRING"] ||= ""
|
85
|
+
env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
|
86
|
+
env["REQUEST_PATH"] ||= "/"
|
87
|
+
status, headers, body = app.call(env)
|
88
|
+
print "Status: #{status}#{EOL}"
|
89
|
+
headers.each { |k, v|
|
90
|
+
print "#{k}: #{v}#{EOL}"
|
91
|
+
}
|
92
|
+
print EOL
|
93
|
+
STDOUT.flush
|
94
|
+
print body
|
95
|
+
STDOUT.flush
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end # class LSAPIServer
|
100
|
+
|
101
|
+
end # module PHPRPC
|
@@ -0,0 +1,168 @@
|
|
1
|
+
############################################################
|
2
|
+
# #
|
3
|
+
# The implementation of PHPRPC Protocol 3.0 #
|
4
|
+
# #
|
5
|
+
# mongrel_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 MongrelServer 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 'mongrel'
|
32
|
+
require 'phprpc/base_server'
|
33
|
+
|
34
|
+
module PHPRPC
|
35
|
+
|
36
|
+
class MongrelServer < Mongrel::HttpHandler
|
37
|
+
|
38
|
+
def initialize(options = {})
|
39
|
+
@options = {
|
40
|
+
:host => '0.0.0.0',
|
41
|
+
:port => 3000,
|
42
|
+
:num_processors => 1024,
|
43
|
+
:throttle => 0,
|
44
|
+
:timeout => 60,
|
45
|
+
:debug => false,
|
46
|
+
:daemonize => false,
|
47
|
+
:cwd => Dir.pwd,
|
48
|
+
:log_file => 'log/mongrel.log',
|
49
|
+
:pid_file => 'log/mongrel.pid',
|
50
|
+
:session_mode => :file,
|
51
|
+
:path => '/',
|
52
|
+
:expire_after => 1800,
|
53
|
+
}.update(options)
|
54
|
+
@opts = OptionParser.new
|
55
|
+
@opts.banner = "Usage: #{@opts.program_name} mongrel [options]"
|
56
|
+
@opts.separator ""
|
57
|
+
@opts.separator "Server options:"
|
58
|
+
@opts.on('-a', '--address IP', String, "Address to bind to (default: #{@options[:host]})") { |ip| @options[:host] = ip }
|
59
|
+
@opts.on('-p', '--port PORT', Integer, "Which port to bind to (default: #{@options[:port]})") { |port| @options[:port] = port }
|
60
|
+
@opts.on('-c', '--chdir PATH', String, "Change to dir before starting", "(will be expanded) (default: #{@options[:cwd]})") { |path| @options[:cwd] = File.expand_path(path) }
|
61
|
+
@opts.on('-u', '--user USER', String, "User to run as") { |user| @options[:user] = user }
|
62
|
+
@opts.on('-g', '--group GROUP', String, "Group to run as") { |group| @options[:group] = group }
|
63
|
+
unless RUBY_PLATFORM =~ /mswin|mingw/ # Daemonizing not supported on Windows
|
64
|
+
@opts.separator ""
|
65
|
+
@opts.separator "Daemon options:"
|
66
|
+
@opts.on('-d', '--daemonize', "Run daemonized in the background") { @options[:daemonize] = true }
|
67
|
+
@opts.on('-l', '--log FILE', String, "Where to write log messages", "(default: #{@options[:log_file]})") { |file| @options[:log_file] = file }
|
68
|
+
@opts.on("-P", "--pid FILE", String, "File to store PID", "(default: #{@options[:pid_file]})") { |file| @options[:pid_file] = file }
|
69
|
+
end
|
70
|
+
@opts.separator ""
|
71
|
+
@opts.separator "Tuning options:"
|
72
|
+
@opts.on('-n', '--num-processors INT', Integer, "Number of processors active", "before clients denied (default: #{@options[:num_processors]})") { |num| @options[:num_processors] = num }
|
73
|
+
@opts.on('-t', '--throttle TIME', Integer, "Time to pause (in hundredths of a second)", "between accepting clients (default: #{@options[:throttle]})") { |time| @options[:throttle] = time }
|
74
|
+
@opts.on('-o', '--timeout TIME', Integer, "Time to wait (in seconds) before killing", "a stalled thread (default: #{@options[:timeout]})") { |time| @options[:timeout] = time }
|
75
|
+
@opts.separator ""
|
76
|
+
@opts.separator "Session options:"
|
77
|
+
@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 }
|
78
|
+
@opts.on('-e','--expire-after TIME', Integer, "Session expire after (default: #{@options[:expire_after]})") { |time| @options[:expire_after] = time }
|
79
|
+
@opts.on('-m','--memcache_server SERVER', String, "Memcache server used by session in", "memcache mode (default: localhost:11211)") { |server| @options[:memcache_server] = server }
|
80
|
+
@opts.on('--prefix PATH', String, "Mount the PHPRPC Server under PATH", "(start with /)") { |path| @options[:path] = path }
|
81
|
+
@opts.separator ""
|
82
|
+
@opts.separator "Common options:"
|
83
|
+
@opts.on_tail('-D', '--debug', "Set debbuging on (default: disabled)") { @options[:debug] = true }
|
84
|
+
@opts.on_tail('-?', '-h', '--help', "Show this help message.") { puts @opts; exit }
|
85
|
+
@opts.on_tail('-v', '--version', "Show version") { puts "Mongrel web server v#{Mongrel::Const::MONGREL_VERSION}"; exit }
|
86
|
+
begin
|
87
|
+
@opts.parse!(ARGV)
|
88
|
+
rescue OptionParser::ParseError
|
89
|
+
puts @opts
|
90
|
+
exit
|
91
|
+
end
|
92
|
+
@app = PHPRPC::BaseServer.new
|
93
|
+
@app.debug = @options[:debug]
|
94
|
+
end
|
95
|
+
|
96
|
+
def add(methodname, obj = nil, aliasname = nil, &block)
|
97
|
+
@app.add(methodname, obj, aliasname, &block)
|
98
|
+
end
|
99
|
+
|
100
|
+
def charset
|
101
|
+
@app.charset
|
102
|
+
end
|
103
|
+
|
104
|
+
def charset=(val)
|
105
|
+
@app.charset = val
|
106
|
+
end
|
107
|
+
|
108
|
+
def debug
|
109
|
+
@app.debug
|
110
|
+
end
|
111
|
+
|
112
|
+
def debug=(val)
|
113
|
+
@app.debug = val
|
114
|
+
end
|
115
|
+
|
116
|
+
def start
|
117
|
+
if [:memcache, :pool].include?(@options[:session_mode]) then
|
118
|
+
old_app = @app
|
119
|
+
begin
|
120
|
+
require 'rack'
|
121
|
+
if @options[:session_mode] == :memcache then
|
122
|
+
@app = Rack::Session::Memcache.new(@app, @options)
|
123
|
+
else
|
124
|
+
@app = Rack::Session::Pool.new(@app, @options)
|
125
|
+
end
|
126
|
+
rescue Exception
|
127
|
+
@app = old_app
|
128
|
+
end
|
129
|
+
end
|
130
|
+
@options[:handler] = self
|
131
|
+
Mongrel::Configurator.new(@options) {
|
132
|
+
daemonize if @defaults[:daemonize]
|
133
|
+
log "Mongrel web server v#{Mongrel::Const::MONGREL_VERSION}"
|
134
|
+
log "Listening on #{@defaults[:host]}:#{@defaults[:port]}"
|
135
|
+
log "CTRL+C to stop" if @defaults[:daemonize]
|
136
|
+
write_pid_file
|
137
|
+
setup_signals
|
138
|
+
listener {
|
139
|
+
uri @defaults[:path]
|
140
|
+
debug(@defaults[:path], [:access, :threads]) if @defaults[:debug]
|
141
|
+
}
|
142
|
+
run
|
143
|
+
join
|
144
|
+
}
|
145
|
+
end
|
146
|
+
|
147
|
+
def process(request, response)
|
148
|
+
env = {}.replace(request.params)
|
149
|
+
env["rack.input"] = request.body || StringIO.new("")
|
150
|
+
env['rack.multithread'] = true # this variable only used for rack pool session on debug mode
|
151
|
+
env["rack.url_scheme"] = "http"
|
152
|
+
env["QUERY_STRING"] ||= ""
|
153
|
+
status, headers, body = @app.call(env)
|
154
|
+
begin
|
155
|
+
response.status = status.to_i
|
156
|
+
headers.each { |k, v|
|
157
|
+
response.header[k] = v
|
158
|
+
}
|
159
|
+
response.body << body
|
160
|
+
response.finished
|
161
|
+
ensure
|
162
|
+
body.close if body.respond_to? :close
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
end # class MongrelServer
|
167
|
+
|
168
|
+
end # module PHPRPC
|
@@ -0,0 +1,134 @@
|
|
1
|
+
############################################################
|
2
|
+
# #
|
3
|
+
# The implementation of PHPRPC Protocol 3.0 #
|
4
|
+
# #
|
5
|
+
# scgi_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 SCGIServer 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 'thread'
|
32
|
+
require 'scgi'
|
33
|
+
require 'phprpc/base_server'
|
34
|
+
|
35
|
+
module PHPRPC
|
36
|
+
|
37
|
+
class SCGIProcessor < SCGI::Processor
|
38
|
+
|
39
|
+
def initialize(options = {})
|
40
|
+
@app = options[:app]
|
41
|
+
if not options.key?(:logfile) then
|
42
|
+
@log = Object.new
|
43
|
+
def @log.info(*args); end
|
44
|
+
def @log.error(*args); end
|
45
|
+
end
|
46
|
+
super(options)
|
47
|
+
end
|
48
|
+
|
49
|
+
def process_request(request, input_body, socket)
|
50
|
+
env = {}.replace(request)
|
51
|
+
env["REQUEST_PATH"], env["QUERY_STRING"] = env["REQUEST_URI"].split('?', 2)
|
52
|
+
env["QUERY_STRING"] ||= ""
|
53
|
+
env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
|
54
|
+
env["SCRIPT_NAME"] = env["PATH_INFO"] = env["REQUEST_PATH"]
|
55
|
+
env["rack.input"] = StringIO.new(input_body)
|
56
|
+
env["rack.multithread"] = true # this variable only used for rack pool session on debug mode
|
57
|
+
env["rack.url_scheme"] = ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
|
58
|
+
status, headers, body = @app.call(env)
|
59
|
+
socket.write("Status: #{status}\r\n")
|
60
|
+
headers.each { |k, v| socket.write("#{k}: #{v}\r\n") }
|
61
|
+
socket.write("\r\n")
|
62
|
+
socket.write(body)
|
63
|
+
end
|
64
|
+
|
65
|
+
end # class SCGIProcessor
|
66
|
+
|
67
|
+
class SCGIServer < BaseServer
|
68
|
+
|
69
|
+
def initialize(options = {})
|
70
|
+
super()
|
71
|
+
@options = {
|
72
|
+
:host => '0.0.0.0',
|
73
|
+
:port => 9999,
|
74
|
+
:maxconns => 2**30 - 1,
|
75
|
+
:session_mode => :file,
|
76
|
+
:path => "/",
|
77
|
+
:expire_after => 1800,
|
78
|
+
}.update(options)
|
79
|
+
@opts = OptionParser.new
|
80
|
+
@opts.banner = "Usage: #{@opts.program_name} scgi [options]"
|
81
|
+
@opts.separator ""
|
82
|
+
@opts.separator "Server options:"
|
83
|
+
@opts.on('-a', '--address IP', String, "Bind SCGI to the specified ip.", "(default: #{@options[:host]})") { |ip| @options[:host] = ip }
|
84
|
+
@opts.on('-p', '--port PORT', Integer, "Run SCGI on the specified port.", "(default: #{@options[:port]})") { |port| @options[:port] = port }
|
85
|
+
@opts.on('-l', '--logfile FILE', String, "Where to write log messages.") { |file| @options[:logfile] = file }
|
86
|
+
@opts.on('-n', '--maxconns NUM', Integer, "Allow this many max connections,", "more than this are redirected to /busy.html", "(default: #{@options[:maxconns]})") { |num| @options[:maxconns] = num }
|
87
|
+
@opts.separator ""
|
88
|
+
@opts.separator "Session options:"
|
89
|
+
@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 }
|
90
|
+
@opts.on('-e','--expire-after TIME', Integer, "Session expire after (default: #{@options[:expire_after]})") { |time| @options[:expire_after] = time }
|
91
|
+
@opts.on('-m','--memcache_server SERVER', String, "Memcache server used by session in", "memcache mode (default: localhost:11211)") { |server| @options[:memcache_server] = server }
|
92
|
+
@opts.on('--prefix PATH', String, "Mount the PHPRPC Server under PATH", "(start with /)") { |path| @options[:path] = path }
|
93
|
+
@opts.separator ""
|
94
|
+
@opts.separator "Common options:"
|
95
|
+
@opts.on_tail('-D', '--debug', "Set debbuging on") { self.debug = true }
|
96
|
+
@opts.on_tail('-?', '-h', '--help', "Show this help message.") { puts @opts; exit }
|
97
|
+
begin
|
98
|
+
@opts.parse!(ARGV)
|
99
|
+
rescue OptionParser::ParseError
|
100
|
+
puts @opts
|
101
|
+
exit
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def start
|
106
|
+
app = self
|
107
|
+
if [:memcache, :pool].include?(@options[:session_mode]) then
|
108
|
+
begin
|
109
|
+
require 'rack'
|
110
|
+
if @options[:session_mode] == :memcache then
|
111
|
+
app = Rack::Session::Memcache.new(self, @options)
|
112
|
+
else
|
113
|
+
app = Rack::Session::Pool.new(self, @options)
|
114
|
+
end
|
115
|
+
rescue Exception
|
116
|
+
app = self
|
117
|
+
end
|
118
|
+
end
|
119
|
+
puts "## PHPRPC SCGI Server 3.0.0"
|
120
|
+
puts "## Listening on #{@options[:host]}:#{@options[:port]}, CTRL+C to stop"
|
121
|
+
begin
|
122
|
+
SCGIProcessor.new(@options.update({:app => app})).listen
|
123
|
+
rescue SystemExit
|
124
|
+
exit
|
125
|
+
rescue Exception => e
|
126
|
+
puts "## #{@options[:host]}:#{@options[:port]} #{e.message}"
|
127
|
+
puts @opts
|
128
|
+
exit
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end # class SCGIServer
|
133
|
+
|
134
|
+
end # module PHPRPC
|