cgialt 0.0.1 → 0.0.2
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/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: []
|