cgialt 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,146 @@
1
+ require 'test/unit'
2
+ #require 'cgi'
3
+ require(ENV['CGI'] || 'cgi')
4
+
5
+
6
+ class CGIModrubyTest < Test::Unit::TestCase
7
+
8
+
9
+ def setup
10
+ @environ = {
11
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
12
+ 'REQUEST_METHOD' => 'GET',
13
+ #'QUERY_STRING' => 'a=foo&b=bar',
14
+ }
15
+ ENV.update(@environ)
16
+ CGI.class_eval { const_set(:MOD_RUBY, true) }
17
+ Apache._reset()
18
+ #@cgi = CGI.new
19
+ #@req = Apache.request
20
+ end
21
+
22
+
23
+ def teardown
24
+ @environ.each do |key, val| ENV.delete(key) end
25
+ CGI.class_eval { remove_const(:MOD_RUBY) }
26
+ end
27
+
28
+
29
+ def test_cgi_modruby_simple
30
+ req = Apache.request
31
+ cgi = CGI.new
32
+ assert(req._setup_cgi_env_invoked?)
33
+ assert(! req._send_http_header_invoked?)
34
+ actual = cgi.header
35
+ assert_equal('', actual)
36
+ assert_equal('text/html', req.content_type)
37
+ assert(req._send_http_header_invoked?)
38
+ end
39
+
40
+
41
+ def test_cgi_modruby_complex
42
+ req = Apache.request
43
+ cgi = CGI.new
44
+ options = {
45
+ 'status' => 'FORBIDDEN',
46
+ 'location' => 'http://www.example.com/',
47
+ 'type' => 'image/gif',
48
+ 'content-encoding' => 'deflate',
49
+ 'cookie' => [ CGI::Cookie.new('name1', 'abc', '123'),
50
+ CGI::Cookie.new('name'=>'name2', 'value'=>'value2', 'secure'=>true),
51
+ ],
52
+ }
53
+ assert(req._setup_cgi_env_invoked?)
54
+ assert(! req._send_http_header_invoked?)
55
+ actual = cgi.header(options)
56
+ assert_equal('', actual)
57
+ assert_equal('image/gif', req.content_type)
58
+ assert_equal('403 Forbidden', req.status_line)
59
+ assert_equal(403, req.status)
60
+ assert_equal('deflate', req.content_encoding)
61
+ assert_equal('http://www.example.com/', req.headers_out['location'])
62
+ assert_equal(["name1=abc&123; path=", "name2=value2; path=; secure"],
63
+ req.headers_out['Set-Cookie'])
64
+ assert(req._send_http_header_invoked?)
65
+ end
66
+
67
+
68
+ def test_cgi_modruby_location
69
+ req = Apache.request
70
+ cgi = CGI.new
71
+ options = {
72
+ 'status' => '200 OK',
73
+ 'location' => 'http://www.example.com/',
74
+ }
75
+ actual = cgi.header(options)
76
+ assert_equal('200 OK', req.status_line) # should be '302 Found' ?
77
+ assert_equal(302, req.status)
78
+ assert_equal('http://www.example.com/', req.headers_out['location'])
79
+ end
80
+
81
+
82
+ def test_cgi_modruby_requestparams
83
+ req = Apache.request
84
+ req.args = 'a=foo&b=bar'
85
+ cgi = CGI.new
86
+ assert_equal('foo', cgi['a'])
87
+ assert_equal('bar', cgi['b'])
88
+ end
89
+
90
+
91
+ instance_methods.each do |method|
92
+ private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
93
+ end if ENV['TEST']
94
+
95
+ end
96
+
97
+
98
+
99
+ ## dummy class for mod_ruby
100
+ class Apache #:nodoc:
101
+
102
+ def self._reset
103
+ @request = Request.new
104
+ end
105
+
106
+ def self.request
107
+ return @request
108
+ end
109
+
110
+ class Request
111
+
112
+ def initialize
113
+ hash = {}
114
+ def hash.add(name, value)
115
+ (self[name] ||= []) << value
116
+ end
117
+ @headers_out = hash
118
+ @status_line = nil
119
+ @status = nil
120
+ @content_type = nil
121
+ @content_encoding = nil
122
+ end
123
+ attr_accessor :headers_out, :status_line, :status, :content_type, :content_encoding
124
+
125
+ attr_accessor :args
126
+ #def args
127
+ # return ENV['QUERY_STRING']
128
+ #end
129
+
130
+ def send_http_header
131
+ @http_header = '*invoked*'
132
+ end
133
+ def _send_http_header_invoked?
134
+ @http_header ? true : false
135
+ end
136
+
137
+ def setup_cgi_env
138
+ @cgi_env = '*invoked*'
139
+ end
140
+ def _setup_cgi_env_invoked?
141
+ @cgi_env ? true : false
142
+ end
143
+
144
+ end
145
+
146
+ end
@@ -0,0 +1,295 @@
1
+ require 'test/unit'
2
+ #require 'cgi'
3
+ require(ENV['CGI'] || 'cgi')
4
+ require 'tempfile'
5
+ require 'stringio'
6
+
7
+
8
+ ##
9
+ ## usage:
10
+ ## boundary = 'foobar1234' # or nil
11
+ ## multipart = MultiPart.new(boundary)
12
+ ## multipart.append('name1', 'value1')
13
+ ## multipart.append('file1', File.read('file1.html'), 'file1.html')
14
+ ## str = multipart.close()
15
+ ## str.each_line {|line| p line }
16
+ ## ## output:
17
+ ## # "--foobar1234\r\n"
18
+ ## # "Content-Disposition: form-data: name=\"name1\"\r\n"
19
+ ## # "\r\n"
20
+ ## # "value1\r\n"
21
+ ## # "--foobar1234\r\n"
22
+ ## # "Content-Disposition: form-data: name=\"file1\"; filename=\"file1.html\"\r\n"
23
+ ## # "Content-Type: text/html\r\n"
24
+ ## # "\r\n"
25
+ ## # "<html>\n"
26
+ ## # "<body><p>Hello</p></body>\n"
27
+ ## # "</html>\n"
28
+ ## # "\r\n"
29
+ ## # "--foobar1234--\r\n"
30
+ ##
31
+ class MultiPart
32
+
33
+ def initialize(boundary=nil)
34
+ @boundary = boundary || create_boundary()
35
+ @buf = ''
36
+ end
37
+ attr_reader :boundary
38
+
39
+ def append(name, value, filename=nil, content_type=nil)
40
+ content_type = detect_content_type(filename) if filename && content_type.nil?
41
+ s = filename ? "; filename=\"#{filename}\"" : ''
42
+ buf = @buf
43
+ buf << "--#{boundary}\r\n"
44
+ buf << "Content-Disposition: form-data: name=\"#{name}\"#{s}\r\n"
45
+ buf << "Content-Type: #{content_type}\r\n" if content_type
46
+ buf << "\r\n"
47
+ buf << value
48
+ buf << "\r\n"
49
+ return self
50
+ end
51
+
52
+ def close
53
+ buf = @buf
54
+ @buf = ''
55
+ return buf << "--#{boundary}--\r\n"
56
+ end
57
+
58
+ def create_boundary() #:nodoc:
59
+ return "--boundary#{rand().to_s[2..-1]}"
60
+ end
61
+
62
+ def detect_content_type(filename) #:nodoc:
63
+ filename =~ /\.(\w+)\z/
64
+ return MIME_TYPES[$1] || 'application/octet-stream'
65
+ end
66
+
67
+ MIME_TYPES = {
68
+ 'gif' => 'image/gif',
69
+ 'jpg' => 'image/jpeg',
70
+ 'jpeg' => 'image/jpeg',
71
+ 'png' => 'image/png',
72
+ 'bmp' => 'image/bmp',
73
+ 'tif' => 'image/tiff',
74
+ 'tiff' => 'image/tiff',
75
+ 'htm' => 'text/html',
76
+ 'html' => 'text/html',
77
+ 'xml' => 'text/xml',
78
+ 'txt' => 'text/plain',
79
+ 'text' => 'text/plain',
80
+ 'css' => 'text/css',
81
+ 'mpg' => 'video/mpeg',
82
+ 'mpeg' => 'video/mpeg',
83
+ 'mov' => 'video/quicktime',
84
+ 'avi' => 'video/x-msvideo',
85
+ 'mp3' => 'audio/mpeg',
86
+ 'mid' => 'audio/midi',
87
+ 'wav' => 'audio/x-wav',
88
+ 'zip' => 'application/zip',
89
+ #'tar.gz' => 'application/gtar',
90
+ 'gz' => 'application/gzip',
91
+ 'bz2' => 'application/bzip2',
92
+ 'rtf' => 'application/rtf',
93
+ 'pdf' => 'application/pdf',
94
+ 'ps' => 'application/postscript',
95
+ 'js' => 'application/x-javascript',
96
+ 'xls' => 'application/vnd.ms-excel',
97
+ 'doc' => 'application/msword',
98
+ 'ppt' => 'application/vnd.ms-powerpoint',
99
+ }
100
+
101
+ end
102
+
103
+
104
+
105
+ class CGIMultipartTest < Test::Unit::TestCase
106
+
107
+ def setup
108
+ ENV['REQUEST_METHOD'] = 'POST'
109
+ end
110
+
111
+ def teardown
112
+ %[REQUEST_METHOD CONTENT_TYPE CONTENT_LENGTH REQUEST_METHOD].each do |name|
113
+ ENV.delete(name)
114
+ end
115
+ $stdin.close() if $stdin.is_a?(Tempfile)
116
+ $stdin = STDIN
117
+ end
118
+
119
+ def _prepare(data)
120
+ ## create multipart input
121
+ multipart = MultiPart.new(@boundary)
122
+ data.each do |hash|
123
+ multipart.append(hash[:name], hash[:value], hash[:filename])
124
+ end
125
+ input = multipart.close()
126
+ input = yield(input) if block_given?
127
+ #$stderr.puts "*** debug: input=\n#{input.collect{|line| line.inspect}.join("\n")}"
128
+ @boundary ||= multipart.boundary
129
+ ## set environment
130
+ ENV['CONTENT_TYPE'] = "multipart/form-data; boundary=#{@boundary}"
131
+ ENV['CONTENT_LENGTH'] = input.length.to_s
132
+ ENV['REQUEST_METHOD'] = 'POST'
133
+ ## set $stdin
134
+ tmpfile = Tempfile.new(self.name)
135
+ tmpfile << input
136
+ tmpfile.rewind()
137
+ $stdin = tmpfile
138
+ end
139
+
140
+ def _test_multipart
141
+ caller(0).find {|s| s =~ /in `test_(.*?)'/ }
142
+ testname = $1
143
+ #$stderr.puts "*** debug: testname=#{testname.inspect}"
144
+ _prepare(@data)
145
+ cgi = CGI.new
146
+ expected_names = @data.collect{|hash| hash[:name] }.sort
147
+ assert_equal(expected_names, cgi.params.keys.sort)
148
+ threshold = 1024*10
149
+ @data.each do |hash|
150
+ name = hash[:name]
151
+ expected = hash[:value]
152
+ expected_class = @expected_class || (hash[:value].length < threshold ? StringIO : Tempfile)
153
+ assert_kind_of(expected_class, cgi[name])
154
+ assert_equal(expected, cgi[name].read())
155
+ assert_equal(hash[:filename] || '', cgi[name].original_filename) #if hash[:filename]
156
+ assert_equal(hash[:content_type] || '', cgi[name].content_type) #if hash[:content_type]
157
+ end
158
+ end
159
+
160
+
161
+ def _read(basename)
162
+ filename = File.join(File.dirname(__FILE__), 'testdata', basename)
163
+ s = File.open(filename, 'rb') {|f| f.read() }
164
+ return s
165
+ end
166
+
167
+
168
+ def test_cgi_multipart_stringio
169
+ @boundary = '----WebKitFormBoundaryAAfvAII+YL9102cX'
170
+ @data = [
171
+ {:name=>'hidden1', :value=>'foobar'},
172
+ {:name=>'text1', :value=>"\202\240\202\242\202\244\202\246\202\250"},
173
+ {:name=>'file1', :value=>_read('file1.html'),
174
+ :filename=>'file1.html', :content_type=>'text/html'},
175
+ {:name=>'image1', :value=>_read('small.png'),
176
+ :filename=>'small.png', :content_type=>'image/png'}, # small image
177
+ ]
178
+ @expected_class = StringIO
179
+ _test_multipart()
180
+ end
181
+
182
+
183
+ def test_cgi_multipart_tempfile
184
+ @boundary = '----WebKitFormBoundaryAAfvAII+YL9102cX'
185
+ @data = [
186
+ {:name=>'hidden1', :value=>'foobar'},
187
+ {:name=>'text1', :value=>"\202\240\202\242\202\244\202\246\202\250"},
188
+ {:name=>'file1', :value=>_read('file1.html'),
189
+ :filename=>'file1.html', :content_type=>'text/html'},
190
+ {:name=>'image1', :value=>_read('large.png'),
191
+ :filename=>'large.png', :content_type=>'image/png'}, # large image
192
+ ]
193
+ @expected_class = Tempfile
194
+ _test_multipart()
195
+ end
196
+
197
+
198
+ def _set_const(klass, name, value)
199
+ old = nil
200
+ klass.class_eval do
201
+ old = const_get(name)
202
+ remove_const(name)
203
+ const_set(name, value)
204
+ end
205
+ return old
206
+ end
207
+
208
+
209
+ def test_cgi_multipart_maxmultipartlength
210
+ @data = [
211
+ {:name=>'image1', :value=>_read('large.png'),
212
+ :filename=>'large.png', :content_type=>'image/png'}, # large image
213
+ ]
214
+ original = _set_const(CGI, :MAX_MULTIPART_LENGTH, 2 * 1024)
215
+ begin
216
+ ex = assert_raise(StandardError) do
217
+ _test_multipart()
218
+ end
219
+ assert_equal("too large multipart data.", ex.message)
220
+ ensure
221
+ _set_const(CGI, :MAX_MULTIPART_LENGTH, original)
222
+ end
223
+ end if CGI.const_defined?(:MAX_MULTIPART_LENGTH)
224
+
225
+
226
+ def test_cgi_multipart_maxmultipartcount
227
+ @data = [
228
+ {:name=>'file1', :value=>_read('file1.html'),
229
+ :filename=>'file1.html', :content_type=>'text/html'},
230
+ ]
231
+ item = @data.first
232
+ 500.times { @data << item }
233
+ #original = _set_const(CGI, :MAX_MULTIPART_COUNT, 128)
234
+ begin
235
+ ex = assert_raise(StandardError) do
236
+ _test_multipart()
237
+ end
238
+ assert_equal("too many parameters.", ex.message)
239
+ ensure
240
+ #_set_const(CGI, :MAX_MULTIPART_COUNT, original)
241
+ end
242
+ end if CGI.const_defined?(:MAX_MULTIPART_COUNT)
243
+
244
+
245
+ def test_cgi_multipart_badbody ## [ruby-dev:28470]
246
+ @data = [
247
+ {:name=>'file1', :value=>_read('file1.html'),
248
+ :filename=>'file1.html', :content_type=>'text/html'},
249
+ ]
250
+ _prepare(@data) do |input|
251
+ input2 = input.sub(/--(\r\n)?\z/, "\r\n")
252
+ assert input2 != input
253
+ #p input2
254
+ input2
255
+ end
256
+ ex = assert_raise(EOFError) do
257
+ cgi = CGI.new
258
+ end
259
+ assert_equal("bad boundary end of body part", ex.message)
260
+ #
261
+ _prepare(@data) do |input|
262
+ input2 = input.sub(/--(\r\n)?\z/, "")
263
+ assert input2 != input
264
+ #p input2
265
+ input2
266
+ end
267
+ ex = assert_raise(EOFError) do
268
+ cgi = CGI.new
269
+ end
270
+ assert_equal("bad content body", ex.message)
271
+ end
272
+
273
+
274
+ def test_cgi_multipart_quoteboundary ## [JVN#84798830]
275
+ @boundary = '(.|\n)*'
276
+ @data = [
277
+ {:name=>'hidden1', :value=>'foobar'},
278
+ {:name=>'text1', :value=>"\202\240\202\242\202\244\202\246\202\250"},
279
+ {:name=>'file1', :value=>_read('file1.html'),
280
+ :filename=>'file1.html', :content_type=>'text/html'},
281
+ {:name=>'image1', :value=>_read('small.png'),
282
+ :filename=>'small.png', :content_type=>'image/png'}, # small image
283
+ ]
284
+ _prepare(@data)
285
+ cgi = CGI.new
286
+ assert_equal('file1.html', cgi['file1'].original_filename)
287
+ end
288
+
289
+ ###
290
+
291
+ self.instance_methods.each do |method|
292
+ private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
293
+ end if ENV['TEST']
294
+
295
+ end
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
+ <html>
3
+ <head>
4
+ <title>ムスカ大佐のひとりごと</title>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF8">
6
+ </head>
7
+ <body>
8
+ <p>バカどもにはちょうどいい目くらましだ。</p>
9
+ </body>
10
+ </html>