serverside 0.2.9 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/CHANGELOG +56 -0
  2. data/Rakefile +12 -52
  3. data/bin/serverside +1 -1
  4. data/lib/serverside/application.rb +2 -1
  5. data/lib/serverside/caching.rb +62 -50
  6. data/lib/serverside/controllers.rb +91 -0
  7. data/lib/serverside/core_ext.rb +6 -0
  8. data/lib/serverside/daemon.rb +25 -5
  9. data/lib/serverside/request.rb +17 -11
  10. data/lib/serverside/routing.rb +11 -10
  11. data/lib/serverside/server.rb +14 -6
  12. data/lib/serverside/static.rb +7 -18
  13. data/lib/serverside/template.rb +20 -12
  14. data/spec/caching_spec.rb +318 -0
  15. data/spec/cluster_spec.rb +140 -0
  16. data/{test/spec → spec}/connection_spec.rb +4 -4
  17. data/{test/spec/controller_spec.rb → spec/controllers_spec.rb} +15 -12
  18. data/{test/spec → spec}/core_ext_spec.rb +23 -18
  19. data/spec/daemon_spec.rb +99 -0
  20. data/{test/spec → spec}/request_spec.rb +45 -45
  21. data/spec/routing_spec.rb +240 -0
  22. data/spec/server_spec.rb +40 -0
  23. data/spec/static_spec.rb +279 -0
  24. data/spec/template_spec.rb +129 -0
  25. metadata +21 -35
  26. data/lib/serverside/controller.rb +0 -67
  27. data/test/functional/primitive_static_server_test.rb +0 -61
  28. data/test/functional/request_body_test.rb +0 -93
  29. data/test/functional/routing_server.rb +0 -14
  30. data/test/functional/routing_server_test.rb +0 -41
  31. data/test/functional/static_profile.rb +0 -17
  32. data/test/functional/static_rfuzz.rb +0 -31
  33. data/test/functional/static_server.rb +0 -7
  34. data/test/functional/static_server_test.rb +0 -31
  35. data/test/spec/caching_spec.rb +0 -139
  36. data/test/test_helper.rb +0 -2
  37. data/test/unit/cluster_test.rb +0 -129
  38. data/test/unit/connection_test.rb +0 -48
  39. data/test/unit/core_ext_test.rb +0 -46
  40. data/test/unit/daemon_test.rb +0 -75
  41. data/test/unit/request_test.rb +0 -278
  42. data/test/unit/routing_test.rb +0 -171
  43. data/test/unit/server_test.rb +0 -28
  44. data/test/unit/static_test.rb +0 -171
  45. data/test/unit/template_test.rb +0 -78
