cgialt 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +13 -0
- data/README.txt +38 -15
- data/bench.rb +1 -1
- data/lib/cgialt/cookie.rb +5 -4
- data/lib/cgialt/core.rb +61 -48
- data/lib/cgialt/fcgi/cgi_helper.rb +102 -0
- data/lib/cgialt/fcgi/core.rb +561 -0
- data/lib/cgialt/fcgi.rb +28 -0
- data/lib/cgialt.rb +1 -1
- metadata +7 -2
data/CHANGES.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
## $Rev$
|
2
|
+
## 0.0.2
|
3
|
+
## copyright(c) 2007 kuwata-lab.com all rights reserved.
|
4
|
+
|
5
|
+
|
6
|
+
- release: 0.0.2
|
7
|
+
date: 2007-12-11
|
8
|
+
enhancements:
|
9
|
+
- FastCGI supported. If you required 'cgialt/fcgi' instead of 'fcgi',
|
10
|
+
you can use FCGI.each_cgi() method.
|
11
|
+
|
12
|
+
- release: 0.0.1
|
13
|
+
date: 2007-12-09
|
data/README.txt
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
= README.txt
|
2
2
|
|
3
|
-
Release: 0.0.
|
3
|
+
Release: 0.0.2
|
4
4
|
|
5
5
|
copyright(c) 2007 kuwata-lab.com all rights reserved.
|
6
6
|
|
7
|
+
http://rubyforge.org/projects/cgialt/
|
8
|
+
|
7
9
|
|
8
10
|
== About
|
9
11
|
|
@@ -17,14 +19,15 @@ It is written in pure Ruby but works faster than 'cgi.rb'.
|
|
17
19
|
* Faster and more lightweight than 'cgi.rb'.
|
18
20
|
* Available to install with CGIExt (which is a re-implementation of 'cgi.rb'
|
19
21
|
in C extension).
|
22
|
+
* FastCGI support
|
20
23
|
|
21
24
|
|
22
25
|
== Install
|
23
26
|
|
24
|
-
Download cgialt-0.0.
|
27
|
+
Download cgialt-0.0.2.tar.gz and install it according to the following:
|
25
28
|
|
26
|
-
$ tar xzf cgialt-0.0.
|
27
|
-
$ cd cgialt-0.0.
|
29
|
+
$ tar xzf cgialt-0.0.2.tar.gz
|
30
|
+
$ cd cgialt-0.0.2/
|
28
31
|
$ ruby setup.rb config
|
29
32
|
$ ruby setup.rb setup
|
30
33
|
$ sudo ruby setup.rb install
|
@@ -45,17 +48,24 @@ CGI class which is compatible with 'cgi.rb'.
|
|
45
48
|
require 'rubygems' # if you have installed with RubyGems
|
46
49
|
require 'cgialt'
|
47
50
|
|
51
|
+
If you want to use CGIAlt with FastCGI (fcgi.rb), require 'cgialt/fcgi'
|
52
|
+
instead of 'fcgi'.
|
53
|
+
|
54
|
+
require 'cgialt'
|
55
|
+
require 'cgialt/fcgi'
|
56
|
+
|
48
57
|
If you want to replace original 'cgi.rb' entirely by 'cgialt',
|
49
58
|
create 'cgi.rb' which requires 'cgialt' under proper directory such as
|
50
59
|
'/usr/local/lib/ruby/site_ruby/1.8'.
|
51
60
|
|
52
61
|
$ sudo echo 'require "cgialt"' > /usr/local/lib/ruby/site_ruby/1.8/cgi.rb
|
62
|
+
$ sudo echo 'require "cgialt/fcgi"' > /usr/local/lib/ruby/site_ruby/1.8/fcgi.rb
|
53
63
|
|
54
64
|
When $DEBUG is true or ENV['DEBUG'] is set, CGIAlt prints release number
|
55
65
|
to $stderr when loaded.
|
56
66
|
|
57
67
|
$ DEBUG=1 ruby -e 'require "cgi"'
|
58
|
-
*** CGIAlt: release 0.0.
|
68
|
+
*** CGIAlt: release 0.0.2
|
59
69
|
|
60
70
|
|
61
71
|
== Benchmark
|
@@ -92,8 +102,9 @@ The following is an example of benchmark.
|
|
92
102
|
CGI#header (simple) 6.0400 0.0100 6.0500 ( 6.0553)
|
93
103
|
CGI#header (complex) 36.2200 0.0400 36.2600 ( 36.3138)
|
94
104
|
|
105
|
+
|
95
106
|
It is good thing for performance to install CGIExt as well as CGIAlt.
|
96
|
-
The following is
|
107
|
+
The following is a benchmark example of using both CGIAlt and CGIExt.
|
97
108
|
|
98
109
|
## CGIAlt and CGIExt
|
99
110
|
$ ruby -s bench.rb -N=1000 -cgialt -cgiext
|
@@ -110,16 +121,28 @@ The following is an benchmark example of using both CGIAlt and CGIExt.
|
|
110
121
|
CGI#header (simple) 6.0300 0.0100 6.0400 ( 6.0651)
|
111
122
|
CGI#header (complex) 36.5400 0.0800 36.6200 ( 37.0642)
|
112
123
|
|
124
|
+
|
113
125
|
The following is a summary of above benchmark results.
|
114
126
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
127
|
+
Table 1. summary of benchmark
|
128
|
+
cgi.rb CGIAlt CGIAlt+CGIExt
|
129
|
+
---------------------------------------------------------------------------
|
130
|
+
require "cgi" (x1000) 13.16 7.89 ( 67%) 9.18 ( 43%)
|
131
|
+
CGI#new (simple) (x100000) 20.34 14.53 ( 40%) 12.46 ( 63%)
|
132
|
+
CGI#new (comple) (x100000) 26.62 20.10 ( 32%) 13.19 (102%)
|
133
|
+
CGI#header (simple) (x1000000) 12.68 6.05 (110%) 6.04 (110%)
|
134
|
+
CGI#header (complex) (x1000000) 43.52 36.26 ( 20%) 36.62 ( 19%)
|
135
|
+
|
136
|
+
|
137
|
+
Another benchmark script 'bench.fcgi' is provided. It is for FastCGI.
|
138
|
+
The following is an example result of benchmark.
|
139
|
+
|
140
|
+
Table 2. result of bench.fcgi
|
141
|
+
Time taken for tests Request per second
|
142
|
+
--------------------------------------------------------------------------
|
143
|
+
cgi + fcgi 16.686 [sec] 1198.61 [#/sec]
|
144
|
+
cgialt + cgialt/fcgi 15.562 [sec] 1285.18 [#/sec]
|
145
|
+
cgialt + cgialt/fcgi + cgiext 15.310 [sec] 1306.34 [#/sec]
|
123
146
|
|
124
147
|
|
125
148
|
== License
|
@@ -127,7 +150,7 @@ The following is a summary of above benchmark results.
|
|
127
150
|
Ruby's license
|
128
151
|
|
129
152
|
|
130
|
-
==
|
153
|
+
== Author
|
131
154
|
|
132
155
|
makoto kuwata <kwa(at)kuwata-lab.com>
|
133
156
|
|
data/bench.rb
CHANGED
data/lib/cgialt/cookie.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
##
|
2
|
-
## copyright(c) 2007 kuwata-lab.com all rights reserved.
|
3
|
-
##
|
4
2
|
## Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
|
5
3
|
##
|
6
4
|
## Copyright (C) 2000 Information-technology Promotion Agency, Japan
|
@@ -9,6 +7,9 @@
|
|
9
7
|
##
|
10
8
|
## Documentation: Wakou Aoyama (RDoc'd and embellished by William Webber)
|
11
9
|
##
|
10
|
+
## $Rev: 32 $
|
11
|
+
## $Release: 0.0.2 $
|
12
|
+
## copyright(c) 2007 kuwata-lab.com all rights reserved.
|
12
13
|
|
13
14
|
class CGI
|
14
15
|
|
@@ -77,13 +78,13 @@ class CGI
|
|
77
78
|
if name.is_a?(String)
|
78
79
|
@name = name
|
79
80
|
@value = value # value is an Array
|
80
|
-
@path = rexp.match(
|
81
|
+
@path = rexp.match($CGI_ENV['SCRIPT_NAME']) ? $& : ''
|
81
82
|
@secure = false
|
82
83
|
else
|
83
84
|
options = name
|
84
85
|
@name = options['name'] or raise ArgumentError, "`name' required"
|
85
86
|
@value = Array(options['value'])
|
86
|
-
@path = options['path'] || (rexp.match(
|
87
|
+
@path = options['path'] || (rexp.match($CGI_ENV['SCRIPT_NAME']) ? $& : '') # simple support for IE
|
87
88
|
@domain = options['domain']
|
88
89
|
@expires = options['expires']
|
89
90
|
@secure = options['secure'] == true
|
data/lib/cgialt/core.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
##
|
2
|
-
## copyright(c) 2007 kuwata-lab.com all rights reserved.
|
3
|
-
##
|
4
2
|
## Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
|
5
3
|
##
|
6
4
|
## Copyright (C) 2000 Information-technology Promotion Agency, Japan
|
@@ -9,6 +7,9 @@
|
|
9
7
|
##
|
10
8
|
## Documentation: Wakou Aoyama (RDoc'd and embellished by William Webber)
|
11
9
|
##
|
10
|
+
## $Rev: 32 $
|
11
|
+
## $Release: 0.0.2 $
|
12
|
+
## copyright(c) 2007 kuwata-lab.com all rights reserved.
|
12
13
|
|
13
14
|
raise "Please, use ruby 1.5.4 or later." if RUBY_VERSION < "1.5.4"
|
14
15
|
|
@@ -257,6 +258,8 @@ class CGI
|
|
257
258
|
|
258
259
|
# :stopdoc:
|
259
260
|
|
261
|
+
$CGI_ENV = ENV # for FCGI support
|
262
|
+
|
260
263
|
EOL = "\r\n"
|
261
264
|
#*** original
|
262
265
|
#*# String for carriage return
|
@@ -268,7 +271,7 @@ class CGI
|
|
268
271
|
#*# Standard internet newline sequence
|
269
272
|
#*EOL = CR + LF
|
270
273
|
#*
|
271
|
-
#*REVISION = '$Id: core.rb
|
274
|
+
#*REVISION = '$Id: core.rb 32 2007-12-11 04:22:35Z kwatch $' #:nodoc:
|
272
275
|
#*
|
273
276
|
#*NEEDS_BINMODE = true if /WIN/ni.match(RUBY_PLATFORM)
|
274
277
|
#*
|
@@ -309,14 +312,24 @@ class CGI
|
|
309
312
|
def env_table
|
310
313
|
ENV
|
311
314
|
end
|
315
|
+
#*** original
|
316
|
+
#*def env_table
|
317
|
+
#* ENV
|
318
|
+
#*end
|
319
|
+
#/*** original
|
312
320
|
|
313
321
|
def stdinput
|
314
322
|
$stdin
|
315
323
|
end
|
316
324
|
|
317
325
|
def stdoutput
|
318
|
-
$
|
326
|
+
$stdout
|
319
327
|
end
|
328
|
+
#*** original
|
329
|
+
#*def stdoutput
|
330
|
+
#* $DEFAULT_OUTPUT
|
331
|
+
#*end
|
332
|
+
#*** /original
|
320
333
|
|
321
334
|
private :env_table, :stdinput, :stdoutput
|
322
335
|
|
@@ -424,9 +437,9 @@ class CGI
|
|
424
437
|
def _header_for_string(content_type) #:nodoc:
|
425
438
|
buf = ''
|
426
439
|
if nph?()
|
427
|
-
buf << "#{
|
440
|
+
buf << "#{$CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'} 200 OK#{EOL}"
|
428
441
|
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
|
429
|
-
buf << "Server: #{
|
442
|
+
buf << "Server: #{$CGI_ENV['SERVER_SOFTWARE']}#{EOL}"
|
430
443
|
buf << "Connection: close#{EOL}"
|
431
444
|
end
|
432
445
|
buf << "Content-Type: #{content_type}#{EOL}"
|
@@ -446,12 +459,12 @@ class CGI
|
|
446
459
|
## NPH
|
447
460
|
options.delete('nph') if defined?(MOD_RUBY)
|
448
461
|
if options.delete('nph') || nph?()
|
449
|
-
protocol =
|
462
|
+
protocol = $CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'
|
450
463
|
status = options.delete('status')
|
451
464
|
status = HTTP_STATUS[status] || status || '200 OK'
|
452
465
|
buf << "#{protocol} #{status}#{EOL}"
|
453
466
|
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
|
454
|
-
options['server'] ||=
|
467
|
+
options['server'] ||= $CGI_ENV['SERVER_SOFTWARE'] || ''
|
455
468
|
options['connection'] ||= 'close'
|
456
469
|
end
|
457
470
|
## common headers
|
@@ -494,7 +507,7 @@ class CGI
|
|
494
507
|
private :_header_for_hash
|
495
508
|
|
496
509
|
def nph? #:nodoc:
|
497
|
-
return /IIS\/(\d+)/n.match(
|
510
|
+
return /IIS\/(\d+)/n.match($CGI_ENV['SERVER_SOFTWARE']) && $1.to_i < 5
|
498
511
|
end
|
499
512
|
|
500
513
|
def _header_for_modruby(buf) #:nodoc:
|
@@ -702,7 +715,7 @@ class CGI
|
|
702
715
|
content = convert_content(content, options)
|
703
716
|
options['length'] = content.length.to_s
|
704
717
|
stdout.print header(options)
|
705
|
-
stdout.print content unless
|
718
|
+
stdout.print content unless $CGI_ENV['REQUEST_METHOD'] == 'HEAD'
|
706
719
|
end
|
707
720
|
def convert_content(content, options) #:nodoc:
|
708
721
|
charset = options['charset']
|
@@ -823,88 +836,88 @@ class CGI
|
|
823
836
|
module QueryExtension
|
824
837
|
|
825
838
|
## return Integer(ENV['CONTENT_LENGTH'])
|
826
|
-
def content_length ; return Integer(
|
839
|
+
def content_length ; return Integer($CGI_ENV['CONTENT_LENGTH']) ; end
|
827
840
|
|
828
841
|
## return Integer(ENV['SERVER_PORT'])
|
829
|
-
def server_port ; return Integer(
|
842
|
+
def server_port ; return Integer($CGI_ENV['SERVER_PORT']) ; end
|
830
843
|
|
831
844
|
## return ENV['AUTH_TYPE']
|
832
|
-
def auth_type ; return
|
845
|
+
def auth_type ; return $CGI_ENV['AUTH_TYPE'] ; end
|
833
846
|
|
834
847
|
## return ENV['CONTENT_TYPE']
|
835
|
-
def content_type ; return
|
848
|
+
def content_type ; return $CGI_ENV['CONTENT_TYPE'] ; end
|
836
849
|
|
837
850
|
## return ENV['GATEWAY_INTERFACE']
|
838
|
-
def gateway_interface ; return
|
851
|
+
def gateway_interface ; return $CGI_ENV['GATEWAY_INTERFACE'] ; end
|
839
852
|
|
840
853
|
## return ENV['PATH_INFO']
|
841
|
-
def path_info ; return
|
854
|
+
def path_info ; return $CGI_ENV['PATH_INFO'] ; end
|
842
855
|
|
843
856
|
## return ENV['PATH_TRANSLATED']
|
844
|
-
def path_translated ; return
|
857
|
+
def path_translated ; return $CGI_ENV['PATH_TRANSLATED'] ; end
|
845
858
|
|
846
859
|
## return ENV['QUERY_STRING']
|
847
|
-
def query_string ; return
|
860
|
+
def query_string ; return $CGI_ENV['QUERY_STRING'] ; end
|
848
861
|
|
849
862
|
## return ENV['REMOTE_ADDR']
|
850
|
-
def remote_addr ; return
|
863
|
+
def remote_addr ; return $CGI_ENV['REMOTE_ADDR'] ; end
|
851
864
|
|
852
865
|
## return ENV['REMOTE_HOST']
|
853
|
-
def remote_host ; return
|
866
|
+
def remote_host ; return $CGI_ENV['REMOTE_HOST'] ; end
|
854
867
|
|
855
868
|
## return ENV['REMOTE_IDENT']
|
856
|
-
def remote_ident ; return
|
869
|
+
def remote_ident ; return $CGI_ENV['REMOTE_IDENT'] ; end
|
857
870
|
|
858
871
|
## return ENV['REMOTE_USER']
|
859
|
-
def remote_user ; return
|
872
|
+
def remote_user ; return $CGI_ENV['REMOTE_USER'] ; end
|
860
873
|
|
861
874
|
## return ENV['REQUEST_METHOD']
|
862
|
-
def request_method ; return
|
875
|
+
def request_method ; return $CGI_ENV['REQUEST_METHOD'] ; end
|
863
876
|
|
864
877
|
## return ENV['SCRIPT_NAME']
|
865
|
-
def script_name ; return
|
878
|
+
def script_name ; return $CGI_ENV['SCRIPT_NAME'] ; end
|
866
879
|
|
867
880
|
## return ENV['SERVER_NAME']
|
868
|
-
def server_name ; return
|
881
|
+
def server_name ; return $CGI_ENV['SERVER_NAME'] ; end
|
869
882
|
|
870
883
|
## return ENV['SERVER_PROTOCOL']
|
871
|
-
def server_protocol ; return
|
884
|
+
def server_protocol ; return $CGI_ENV['SERVER_PROTOCOL'] ; end
|
872
885
|
|
873
886
|
## return ENV['SERVER_SOFTWARE']
|
874
|
-
def server_software ; return
|
887
|
+
def server_software ; return $CGI_ENV['SERVER_SOFTWARE'] ; end
|
875
888
|
|
876
889
|
## return ENV['HTTP_ACCEPT']
|
877
|
-
def accept ; return
|
890
|
+
def accept ; return $CGI_ENV['HTTP_ACCEPT'] ; end
|
878
891
|
|
879
892
|
## return ENV['HTTP_ACCEPT_CHARSET']
|
880
|
-
def accept_charset ; return
|
893
|
+
def accept_charset ; return $CGI_ENV['HTTP_ACCEPT_CHARSET'] ; end
|
881
894
|
|
882
895
|
## return ENV['HTTP_ACCEPT_ENCODING']
|
883
|
-
def accept_encoding ; return
|
896
|
+
def accept_encoding ; return $CGI_ENV['HTTP_ACCEPT_ENCODING'] ; end
|
884
897
|
|
885
898
|
## return ENV['HTTP_ACCEPT_LANGUAGE']
|
886
|
-
def accept_language ; return
|
899
|
+
def accept_language ; return $CGI_ENV['HTTP_ACCEPT_LANGUAGE'] ; end
|
887
900
|
|
888
901
|
## return ENV['HTTP_CACHE_CONTROL']
|
889
|
-
def cache_control ; return
|
902
|
+
def cache_control ; return $CGI_ENV['HTTP_CACHE_CONTROL'] ; end
|
890
903
|
|
891
904
|
## return ENV['HTTP_FROM']
|
892
|
-
def from ; return
|
905
|
+
def from ; return $CGI_ENV['HTTP_FROM'] ; end
|
893
906
|
|
894
907
|
## return ENV['HTTP_HOST']
|
895
|
-
def host ; return
|
908
|
+
def host ; return $CGI_ENV['HTTP_HOST'] ; end
|
896
909
|
|
897
910
|
## return ENV['HTTP_NEGOTIATE']
|
898
|
-
def negotiate ; return
|
911
|
+
def negotiate ; return $CGI_ENV['HTTP_NEGOTIATE'] ; end
|
899
912
|
|
900
913
|
## return ENV['HTTP_PRAGMA']
|
901
|
-
def pragma ; return
|
914
|
+
def pragma ; return $CGI_ENV['HTTP_PRAGMA'] ; end
|
902
915
|
|
903
916
|
## return ENV['HTTP_REFERER']
|
904
|
-
def referer ; return
|
917
|
+
def referer ; return $CGI_ENV['HTTP_REFERER'] ; end
|
905
918
|
|
906
919
|
## return ENV['HTTP_USER_AGENT']
|
907
|
-
def user_agent ; return
|
920
|
+
def user_agent ; return $CGI_ENV['HTTP_USER_AGENT'] ; end
|
908
921
|
|
909
922
|
#*** orignal
|
910
923
|
#*%w[ CONTENT_LENGTH SERVER_PORT ].each do |env|
|
@@ -929,7 +942,7 @@ class CGI
|
|
929
942
|
|
930
943
|
# Get the raw cookies as a string.
|
931
944
|
def raw_cookie
|
932
|
-
return
|
945
|
+
return $CGI_ENV['HTTP_COOKIE']
|
933
946
|
end
|
934
947
|
#*** original
|
935
948
|
#*def raw_cookie
|
@@ -939,7 +952,7 @@ class CGI
|
|
939
952
|
|
940
953
|
# Get the raw RFC2965 cookies as a string.
|
941
954
|
def raw_cookie2
|
942
|
-
return
|
955
|
+
return $CGI_ENV['HTTP_COOKIE2']
|
943
956
|
end
|
944
957
|
#*** original
|
945
958
|
#*def raw_cookie2
|
@@ -1064,7 +1077,7 @@ class CGI
|
|
1064
1077
|
return body
|
1065
1078
|
end
|
1066
1079
|
def unescape_filename? #:nodoc:
|
1067
|
-
user_agent =
|
1080
|
+
user_agent = $CGI_ENV['HTTP_USER_AGENT']
|
1068
1081
|
return /Mac/ni.match(user_agent) && /Mozilla/ni.match(user_agent) && !/MSIE/ni.match(user_agent)
|
1069
1082
|
end
|
1070
1083
|
#*** original
|
@@ -1222,16 +1235,16 @@ class CGI
|
|
1222
1235
|
# Handles multipart forms (in particular, forms that involve file uploads).
|
1223
1236
|
# Reads query parameters in the @params field, and cookies into @cookies.
|
1224
1237
|
def initialize_query()
|
1225
|
-
case
|
1238
|
+
case $CGI_ENV['REQUEST_METHOD']
|
1226
1239
|
when 'GET', 'HEAD'
|
1227
|
-
query_str = defined?(MOD_RUBY) ? Apache::request.args :
|
1240
|
+
query_str = defined?(MOD_RUBY) ? Apache::request.args : $CGI_ENV['QUERY_STRING']
|
1228
1241
|
@params = CGI.parse(query_str || '')
|
1229
1242
|
@multipart = false
|
1230
1243
|
when 'POST'
|
1231
|
-
content_length = Integer(
|
1232
|
-
if /\Amultipart\/form-data/.match(
|
1244
|
+
content_length = Integer($CGI_ENV['CONTENT_LENGTH'])
|
1245
|
+
if /\Amultipart\/form-data/.match($CGI_ENV['CONTENT_TYPE'])
|
1233
1246
|
raise StandardError.new("too large multipart data.") if content_length > MAX_MULTIPART_LENGTH
|
1234
|
-
unless /boundary=(?:"([^";,]+?)"|([^;,\s]+))/.match(
|
1247
|
+
unless /boundary=(?:"([^";,]+?)"|([^;,\s]+))/.match($CGI_ENV['CONTENT_TYPE'])
|
1235
1248
|
raise StandardError.new("no boundary of multipart data.")
|
1236
1249
|
end
|
1237
1250
|
boundary = $1 || $2
|
@@ -1249,7 +1262,7 @@ class CGI
|
|
1249
1262
|
@params = Hash.new([].freeze)
|
1250
1263
|
@multipart = false
|
1251
1264
|
end
|
1252
|
-
@cookies = CGI::Cookie.parse(
|
1265
|
+
@cookies = CGI::Cookie.parse($CGI_ENV['HTTP_COOKIE'] || $CGI_ENV['COOKIE'])
|
1253
1266
|
nil
|
1254
1267
|
end
|
1255
1268
|
private :initialize_query
|
@@ -1383,7 +1396,7 @@ class CGI
|
|
1383
1396
|
# cookies and other parameters are parsed automatically from the standard
|
1384
1397
|
# CGI locations, which varies according to the REQUEST_METHOD.
|
1385
1398
|
def initialize(type=nil)
|
1386
|
-
if defined?(MOD_RUBY) &&
|
1399
|
+
if defined?(MOD_RUBY) && !$CGI_ENV['GATEWAY_INTERFACE']
|
1387
1400
|
Apache.request.setup_cgi_env
|
1388
1401
|
end
|
1389
1402
|
##
|
@@ -0,0 +1,102 @@
|
|
1
|
+
##
|
2
|
+
## $Rev: 33 $
|
3
|
+
## $Release: 0.0.2 $
|
4
|
+
## copyright(c) 2007 kuwata-lab.com all rights reserved.
|
5
|
+
##
|
6
|
+
|
7
|
+
=begin
|
8
|
+
|
9
|
+
fcgi.rb 0.8.5 - fcgi.so compatible pure-ruby FastCGI library
|
10
|
+
|
11
|
+
fastcgi.rb Copyright (C) 2001 Eli Green
|
12
|
+
fcgi.rb Copyright (C) 2002-2003 MoonWolf <moonwolf@moonwolf.com>
|
13
|
+
fcgi.rb Copyright (C) 2004 Minero Aoki
|
14
|
+
|
15
|
+
=end
|
16
|
+
|
17
|
+
require 'cgialt' unless defined?(CGI)
|
18
|
+
|
19
|
+
class FCGI
|
20
|
+
|
21
|
+
if FCGI.is_cgi?
|
22
|
+
def FCGI.each_cgi(arg=nil)
|
23
|
+
#require 'cgialt' unless defined?(CGI)
|
24
|
+
yield CGI.new(arg)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
def FCGI.each_cgi(arg=nil)
|
28
|
+
#require 'cgialt' unless defined?(CGI)
|
29
|
+
#exit_requested = false
|
30
|
+
FCGI.each do |request|
|
31
|
+
$FCGI_REQUEST = request
|
32
|
+
$stdout = request.out
|
33
|
+
$stderr = request.err
|
34
|
+
#ENV.clear
|
35
|
+
#ENV.update(request.env)
|
36
|
+
$CGI_ENV = request.env
|
37
|
+
yield CGI.new(arg)
|
38
|
+
request.finish
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
#*** original
|
45
|
+
#*# There is no C version of 'each_cgi'
|
46
|
+
#*# Note: for ruby-1.6.8 at least, the constants CGI_PARAMS/CGI_COOKIES
|
47
|
+
#*# are defined within module 'CGI', even if you have subclassed it
|
48
|
+
#*
|
49
|
+
#*class FCGI
|
50
|
+
#* def self::each_cgi(*args)
|
51
|
+
#* require 'cgi'
|
52
|
+
#*
|
53
|
+
#* eval(<<-EOS,TOPLEVEL_BINDING)
|
54
|
+
#* class CGI
|
55
|
+
#* public :env_table
|
56
|
+
#* def self::remove_params
|
57
|
+
#* if (const_defined?(:CGI_PARAMS))
|
58
|
+
#* remove_const(:CGI_PARAMS)
|
59
|
+
#* remove_const(:CGI_COOKIES)
|
60
|
+
#* end
|
61
|
+
#* end
|
62
|
+
#* end # ::CGI class
|
63
|
+
#*
|
64
|
+
#* class FCGI
|
65
|
+
#* class CGI < ::CGI
|
66
|
+
#* def initialize(request, *args)
|
67
|
+
#* ::CGI.remove_params
|
68
|
+
#* @request = request
|
69
|
+
#* super(*args)
|
70
|
+
#* @args = *args
|
71
|
+
#* end
|
72
|
+
#* def args
|
73
|
+
#* @args
|
74
|
+
#* end
|
75
|
+
#* def env_table
|
76
|
+
#* @request.env
|
77
|
+
#* end
|
78
|
+
#* def stdinput
|
79
|
+
#* @request.in
|
80
|
+
#* end
|
81
|
+
#* def stdoutput
|
82
|
+
#* @request.out
|
83
|
+
#* end
|
84
|
+
#* end # FCGI::CGI class
|
85
|
+
#* end # FCGI class
|
86
|
+
#* EOS
|
87
|
+
#*
|
88
|
+
#* if FCGI::is_cgi?
|
89
|
+
#* yield ::CGI.new(*args)
|
90
|
+
#* else
|
91
|
+
#* exit_requested = false
|
92
|
+
#* FCGI::each {|request|
|
93
|
+
#* $stdout, $stderr = request.out, request.err
|
94
|
+
#*
|
95
|
+
#* yield CGI.new(request, *args)
|
96
|
+
#*
|
97
|
+
#* request.finish
|
98
|
+
#* }
|
99
|
+
#* end
|
100
|
+
#* end
|
101
|
+
#*end
|
102
|
+
#*** /original
|
@@ -0,0 +1,561 @@
|
|
1
|
+
##
|
2
|
+
## $Rev: 33 $
|
3
|
+
## $Release: 0.0.2 $
|
4
|
+
## copyright(c) 2007 kuwata-lab.com all rights reserved.
|
5
|
+
##
|
6
|
+
|
7
|
+
=begin
|
8
|
+
|
9
|
+
fcgi.rb 0.8.5 - fcgi.so compatible pure-ruby FastCGI library
|
10
|
+
|
11
|
+
fastcgi.rb Copyright (C) 2001 Eli Green
|
12
|
+
fcgi.rb Copyright (C) 2002-2003 MoonWolf <moonwolf@moonwolf.com>
|
13
|
+
fcgi.rb Copyright (C) 2004 Minero Aoki
|
14
|
+
|
15
|
+
=end
|
16
|
+
|
17
|
+
|
18
|
+
require 'socket'
|
19
|
+
require 'stringio'
|
20
|
+
|
21
|
+
class FCGI
|
22
|
+
|
23
|
+
def self::is_cgi?
|
24
|
+
begin
|
25
|
+
s = Socket.for_fd($stdin.fileno)
|
26
|
+
s.getpeername
|
27
|
+
false
|
28
|
+
rescue Errno::ENOTCONN
|
29
|
+
false
|
30
|
+
rescue Errno::ENOTSOCK, Errno::EINVAL
|
31
|
+
true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self::each(&block)
|
36
|
+
f = default_connection()
|
37
|
+
Server.new(f).each_request(&block)
|
38
|
+
ensure
|
39
|
+
f.close if f
|
40
|
+
end
|
41
|
+
|
42
|
+
def self::each_request(&block)
|
43
|
+
f = default_connection()
|
44
|
+
Server.new(f).each_request(&block)
|
45
|
+
ensure
|
46
|
+
f.close if f
|
47
|
+
end
|
48
|
+
|
49
|
+
def self::default_connection
|
50
|
+
::Socket.for_fd($stdin.fileno)
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
ProtocolVersion = 1
|
56
|
+
|
57
|
+
# Record types
|
58
|
+
FCGI_BEGIN_REQUEST = 1
|
59
|
+
FCGI_ABORT_REQUEST = 2
|
60
|
+
FCGI_END_REQUEST = 3
|
61
|
+
FCGI_PARAMS = 4
|
62
|
+
FCGI_STDIN = 5
|
63
|
+
FCGI_STDOUT = 6
|
64
|
+
FCGI_STDERR = 7
|
65
|
+
FCGI_DATA = 8
|
66
|
+
FCGI_GET_VALUES = 9
|
67
|
+
FCGI_GET_VALUES_RESULT = 10
|
68
|
+
FCGI_UNKNOWN_TYPE = 11
|
69
|
+
FCGI_MAXTYPE = FCGI_UNKNOWN_TYPE
|
70
|
+
|
71
|
+
FCGI_NULL_REQUEST_ID = 0
|
72
|
+
|
73
|
+
# FCGI_BEGIN_REQUSET.role
|
74
|
+
FCGI_RESPONDER = 1
|
75
|
+
FCGI_AUTHORIZER = 2
|
76
|
+
FCGI_FILTER = 3
|
77
|
+
|
78
|
+
# FCGI_BEGIN_REQUEST.flags
|
79
|
+
FCGI_KEEP_CONN = 1
|
80
|
+
|
81
|
+
# FCGI_END_REQUEST.protocolStatus
|
82
|
+
FCGI_REQUEST_COMPLETE = 0
|
83
|
+
FCGI_CANT_MPX_CONN = 1
|
84
|
+
FCGI_OVERLOADED = 2
|
85
|
+
FCGI_UNKNOWN_ROLE = 3
|
86
|
+
|
87
|
+
|
88
|
+
class Server
|
89
|
+
|
90
|
+
def initialize(server)
|
91
|
+
@server = server
|
92
|
+
@buffers = {}
|
93
|
+
@default_parameters = {
|
94
|
+
"FCGI_MAX_CONNS" => 1,
|
95
|
+
"FCGI_MAX_REQS" => 1,
|
96
|
+
"FCGI_MPX_CONNS" => true
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
def each_request(&block)
|
101
|
+
graceful = false
|
102
|
+
trap("SIGUSR1") { graceful = true }
|
103
|
+
while true
|
104
|
+
begin
|
105
|
+
session(&block)
|
106
|
+
rescue Errno::EPIPE, EOFError
|
107
|
+
# HTTP request is canceled by the remote user
|
108
|
+
end
|
109
|
+
exit 0 if graceful
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def session
|
114
|
+
sock, addr = *@server.accept
|
115
|
+
return unless sock
|
116
|
+
fsock = FastCGISocket.new(sock)
|
117
|
+
req = next_request(fsock)
|
118
|
+
yield req
|
119
|
+
respond_to req, fsock, FCGI_REQUEST_COMPLETE
|
120
|
+
ensure
|
121
|
+
sock.close if sock and not sock.closed?
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def next_request(sock)
|
127
|
+
while rec = sock.read_record
|
128
|
+
if rec.management_record?
|
129
|
+
case rec.type
|
130
|
+
when FCGI_GET_VALUES
|
131
|
+
sock.send_record handle_GET_VALUES(rec)
|
132
|
+
else
|
133
|
+
sock.send_record UnknownTypeRecord.new(rec.request_id, rec.type)
|
134
|
+
end
|
135
|
+
else
|
136
|
+
case rec.type
|
137
|
+
when FCGI_BEGIN_REQUEST
|
138
|
+
@buffers[rec.request_id] = RecordBuffer.new(rec)
|
139
|
+
when FCGI_ABORT_REQUEST
|
140
|
+
raise "got ABORT_REQUEST" # FIXME
|
141
|
+
else
|
142
|
+
buf = @buffers[rec.request_id] or next # inactive request
|
143
|
+
buf.push rec
|
144
|
+
if buf.ready?
|
145
|
+
@buffers.delete rec.request_id
|
146
|
+
return buf.new_request
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
raise "must not happen: FCGI socket unexpected EOF"
|
152
|
+
end
|
153
|
+
|
154
|
+
def handle_GET_VALUES(rec)
|
155
|
+
h = {}
|
156
|
+
rec.values.each_key do |name|
|
157
|
+
h[name] = @default_parameters[name]
|
158
|
+
end
|
159
|
+
ValuesRecord.new(FCGI_GET_VALUES_RESULT, rec.request_id, h)
|
160
|
+
end
|
161
|
+
|
162
|
+
def respond_to(req, sock, status)
|
163
|
+
split_data(FCGI_STDOUT, req.id, req.out) do |rec|
|
164
|
+
sock.send_record rec
|
165
|
+
end
|
166
|
+
split_data(FCGI_STDERR, req.id, req.err) do |rec|
|
167
|
+
sock.send_record rec
|
168
|
+
end if req.err.length > 0
|
169
|
+
sock.send_record EndRequestRecord.new(req.id, 0, status)
|
170
|
+
end
|
171
|
+
|
172
|
+
DATA_UNIT = 16384
|
173
|
+
|
174
|
+
def split_data(type, id, f)
|
175
|
+
unless f.length == 0
|
176
|
+
f.rewind
|
177
|
+
while s = f.read(DATA_UNIT)
|
178
|
+
yield GenericDataRecord.new(type, id, s)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
yield GenericDataRecord.new(type, id, '')
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
class FastCGISocket
|
188
|
+
def initialize(sock)
|
189
|
+
@socket = sock
|
190
|
+
end
|
191
|
+
|
192
|
+
def read_record
|
193
|
+
header = @socket.read(Record::HEADER_LENGTH) or return nil
|
194
|
+
return nil unless header.size == Record::HEADER_LENGTH
|
195
|
+
version, type, reqid, clen, padlen, reserved = *Record.parse_header(header)
|
196
|
+
Record.class_for(type).parse(reqid, read_record_body(clen, padlen))
|
197
|
+
end
|
198
|
+
|
199
|
+
def read_record_body(clen, padlen)
|
200
|
+
buf = ''
|
201
|
+
while buf.length < clen
|
202
|
+
buf << @socket.read([1024, clen - buf.length].min)
|
203
|
+
end
|
204
|
+
@socket.read padlen if padlen
|
205
|
+
buf
|
206
|
+
end
|
207
|
+
private :read_record_body
|
208
|
+
|
209
|
+
def send_record(rec)
|
210
|
+
@socket.write rec.serialize
|
211
|
+
@socket.flush
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
class RecordBuffer
|
217
|
+
def initialize(rec)
|
218
|
+
@begin_request = rec
|
219
|
+
@envs = []
|
220
|
+
@stdins = []
|
221
|
+
@datas = []
|
222
|
+
end
|
223
|
+
|
224
|
+
def push(rec)
|
225
|
+
case rec
|
226
|
+
when ParamsRecord
|
227
|
+
@envs.push rec
|
228
|
+
when StdinDataRecord
|
229
|
+
@stdins.push rec
|
230
|
+
when DataRecord
|
231
|
+
@datas.push rec
|
232
|
+
else
|
233
|
+
raise "got unknown record: #{rec.class}"
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def ready?
|
238
|
+
case @begin_request.role
|
239
|
+
when FCGI_RESPONDER
|
240
|
+
completed?(@envs) and
|
241
|
+
completed?(@stdins)
|
242
|
+
when FCGI_AUTHORIZER
|
243
|
+
completed?(@envs)
|
244
|
+
when FCGI_FILTER
|
245
|
+
completed?(@envs) and
|
246
|
+
completed?(@stdins) and
|
247
|
+
completed?(@datas)
|
248
|
+
else
|
249
|
+
raise "unknown role: #{@begin_request.role}"
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def completed?(records)
|
254
|
+
records.last and records.last.empty?
|
255
|
+
end
|
256
|
+
private :completed?
|
257
|
+
|
258
|
+
def new_request
|
259
|
+
Request.new(@begin_request.request_id, env(), stdin(), nil, nil, data())
|
260
|
+
end
|
261
|
+
|
262
|
+
def env
|
263
|
+
h = {}
|
264
|
+
@envs.each {|rec| h.update rec.values }
|
265
|
+
h
|
266
|
+
end
|
267
|
+
|
268
|
+
def stdin
|
269
|
+
StringIO.new(@stdins.inject('') {|buf, rec| buf << rec.flagment })
|
270
|
+
end
|
271
|
+
|
272
|
+
def data
|
273
|
+
StringIO.new(@datas.inject('') {|buf, rec| buf << rec.flagment })
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
class Request
|
279
|
+
def initialize(id, env, stdin, stdout = nil, stderr = nil, data = nil)
|
280
|
+
@id = id
|
281
|
+
@env = env
|
282
|
+
@in = stdin
|
283
|
+
@out = stdout || StringIO.new
|
284
|
+
@err = stderr || StringIO.new
|
285
|
+
@data = data || StringIO.new
|
286
|
+
end
|
287
|
+
|
288
|
+
attr_reader :id
|
289
|
+
attr_reader :env
|
290
|
+
attr_reader :in
|
291
|
+
attr_reader :out
|
292
|
+
attr_reader :err
|
293
|
+
attr_reader :data
|
294
|
+
|
295
|
+
def finish # for backword compatibility
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
|
300
|
+
class Record
|
301
|
+
# uint8_t protocol_version;
|
302
|
+
# uint8_t record_type;
|
303
|
+
# uint16_t request_id; (big endian)
|
304
|
+
# uint16_t content_length; (big endian)
|
305
|
+
# uint8_t padding_length;
|
306
|
+
# uint8_t reserved;
|
307
|
+
HEADER_FORMAT = 'CCnnCC'
|
308
|
+
HEADER_LENGTH = 8
|
309
|
+
|
310
|
+
def self::parse_header(buf)
|
311
|
+
return *buf.unpack(HEADER_FORMAT)
|
312
|
+
end
|
313
|
+
|
314
|
+
def self::class_for(type)
|
315
|
+
RECORD_CLASS[type]
|
316
|
+
end
|
317
|
+
|
318
|
+
def initialize(type, reqid)
|
319
|
+
@type = type
|
320
|
+
@request_id = reqid
|
321
|
+
end
|
322
|
+
|
323
|
+
def version
|
324
|
+
::FCGI::ProtocolVersion
|
325
|
+
end
|
326
|
+
|
327
|
+
attr_reader :type
|
328
|
+
attr_reader :request_id
|
329
|
+
|
330
|
+
def management_record?
|
331
|
+
@request_id == FCGI_NULL_REQUEST_ID
|
332
|
+
end
|
333
|
+
|
334
|
+
def serialize
|
335
|
+
body = make_body()
|
336
|
+
padlen = body.length % 8
|
337
|
+
header = make_header(body.length, padlen)
|
338
|
+
header + body + "\000" * padlen
|
339
|
+
end
|
340
|
+
|
341
|
+
private
|
342
|
+
|
343
|
+
def make_header(clen, padlen)
|
344
|
+
[version(), @type, @request_id, clen, padlen, 0].pack(HEADER_FORMAT)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
class BeginRequestRecord < Record
|
349
|
+
# uint16_t role; (big endian)
|
350
|
+
# uint8_t flags;
|
351
|
+
# uint8_t reserved[5];
|
352
|
+
BODY_FORMAT = 'nCC5'
|
353
|
+
|
354
|
+
def BeginRequestRecord.parse(id, body)
|
355
|
+
role, flags, *reserved = *body.unpack(BODY_FORMAT)
|
356
|
+
new(id, role, flags)
|
357
|
+
end
|
358
|
+
|
359
|
+
def initialize(id, role, flags)
|
360
|
+
super FCGI_BEGIN_REQUEST, id
|
361
|
+
@role = role
|
362
|
+
@flags = flags
|
363
|
+
end
|
364
|
+
|
365
|
+
attr_reader :role
|
366
|
+
attr_reader :flags
|
367
|
+
|
368
|
+
def make_body
|
369
|
+
[@role, @flags, 0, 0, 0, 0, 0].pack(BODY_FORMAT)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
class AbortRequestRecord < Record
|
374
|
+
def AbortRequestRecord.parse(id, body)
|
375
|
+
new(id)
|
376
|
+
end
|
377
|
+
|
378
|
+
def initialize(id)
|
379
|
+
super FCGI_ABORT_REQUEST, id
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
class EndRequestRecord < Record
|
384
|
+
# uint32_t appStatus; (big endian)
|
385
|
+
# uint8_t protocolStatus;
|
386
|
+
# uint8_t reserved[3];
|
387
|
+
BODY_FORMAT = 'NCC3'
|
388
|
+
|
389
|
+
def self::parse(id, body)
|
390
|
+
appstatus, protostatus, *reserved = *body.unpack(BODY_FORMAT)
|
391
|
+
new(id, appstatus, protostatus)
|
392
|
+
end
|
393
|
+
|
394
|
+
def initialize(id, appstatus, protostatus)
|
395
|
+
super FCGI_END_REQUEST, id
|
396
|
+
@application_status = appstatus
|
397
|
+
@protocol_status = protostatus
|
398
|
+
end
|
399
|
+
|
400
|
+
attr_reader :application_status
|
401
|
+
attr_reader :protocol_status
|
402
|
+
|
403
|
+
private
|
404
|
+
|
405
|
+
def make_body
|
406
|
+
[@application_status, @protocol_status, 0, 0, 0].pack(BODY_FORMAT)
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
class UnknownTypeRecord < Record
|
411
|
+
# uint8_t type;
|
412
|
+
# uint8_t reserved[7];
|
413
|
+
BODY_FORMAT = 'CC7'
|
414
|
+
|
415
|
+
def self::parse(id, body)
|
416
|
+
type, *reserved = *body.unpack(BODY_FORMAT)
|
417
|
+
new(id, type)
|
418
|
+
end
|
419
|
+
|
420
|
+
def initialize(id, t)
|
421
|
+
super FCGI_UNKNOWN_TYPE, id
|
422
|
+
@unknown_type = t
|
423
|
+
end
|
424
|
+
|
425
|
+
attr_reader :unknown_type
|
426
|
+
|
427
|
+
private
|
428
|
+
|
429
|
+
def make_body
|
430
|
+
[@unknown_type, 0, 0, 0, 0, 0, 0, 0].pack(BODY_FORMAT)
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
class ValuesRecord < Record
|
435
|
+
def self::parse(id, body)
|
436
|
+
new(id, parse_values(body))
|
437
|
+
end
|
438
|
+
|
439
|
+
def self::parse_values(buf)
|
440
|
+
result = {}
|
441
|
+
until buf.empty?
|
442
|
+
name, value = *read_pair(buf)
|
443
|
+
result[name] = value
|
444
|
+
end
|
445
|
+
result
|
446
|
+
end
|
447
|
+
|
448
|
+
def self::read_pair(buf)
|
449
|
+
nlen = read_length(buf)
|
450
|
+
vlen = read_length(buf)
|
451
|
+
return buf.slice!(0, nlen), buf.slice!(0, vlen)
|
452
|
+
end
|
453
|
+
|
454
|
+
def self::read_length(buf)
|
455
|
+
if buf[0] >> 7 == 0
|
456
|
+
then buf.slice!(0,1)[0]
|
457
|
+
else buf.slice!(0,4).unpack('N')[0] & ((1<<31) - 1)
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
def initialize(type, id, values)
|
462
|
+
super type, id
|
463
|
+
@values = values
|
464
|
+
end
|
465
|
+
|
466
|
+
attr_reader :values
|
467
|
+
|
468
|
+
private
|
469
|
+
|
470
|
+
def make_body
|
471
|
+
buf = ''
|
472
|
+
@values.each do |name, value|
|
473
|
+
buf << serialize_length(name.length)
|
474
|
+
buf << serialize_length(value.length)
|
475
|
+
buf << name
|
476
|
+
buf << value
|
477
|
+
end
|
478
|
+
buf
|
479
|
+
end
|
480
|
+
|
481
|
+
def serialize_length(len)
|
482
|
+
if len < 0x80
|
483
|
+
then len.chr
|
484
|
+
else [len | (1<<31)].pack('N')
|
485
|
+
end
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
class GetValuesRecord < ValuesRecord
|
490
|
+
def initialize(id, values)
|
491
|
+
super FCGI_GET_VALUES, id, values
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
class ParamsRecord < ValuesRecord
|
496
|
+
def initialize(id, values)
|
497
|
+
super FCGI_PARAMS, id, values
|
498
|
+
end
|
499
|
+
|
500
|
+
def empty?
|
501
|
+
@values.empty?
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
class GenericDataRecord < Record
|
506
|
+
def self::parse(id, body)
|
507
|
+
new(id, body)
|
508
|
+
end
|
509
|
+
|
510
|
+
def initialize(type, id, flagment)
|
511
|
+
super type, id
|
512
|
+
@flagment = flagment
|
513
|
+
end
|
514
|
+
|
515
|
+
attr_reader :flagment
|
516
|
+
|
517
|
+
def empty?
|
518
|
+
@flagment.empty?
|
519
|
+
end
|
520
|
+
|
521
|
+
private
|
522
|
+
|
523
|
+
def make_body
|
524
|
+
@flagment
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|
528
|
+
class StdinDataRecord < GenericDataRecord
|
529
|
+
def initialize(id, flagment)
|
530
|
+
super FCGI_STDIN, id, flagment
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
class StdoutDataRecord < GenericDataRecord
|
535
|
+
def initialize(id, flagment)
|
536
|
+
super FCGI_STDOUT, id, flagment
|
537
|
+
end
|
538
|
+
end
|
539
|
+
|
540
|
+
class DataRecord < GenericDataRecord
|
541
|
+
def initialize(id, flagment)
|
542
|
+
super FCGI_DATA, id, flagment
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
class Record # redefine
|
547
|
+
RECORD_CLASS = {
|
548
|
+
FCGI_GET_VALUES => GetValuesRecord,
|
549
|
+
|
550
|
+
FCGI_BEGIN_REQUEST => BeginRequestRecord,
|
551
|
+
FCGI_ABORT_REQUEST => AbortRequestRecord,
|
552
|
+
FCGI_PARAMS => ParamsRecord,
|
553
|
+
FCGI_STDIN => StdinDataRecord,
|
554
|
+
FCGI_DATA => DataRecord,
|
555
|
+
FCGI_STDOUT => StdoutDataRecord,
|
556
|
+
FCGI_END_REQUEST => EndRequestRecord
|
557
|
+
}
|
558
|
+
end
|
559
|
+
|
560
|
+
end # FCGI class
|
561
|
+
|
data/lib/cgialt/fcgi.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
##
|
2
|
+
## $Rev: 33 $
|
3
|
+
## $Release: 0.0.2 $
|
4
|
+
## copyright(c) 2007 kuwata-lab.com all rights reserved.
|
5
|
+
##
|
6
|
+
|
7
|
+
=begin
|
8
|
+
|
9
|
+
fcgi.rb 0.8.5 - fcgi.so compatible pure-ruby FastCGI library
|
10
|
+
|
11
|
+
fastcgi.rb Copyright (C) 2001 Eli Green
|
12
|
+
fcgi.rb Copyright (C) 2002-2003 MoonWolf <moonwolf@moonwolf.com>
|
13
|
+
fcgi.rb Copyright (C) 2004 Minero Aoki
|
14
|
+
|
15
|
+
=end
|
16
|
+
|
17
|
+
|
18
|
+
trap('SIGTERM') { exit }
|
19
|
+
trap('SIGPIPE', 'IGNORE')
|
20
|
+
|
21
|
+
begin
|
22
|
+
raise LoadError if defined?(FCGI_PURE_RUBY) && FCGI_PURE_RUBY
|
23
|
+
require 'fcgi.so'
|
24
|
+
rescue LoadError
|
25
|
+
require 'cgialt/fcgi/core'
|
26
|
+
end
|
27
|
+
|
28
|
+
require 'cgialt/fcgi/cgi_helper' if defined?(CGI)
|
data/lib/cgialt.rb
CHANGED
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: cgialt
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2007-12-
|
6
|
+
version: 0.0.2
|
7
|
+
date: 2007-12-11 00:00:00 +09:00
|
8
8
|
summary: an alternative of 'cgi.rb' in pure Ruby
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -32,6 +32,10 @@ files:
|
|
32
32
|
- lib/cgialt
|
33
33
|
- lib/cgialt/cookie.rb
|
34
34
|
- lib/cgialt/core.rb
|
35
|
+
- lib/cgialt/fcgi
|
36
|
+
- lib/cgialt/fcgi/cgi_helper.rb
|
37
|
+
- lib/cgialt/fcgi/core.rb
|
38
|
+
- lib/cgialt/fcgi.rb
|
35
39
|
- lib/cgialt/html.rb
|
36
40
|
- lib/cgialt/util.rb
|
37
41
|
- lib/cgialt.rb
|
@@ -47,6 +51,7 @@ files:
|
|
47
51
|
- README.txt
|
48
52
|
- bench.rb
|
49
53
|
- setup.rb
|
54
|
+
- CHANGES.txt
|
50
55
|
test_files: []
|
51
56
|
|
52
57
|
rdoc_options: []
|