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