serverside 0.2.9 → 0.3.0

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.
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