@@ -1,278 +0,0 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
- require 'stringio'
3
-
4
- class RequestTest < Test::Unit::TestCase
5
- class DummyConnection
6
- attr_reader :opened
7
-
8
- def initialize
9
- @opened = true
10
- end
11
-
12
- def close
13
- @opened = false
14
- end
15
- end
16
-
17
- class DummyRequest2 < ServerSide::HTTP::Request
18
- attr_accessor :count
19
-
20
- def parse
21
- @count = 1
22
- end
23
-
24
- def respond
25
- @count += 1
26
- @persistent = @count < 2
27
- end
28
- end
29
-
30
- def test_process
31
- r = DummyRequest2.new(nil)
32
- sleep 0.2
33
- assert_equal false, r.process
34
- assert_equal 2, r.count
35
- assert_equal false, r.persistent
36
- end
37
-
38
- class DummyRequest3 < ServerSide::HTTP::Request
39
- attr_accessor :parse_result, :respond_result
40
- def parse; @parse_result; end
41
- def respond; @respond_result; end
42
- end
43
-
44
- class ServerSide::HTTP::Request
45
- attr_writer :socket, :persistent, :response_headers
46
- end
47
-
48
- def test_process_result
49
- r = DummyRequest3.new(nil)
50
- r.parse_result = nil
51
- r.persistent = true
52
- assert_equal nil, r.process
53
- r.parse_result = nil
54
- r.respond_result = true
55
- assert_equal nil, r.process
56
- r.parse_result = {}
57
- r.respond_result = nil
58
- r.persistent = false
59
- assert_equal false, r.process
60
- r.parse_result = {}
61
- r.respond_result = true
62
- r.persistent = true
63
- assert_equal true, r.process
64
- r.parse_result = {}
65
- r.persistent = 'hello'
66
- assert_equal 'hello', r.process
67
- end
68
-
69
- def test_parse_request_invalid
70
- r = ServerSide::HTTP::Request.new(nil)
71
- r.socket = StringIO.new('POST /test')
72
- assert_nil r.parse
73
- r.socket = StringIO.new('invalid string')
74
- assert_nil r.parse
75
- r.socket = StringIO.new('GET HTTP/1.1')
76
- assert_nil r.parse
77
- r.socket = StringIO.new('GET /test http')
78
- assert_nil r.parse
79
- r.socket = StringIO.new('GET /test HTTP')
80
- assert_nil r.parse
81
- r.socket = StringIO.new('GET /test HTTP/')
82
- assert_nil r.parse
83
- r.socket = StringIO.new('POST /test HTTP/1.1')
84
- assert_nil r.parse
85
- end
86
-
87
- def test_parse_request
88
- r = ServerSide::HTTP::Request.new(nil)
89
- r.socket = StringIO.new("POST /test HTTP/1.1\r\n\r\n")
90
- assert_kind_of Hash, r.parse
91
- assert_equal :post, r.method
92
- assert_equal '/test', r.path
93
- assert_nil r.query
94
- assert_equal '1.1', r.version
95
- assert_equal({}, r.parameters)
96
- assert_equal({}, r.headers)
97
- assert_equal({}, r.cookies)
98
- assert_nil r.response_cookies
99
- assert_equal true, r.persistent
100
-
101
- # trailing slash in path
102
- r = ServerSide::HTTP::Request.new(nil)
103
- r.socket = StringIO.new("POST /test/asdf/qw/?time=24%20hours HTTP/1.1\r\n\r\n")
104
- assert_kind_of Hash, r.parse
105
- assert_equal :post, r.method
106
- assert_equal '/test/asdf/qw', r.path
107
- assert_equal 'time=24%20hours', r.query
108
- assert_equal '1.1', r.version
109
- assert_equal({:time => '24 hours'}, r.parameters)
110
- assert_equal({}, r.headers)
111
- assert_equal({}, r.cookies)
112
- assert_nil r.response_cookies
113
- assert_equal true, r.persistent
114
-
115
- r.socket = StringIO.new("GET /cex?q=node_state HTTP/1.1\r\n\r\n")
116
- assert_kind_of Hash, r.parse
117
- assert_equal :get, r.method
118
- assert_equal '/cex', r.path
119
- assert_equal 'q=node_state', r.query
120
- assert_equal({:q => 'node_state'}, r.parameters)
121
- assert_equal({}, r.cookies)
122
- assert_nil r.response_cookies
123
-
124
- r.socket = StringIO.new("GET / HTTP/1.0\r\n\r\n")
125
- assert_kind_of Hash, r.parse
126
- assert_equal false, r.persistent
127
- assert_equal({}, r.cookies)
128
- assert_nil r.response_cookies
129
-
130
- r.socket = StringIO.new("GET / HTTP/invalid\r\n\r\n")
131
- assert_kind_of Hash, r.parse
132
- assert_equal 'invalid', r.version
133
- assert_equal false, r.persistent
134
-
135
- r.socket = StringIO.new("GET / HTTP/1.1\r\nConnection: close\r\n\r\n")
136
- assert_kind_of Hash, r.parse
137
- assert_equal '1.1', r.version
138
- assert_equal 'close', r.headers['Connection']
139
- assert_equal false, r.persistent
140
-
141
- # cookies
142
- r.socket = StringIO.new("GET / HTTP/1.1\r\nConnection: close\r\nCookie: abc=1342; def=7%2f4\r\n\r\n")
143
- assert_kind_of Hash, r.parse
144
- assert_equal 'abc=1342; def=7%2f4', r.headers['Cookie']
145
- assert_equal '1342', r.cookies[:abc]
146
- assert_equal '7/4', r.cookies[:def]
147
- end
148
-
149
- def test_send_response
150
- r = ServerSide::HTTP::Request.new(nil)
151
- # simple case
152
- r.response_headers = {}
153
- r.socket = StringIO.new
154
- r.persistent = true
155
- r.send_response(200, 'text', 'Hello there!')
156
- r.socket.rewind
157
- assert_equal "HTTP/1.1 200\r\nDate: #{Time.now.httpdate}\r\nContent-Type: text\r\nContent-Length: 12\r\n\r\nHello there!",
158
- r.socket.read
159
-
160
- # include content-length
161
- r.response_headers = {}
162
- r.socket = StringIO.new
163
- r.persistent = true
164
- r.send_response(404, 'text/html', '<h1>404!</h1>', 10) # incorrect length
165
- r.socket.rewind
166
- assert_equal "HTTP/1.1 404\r\nDate: #{Time.now.httpdate}\r\nContent-Type: text/html\r\nContent-Length: 10\r\n\r\n<h1>404!</h1>",
167
- r.socket.read
168
-
169
- # headers
170
- r.response_headers = {}
171
- r.socket = StringIO.new
172
- r.persistent = true
173
- r.send_response(404, 'text/html', '<h1>404!</h1>', nil, {'ETag' => 'xxyyzz'})
174
- r.socket.rewind
175
- assert_equal "HTTP/1.1 404\r\nDate: #{Time.now.httpdate}\r\nContent-Type: text/html\r\nETag: xxyyzz\r\nContent-Length: 13\r\n\r\n<h1>404!</h1>",
176
- r.socket.read
177
-
178
- # no body
179
- r.response_headers = {}
180
- r.socket = StringIO.new
181
- r.persistent = true
182
- r.send_response(404, 'text/html', nil, nil, {'Set-Cookie' => 'abc=123'})
183
- r.socket.rewind
184
- assert_equal "HTTP/1.1 404\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nContent-Type: text/html\r\nSet-Cookie: abc=123\r\n\r\n",
185
- r.socket.read
186
- assert_equal false, r.persistent
187
-
188
- # not persistent
189
- r.response_headers = {}
190
- r.socket = StringIO.new
191
- r.persistent = false
192
- r.send_response(200, 'text', 'Hello there!')
193
- r.socket.rewind
194
- assert_equal "HTTP/1.1 200\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nContent-Type: text\r\nContent-Length: 12\r\n\r\nHello there!",
195
- r.socket.read
196
-
197
- # socket error
198
- r.response_headers = {}
199
- r.socket = nil
200
- r.persistent = true
201
- assert_nothing_raised {r.send_response(200, 'text', 'Hello there!')}
202
- assert_equal false, r.persistent
203
- end
204
-
205
- def test_stream
206
- r = ServerSide::HTTP::Request.new(nil)
207
- r.socket = StringIO.new
208
- r.stream 'hey there'
209
- r.socket.rewind
210
- assert_equal 'hey there', r.socket.read
211
-
212
- r.socket = StringIO.new
213
- r.persistent = true
214
- r.send_response(404, 'text/html', nil, nil, {'Set-Cookie' => 'abc=123'})
215
- r.stream('hey there')
216
- r.socket.rewind
217
- assert_equal "HTTP/1.1 404\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nContent-Type: text/html\r\nSet-Cookie: abc=123\r\n\r\nhey there",
218
- r.socket.read
219
- end
220
-
221
- def test_redirect
222
- r = ServerSide::HTTP::Request.new(nil)
223
- r.socket = StringIO.new
224
- r.redirect('http://mau.com/132')
225
- r.socket.rewind
226
- assert_equal "HTTP/1.1 302\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nLocation: http://mau.com/132\r\n\r\n", r.socket.read
227
-
228
- r.response_headers = {}
229
- r.socket = StringIO.new
230
- r.redirect('http://www.google.com/search?q=meaning%20of%20life', true)
231
- r.socket.rewind
232
- assert_equal "HTTP/1.1 301\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nLocation: http://www.google.com/search?q=meaning%20of%20life\r\n\r\n", r.socket.read
233
- end
234
-
235
- def test_set_cookie
236
- r = ServerSide::HTTP::Request.new(nil)
237
- r.socket = StringIO.new
238
- t = Time.now + 360
239
- r.set_cookie(:session, "ABCDEFG", t)
240
- assert_equal "Set-Cookie: session=ABCDEFG; path=/; expires=#{t.rfc2822}\r\n", r.response_cookies
241
- r.send_response(200, 'text', 'Hi!')
242
- r.socket.rewind
243
- assert_equal "HTTP/1.1 200\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nContent-Type: text\r\nSet-Cookie: session=ABCDEFG; path=/; expires=#{t.rfc2822}\r\nContent-Length: 3\r\n\r\nHi!", r.socket.read
244
- end
245
-
246
- def test_delete_cookie
247
- r = ServerSide::HTTP::Request.new(nil)
248
- r.socket = StringIO.new
249
- r.delete_cookie(:session)
250
- assert_equal "Set-Cookie: session=; path=/; expires=#{Time.at(0).rfc2822}\r\n", r.response_cookies
251
- r.send_response(200, 'text', 'Hi!')
252
- r.socket.rewind
253
- assert_equal "HTTP/1.1 200\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nContent-Type: text\r\nSet-Cookie: session=; path=/; expires=#{Time.at(0).rfc2822}\r\nContent-Length: 3\r\n\r\nHi!", r.socket.read
254
- end
255
-
256
- def test_response_headers
257
- r = ServerSide::HTTP::Request.new(nil)
258
- r.socket = StringIO.new
259
- assert_equal({}, r.response_headers)
260
- r.response_headers = {'A' => '1', 'B' => 2}
261
- r.send_response(200, 'text', 'Hi!')
262
- r.socket.rewind
263
- resp = r.socket.read
264
- assert_not_nil resp.match("A: 1\r\n")
265
- assert_not_nil resp.match("B: 2\r\n")
266
-
267
- r.response_headers = {}
268
- r.socket = StringIO.new
269
- assert_equal({}, r.response_headers)
270
- r.response_headers = {'D' => '1', 'E' => 2}
271
- r.send_response(200, 'text', 'Hi!', nil, {'F' => 3})
272
- r.socket.rewind
273
- resp = r.socket.read
274
- assert_not_nil resp.match("D: 1\r\n")
275
- assert_not_nil resp.match("E: 2\r\n")
276
- assert_not_nil resp.match("F: 3\r\n")
277
- end
278
- end
@@ -1,171 +0,0 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
- require 'stringio'
3
-
4
- class ServerSide::Router
5
- attr_accessor :t, :parameters
6
-
7
- def self.rules
8
- @@rules
9
- end
10
-
11
- def self.remove_rules
12
- @@rules = nil
13
- end
14
-
15
- def self.reset_rules
16
- @@rules = []
17
- end
18
-
19
- def self.reset_respond
20
- define_method(:respond) {nil}
21
- end
22
- end
23
-
24
- class RoutingTest < Test::Unit::TestCase
25
- R = ServerSide::Router
26
-
27
- def test_has_routes?
28
- R.remove_rules
29
- assert_nil R.has_routes?
30
- R.reset_rules
31
- assert_equal false, R.has_routes?
32
- R.route('/controller/:action/:id') {}
33
- assert_equal true, R.has_routes?
34
- end
35
-
36
- def test_route
37
- l1 = lambda {1 + 1}
38
- R.reset_rules
39
- R.route('/controller/:action/:id', &l1)
40
- assert_equal 1, R.rules.length
41
- assert_equal({:path => '/controller/:action/:id'}, R.rules[0][0])
42
- assert_equal l1, R.rules[0][1]
43
-
44
- l2 = lambda {2 + 2}
45
- R.route(:host => '^static\..+', &l2)
46
- assert_equal 2, R.rules.length
47
- assert_equal({:host => '^static\..+'}, R.rules[0][0])
48
- assert_equal l2, R.rules[0][1]
49
- assert_equal({:path => '/controller/:action/:id'}, R.rules[1][0])
50
- assert_equal l1, R.rules[1][1]
51
-
52
- l3 = lambda {3 + 3}
53
- l4 = lambda {4 + 4}
54
-
55
- R.route(l3, &l4)
56
- assert_equal 3, R.rules.length
57
- assert_equal l3, R.rules[0][0]
58
- assert_equal l4, R.rules[0][1]
59
- assert_equal({:host => '^static\..+'}, R.rules[1][0])
60
- assert_equal l2, R.rules[1][1]
61
- assert_equal({:path => '/controller/:action/:id'}, R.rules[2][0])
62
- assert_equal l1, R.rules[2][1]
63
- end
64
-
65
- def test_compile_rules
66
- R.reset_rules
67
- R.reset_respond
68
-
69
- assert_equal nil, R.new(StringIO.new).respond
70
- R.rules << [{:t => 'abc'}, lambda{1}]
71
- R.rules << [{:t => 'def'}, lambda{2}]
72
- R.default_route {3}
73
- R.compile_rules
74
- r = R.new(StringIO.new)
75
- r.t = 'abc'
76
- assert_equal 1, r.respond
77
- r.t = 'def'
78
- assert_equal 2, r.respond
79
- r.t = ''
80
- assert_equal 3, r.respond
81
- end
82
-
83
- def test_rule_to_statement
84
- l1 = lambda {1 + 1}
85
- l2 = lambda {2 + 2}
86
- s = R.rule_to_statement(l1, l2)
87
- assert_equal "return #{l2.proc_tag} if #{l1.proc_tag}\n" ,s
88
- r = R.new(StringIO.new)
89
- assert_equal true, r.respond_to?(l1.proc_tag)
90
- assert_equal true, r.respond_to?(l2.proc_tag)
91
-
92
- l3 = lambda {3 + 3}
93
- s = R.rule_to_statement({:path => '/.*'}, l3)
94
- assert_not_nil s =~ /^return\s#{l3.proc_tag}\sif\s\(@path\s=~\s(.*)\)\n$/, s
95
- assert_equal /\/.*/, eval("R::#{$1}")
96
- assert_equal true, r.respond_to?(l3.proc_tag)
97
-
98
- l4 = lambda {4 + 4}
99
- s = R.rule_to_statement({:path => '/controller', :host => 'static'}, l4)
100
- assert_not_nil s =~ /^return\s#{l4.proc_tag}\sif\s\(.+\)&&\(.+\)\n$/
101
- assert_not_nil s =~ /\(@path\s=~\s([^\)]+)\)/
102
- assert_equal /\/controller/, eval("R::#{$1}")
103
- assert_not_nil s =~ /\(@host\s=~\s([^\)]+)\)/
104
- assert_equal /static/, eval("R::#{$1}")
105
- assert_equal true, r.respond_to?(l4.proc_tag)
106
-
107
- l5 = lambda {5 + 5}
108
- s = R.rule_to_statement({:path => ['/x', '/y']}, l5)
109
- assert_not_nil s =~ /^return\s#{l5.proc_tag}\sif\s\(\(@path\s=~\s(.*)\)\|\|\(@path\s=~\s(.*)\)\)\n$/
110
- assert_equal /\/x/, eval("R::#{$1}")
111
- assert_equal /\/y/, eval("R::#{$2}")
112
- assert_equal true, r.respond_to?(l5.proc_tag)
113
- end
114
-
115
- def test_condition_part
116
- s = R.condition_part(:t, 'abc')
117
- assert_not_nil s =~ /^\(@t\s=~\s(.*)\)$/
118
- assert_equal /abc/, eval("R::#{$1}")
119
-
120
- s = R.condition_part(:t, ':action/:id')
121
- assert_not_nil s =~ /^\((.*)\)$/
122
- tag = $1
123
- r = R.new(StringIO.new)
124
- assert_equal true, r.respond_to?(tag)
125
- r.parameters = {}
126
- r.t = 'abc'
127
- assert_equal false, r.send(tag)
128
- r.t = 'show/16'
129
- assert_equal true, r.send(tag)
130
- assert_equal 'show', r.parameters[:action]
131
- assert_equal '16', r.parameters[:id]
132
- end
133
-
134
- def test_define_proc
135
- l1 = lambda {1 + 1}
136
- tag = R.define_proc(&l1)
137
- assert_kind_of Symbol, tag
138
- assert_equal l1.proc_tag.to_sym, tag
139
- r = R.new(StringIO.new)
140
- assert 2, r.send(tag)
141
- end
142
-
143
- def test_cache_constant
144
- c = rand(100000)
145
- tag = R.cache_constant(c)
146
- assert_kind_of String, tag
147
- assert_equal c.const_tag, tag
148
- assert_equal c, eval("R::#{tag}")
149
- end
150
-
151
- def test_default_route
152
- R.default_route {'mau m'}
153
- assert_equal 'mau m', R.new(StringIO.new).default_handler
154
-
155
- R.default_route {654321}
156
- assert_equal 654321, R.new(StringIO.new).default_handler
157
- end
158
-
159
- def test_serverside_route
160
- R.reset_rules
161
- ServerSide::Router.route(:path => 'abc') {1 + 1}
162
- assert_equal 1, R.rules.length
163
- assert_equal({:path => 'abc'}, R.rules[0][0])
164
- assert_equal 2, R.rules[0][1].call
165
- end
166
-
167
- def test_serverside_default_route
168
- ServerSide::Router.default_route {1234}
169
- assert_equal 1234, R.new(StringIO.new).default_handler
170
- end
171
- end
@@ -1,28 +0,0 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
- require 'net/http'
3
-
4
- class ServerTest < Test::Unit::TestCase
5
- class DummyRequest < ServerSide::HTTP::Request
6
- def respond
7
- @socket << "HTTP/1.1 200\r\nContent-Length: 9\r\n\r\nHi there!"
8
- end
9
- end
10
-
11
- def test_server_creation
12
- t = Thread.new do
13
- begin
14
- ServerSide::HTTP::Server.new('0.0.0.0', 17543, DummyRequest)
15
- rescue => e
16
- puts e.message
17
- puts e.backtrace.first
18
- end
19
- end
20
- sleep 0.1
21
-
22
- h = Net::HTTP.new('localhost', 17543)
23
- resp, data = h.get('/', nil)
24
- assert_equal 200, resp.code.to_i
25
- assert_equal 'Hi there!', data
26
- t.exit
27
- end
28
- end
@@ -1,171 +0,0 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
- require 'stringio'
3
- require 'fileutils'
4
-
5
- class StaticTest < Test::Unit::TestCase
6
- class Dummy < ServerSide::HTTP::Request
7
- def self.static_files
8
- @@static_files
9
- end
10
-
11
- def self.mime_types
12
- @@mime_types
13
- end
14
-
15
- attr_accessor :path, :socket, :headers
16
-
17
- def initialize
18
- super(nil)
19
- @headers = {}
20
- end
21
- end
22
-
23
- def test_cache
24
- assert_kind_of Hash, Dummy.static_files
25
- Dummy.static_files.clear
26
- c = Dummy.new
27
- c.socket = StringIO.new
28
- assert_nil Dummy.static_files[__FILE__]
29
- c.serve_file(__FILE__)
30
- cache = Dummy.static_files[__FILE__]
31
- assert_not_nil cache
32
- stat = File.stat(__FILE__)
33
- etag = (ServerSide::Static::ETAG_FORMAT %
34
- [stat.mtime.to_i, stat.size, stat.ino])
35
- assert_equal etag, cache[0]
36
- assert_equal IO.read(__FILE__), cache[1]
37
- end
38
-
39
- def test_mime_types
40
- assert_kind_of Hash, Dummy.mime_types
41
- assert_equal 'text/plain', Dummy.mime_types['.rb']
42
- assert_equal 'text/plain', Dummy.mime_types['.invalid']
43
- assert_equal 'text/html', Dummy.mime_types['.html']
44
- assert_equal 'text/css', Dummy.mime_types['.css']
45
- assert_equal 'text/javascript', Dummy.mime_types['.js']
46
- assert_equal 'image/gif', Dummy.mime_types['.gif']
47
- assert_equal 'image/jpeg', Dummy.mime_types['.jpg']
48
- assert_equal 'image/jpeg', Dummy.mime_types['.jpeg']
49
- assert_equal 'image/png', Dummy.mime_types['.png']
50
- end
51
-
52
- def test_serve_file_normal
53
- c = Dummy.new
54
- c.socket = StringIO.new
55
- c.serve_file(__FILE__)
56
- c.socket.rewind
57
- resp = c.socket.read
58
-
59
- assert_equal '200', /HTTP\/1.1\s(.*)\r\n/.match(resp)[1]
60
- fc = IO.read(__FILE__)
61
- stat = File.stat(__FILE__)
62
- etag = (ServerSide::Static::ETAG_FORMAT %
63
- [stat.mtime.to_i, stat.size, stat.ino])
64
- assert_not_nil resp =~ /ETag:\s"#{etag}"\r\n/
65
- assert_not_nil resp =~ /Cache-Control:\smax-age=#{ServerSide::HTTP::Caching::DEFAULT_MAX_AGE}\r\n/
66
- assert_equal stat.size.to_s,
67
- /Content-Length:\s(.*)\r\n/.match(resp)[1]
68
- end
69
-
70
- def test_serve_file_etags
71
- c = Dummy.new
72
- c.socket = StringIO.new
73
- Dummy.static_files.clear
74
- c.serve_file(__FILE__)
75
- c.socket.rewind
76
- resp = c.socket.read
77
-
78
- # normal response
79
- assert_equal '200', /HTTP\/1.1\s(.*)\r\n/.match(resp)[1]
80
- fc = IO.read(__FILE__)
81
- stat = File.stat(__FILE__)
82
- etag = (ServerSide::Static::ETAG_FORMAT %
83
- [stat.mtime.to_i, stat.size, stat.ino])
84
- assert_not_nil resp =~ /ETag:\s"#{etag}"\r\n/
85
- assert_not_nil resp =~ /Cache-Control:\smax-age=#{ServerSide::HTTP::Caching::DEFAULT_MAX_AGE}\r\n/
86
- assert_equal stat.size.to_s,
87
- /Content-Length:\s(.*)\r\n/.match(resp)[1]
88
-
89
- c.socket = StringIO.new
90
- c.headers[ServerSide::Static::IF_NONE_MATCH] = "\"#{etag}\""
91
- c.serve_file(__FILE__)
92
- c.socket.rewind
93
- resp = c.socket.read
94
-
95
- # not modified response
96
- assert_equal '304 Not Modified', /HTTP\/1.1\s(.*)\r\n/.match(resp)[1]
97
- fc = IO.read(__FILE__)
98
- stat = File.stat(__FILE__)
99
- etag = (ServerSide::Static::ETAG_FORMAT %
100
- [stat.mtime.to_i, stat.size, stat.ino])
101
- assert_not_nil resp =~ /ETag:\s"#{etag}"\r\n/
102
- assert_not_nil resp =~ /Cache-Control:\smax-age=#{ServerSide::HTTP::Caching::DEFAULT_MAX_AGE}\r\n/
103
-
104
- FileUtils.touch(__FILE__)
105
- c.socket = StringIO.new
106
- c.headers[ServerSide::Static::IF_NONE_MATCH] = etag
107
- c.serve_file(__FILE__)
108
- c.socket.rewind
109
- resp = c.socket.read
110
-
111
- # modified response
112
- assert_equal '200', /HTTP\/1.1\s(.*)\r\n/.match(resp)[1]
113
- fc = IO.read(__FILE__)
114
- stat = File.stat(__FILE__)
115
- etag = (ServerSide::Static::ETAG_FORMAT %
116
- [stat.mtime.to_i, stat.size, stat.ino])
117
- assert_not_nil resp =~ /ETag:\s"#{etag}"\r\n/
118
- assert_not_nil resp =~ /Cache-Control:\smax-age=#{ServerSide::HTTP::Caching::DEFAULT_MAX_AGE}\r\n/
119
- assert_equal stat.size.to_s,
120
- /Content-Length:\s(.*)\r\n/.match(resp)[1]
121
- end
122
-
123
- def test_serve_dir
124
- dir = File.dirname(__FILE__)
125
-
126
- c = Dummy.new
127
- c.socket = StringIO.new
128
- Dummy.static_files.clear
129
- c.path = dir
130
- c.serve_dir(dir)
131
- c.socket.rewind
132
- resp = c.socket.read
133
-
134
- Dir.entries(dir).each do |fn|
135
- next if fn =~ /^\./
136
- assert_not_nil resp =~ /<a href="#{dir/fn}">(#{fn})<\/a>/
137
- end
138
- end
139
-
140
- def test_serve_static
141
- dir = File.dirname(__FILE__)
142
-
143
- c = Dummy.new
144
- c.socket = StringIO.new
145
- c.path = dir
146
- c.serve_static(dir)
147
- c.socket.rewind
148
- resp = c.socket.read
149
-
150
- Dir.entries(dir).each do |fn|
151
- next if fn =~ /^\./
152
- assert_not_nil resp =~ /<a href="#{dir/fn}">(#{fn})<\/a>/
153
- end
154
-
155
- c.socket = StringIO.new
156
- c.serve_file(__FILE__)
157
- c.socket.rewind
158
- resp = c.socket.read
159
-
160
- # normal response
161
- assert_equal '200', /HTTP\/1.1\s(.*)\r\n/.match(resp)[1]
162
- fc = IO.read(__FILE__)
163
- stat = File.stat(__FILE__)
164
- etag = (ServerSide::Static::ETAG_FORMAT %
165
- [stat.mtime.to_i, stat.size, stat.ino])
166
- assert_not_nil resp =~ /ETag:\s"#{etag}"\r\n/
167
- assert_not_nil resp =~ /Cache-Control:\smax-age=#{ServerSide::HTTP::Caching::DEFAULT_MAX_AGE}\r\n/
168
- assert_equal stat.size.to_s,
169
- /Content-Length:\s(.*)\r\n/.match(resp)[1]
170
- end
171
- end