serverside 0.3.1 → 0.4.1
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/README +15 -11
- data/Rakefile +18 -18
- data/bin/serverside +20 -16
- data/lib/serverside/cluster.rb +4 -33
- data/lib/serverside/core_ext.rb +56 -7
- data/lib/serverside/daemon.rb +10 -17
- data/lib/serverside/http/caching.rb +79 -0
- data/lib/serverside/http/const.rb +69 -0
- data/lib/serverside/http/error.rb +24 -0
- data/lib/serverside/http/parsing.rb +175 -0
- data/lib/serverside/http/response.rb +91 -0
- data/lib/serverside/http/server.rb +194 -0
- data/lib/serverside/http/static.rb +72 -0
- data/lib/serverside/http.rb +14 -0
- data/lib/serverside/js.rb +173 -0
- data/lib/serverside/log.rb +79 -0
- data/lib/serverside/template.rb +5 -4
- data/lib/serverside/xml.rb +84 -0
- data/lib/serverside.rb +11 -2
- data/spec/core_ext_spec.rb +13 -58
- data/spec/daemon_spec.rb +61 -28
- data/spec/http_spec.rb +259 -0
- data/spec/template_spec.rb +9 -7
- metadata +42 -28
- data/CHANGELOG +0 -261
- data/lib/serverside/application.rb +0 -26
- data/lib/serverside/caching.rb +0 -91
- data/lib/serverside/connection.rb +0 -34
- data/lib/serverside/controllers.rb +0 -91
- data/lib/serverside/request.rb +0 -210
- data/lib/serverside/routing.rb +0 -133
- data/lib/serverside/server.rb +0 -27
- data/lib/serverside/static.rb +0 -82
- data/spec/caching_spec.rb +0 -318
- data/spec/cluster_spec.rb +0 -140
- data/spec/connection_spec.rb +0 -59
- data/spec/controllers_spec.rb +0 -142
- data/spec/request_spec.rb +0 -288
- data/spec/routing_spec.rb +0 -240
- data/spec/server_spec.rb +0 -40
- data/spec/static_spec.rb +0 -279
data/spec/static_spec.rb
DELETED
@@ -1,279 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '../lib/serverside')
|
2
|
-
require 'stringio'
|
3
|
-
require 'fileutils'
|
4
|
-
|
5
|
-
class Dummy < ServerSide::HTTP::Request
|
6
|
-
def self.mime_types
|
7
|
-
@@mime_types
|
8
|
-
end
|
9
|
-
|
10
|
-
attr_accessor :path, :socket, :headers
|
11
|
-
|
12
|
-
def initialize
|
13
|
-
super(nil)
|
14
|
-
@headers = {}
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
include ServerSide
|
19
|
-
|
20
|
-
context "Static.mime_types" do
|
21
|
-
specify "should be a hash" do
|
22
|
-
Dummy.mime_types.should_be_a_kind_of Hash
|
23
|
-
end
|
24
|
-
|
25
|
-
specify "should return text/plain as the default mime type" do
|
26
|
-
Dummy.mime_types['.rb'].should == 'text/plain'
|
27
|
-
Dummy.mime_types['.invalid'].should == 'text/plain'
|
28
|
-
end
|
29
|
-
|
30
|
-
specify "should return the correct mime type for common files" do
|
31
|
-
Dummy.mime_types['.html'].should == 'text/html'
|
32
|
-
Dummy.mime_types['.css'].should == 'text/css'
|
33
|
-
Dummy.mime_types['.js'].should == 'text/javascript'
|
34
|
-
Dummy.mime_types['.gif'].should == 'image/gif'
|
35
|
-
Dummy.mime_types['.jpg'].should == 'image/jpeg'
|
36
|
-
Dummy.mime_types['.jpeg'].should == 'image/jpeg'
|
37
|
-
Dummy.mime_types['.png'].should == 'image/png'
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
context "Static.serve_file" do
|
42
|
-
specify "should render correctly with file content, etag and size" do
|
43
|
-
c = Dummy.new
|
44
|
-
c.socket = StringIO.new
|
45
|
-
c.serve_file(__FILE__)
|
46
|
-
c.socket.rewind
|
47
|
-
resp = c.socket.read
|
48
|
-
|
49
|
-
resp.should_match /HTTP\/1.1\s200(.*)\r\n/
|
50
|
-
fc = IO.read(__FILE__)
|
51
|
-
stat = File.stat(__FILE__)
|
52
|
-
etag = (ServerSide::Static::ETAG_FORMAT %
|
53
|
-
[stat.mtime.to_i, stat.size, stat.ino])
|
54
|
-
resp.should_match /ETag:\s"#{etag}"\r\n/
|
55
|
-
resp.should_match /Content-Length:\s#{stat.size.to_s}\r\n/
|
56
|
-
end
|
57
|
-
|
58
|
-
specify "should send a not modified response only if a correct etag is specified in the request" do
|
59
|
-
stat = File.stat(__FILE__)
|
60
|
-
etag = (ServerSide::Static::ETAG_FORMAT %
|
61
|
-
[stat.mtime.to_i, stat.size, stat.ino])
|
62
|
-
|
63
|
-
# normal response
|
64
|
-
c = Dummy.new
|
65
|
-
c.socket = StringIO.new
|
66
|
-
c.serve_file(__FILE__)
|
67
|
-
c.socket.rewind
|
68
|
-
resp = c.socket.read
|
69
|
-
|
70
|
-
resp.should_match /HTTP\/1.1\s200(.*)\r\n/
|
71
|
-
resp.should_match /ETag:\s"#{etag}"\r\n/
|
72
|
-
resp.should_match /Content-Length:\s#{stat.size.to_s}\r\n/
|
73
|
-
|
74
|
-
# normal response (invalid etag)
|
75
|
-
c = Dummy.new
|
76
|
-
c.socket = StringIO.new
|
77
|
-
c.headers['If-None-Match'] = "\"xxx-yyy\""
|
78
|
-
c.serve_file(__FILE__)
|
79
|
-
c.socket.rewind
|
80
|
-
resp = c.socket.read
|
81
|
-
|
82
|
-
resp.should_match /HTTP\/1.1\s200(.*)\r\n/
|
83
|
-
resp.should_match /ETag:\s"#{etag}"\r\n/
|
84
|
-
resp.should_match /Content-Length:\s#{stat.size.to_s}\r\n/
|
85
|
-
|
86
|
-
# not modified (etag specified)
|
87
|
-
c.socket = StringIO.new
|
88
|
-
c.headers['If-None-Match'] = "\"#{etag}\""
|
89
|
-
c.valid_etag?(etag).should_be true
|
90
|
-
c.serve_file(__FILE__)
|
91
|
-
c.socket.rewind
|
92
|
-
resp = c.socket.read
|
93
|
-
|
94
|
-
resp.should_match /HTTP\/1.1\s304(.*)\r\n/
|
95
|
-
|
96
|
-
# modified response (file stamp changed)
|
97
|
-
FileUtils.touch(__FILE__)
|
98
|
-
c.socket = StringIO.new
|
99
|
-
c.headers['If-None-Match'] = etag
|
100
|
-
c.serve_file(__FILE__)
|
101
|
-
c.socket.rewind
|
102
|
-
resp = c.socket.read
|
103
|
-
|
104
|
-
resp.should_match /HTTP\/1.1\s200(.*)\r\n/
|
105
|
-
stat = File.stat(__FILE__)
|
106
|
-
etag = (ServerSide::Static::ETAG_FORMAT %
|
107
|
-
[stat.mtime.to_i, stat.size, stat.ino])
|
108
|
-
resp.should_match /ETag:\s"#{etag}"\r\n/
|
109
|
-
resp.should_match /Content-Length:\s#{stat.size.to_s}\r\n/
|
110
|
-
end
|
111
|
-
|
112
|
-
specify "should serve a 404 response for invalid files" do
|
113
|
-
c = Dummy.new
|
114
|
-
c.socket = StringIO.new
|
115
|
-
c.serve_file('invalid_file.html')
|
116
|
-
c.socket.rewind
|
117
|
-
resp = c.socket.read
|
118
|
-
|
119
|
-
resp.should_match /HTTP\/1.1\s404(.*)\r\n/
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
class IO
|
124
|
-
def self.write(fn, content)
|
125
|
-
File.open(fn, 'w') {|f| f << content}
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
class ServerSide::Template
|
130
|
-
def self.reset
|
131
|
-
@@templates = {}
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
|
136
|
-
context "Static.serve_template" do
|
137
|
-
specify "should render .rhtml file as template" do
|
138
|
-
IO.write('tmp.rhtml', '<%= @t %>')
|
139
|
-
@t = Time.now.to_f
|
140
|
-
c = Dummy.new
|
141
|
-
c.socket = StringIO.new
|
142
|
-
c.serve_template('tmp.rhtml', binding)
|
143
|
-
c.socket.rewind
|
144
|
-
resp = c.socket.read
|
145
|
-
resp.should.match /\r\n\r\n#{@t}$/
|
146
|
-
FileUtils.rm('tmp.rhtml')
|
147
|
-
end
|
148
|
-
|
149
|
-
specify "should use its own binding when none is specified" do
|
150
|
-
Template.reset
|
151
|
-
IO.write('tmp.rhtml', '<%= @path %>')
|
152
|
-
|
153
|
-
c = Dummy.new
|
154
|
-
c.socket = StringIO.new
|
155
|
-
c.path = '/test/hey'
|
156
|
-
c.serve_template('tmp.rhtml')
|
157
|
-
c.socket.rewind
|
158
|
-
resp = c.socket.read
|
159
|
-
resp.should.match /\r\n\r\n\/test\/hey$/
|
160
|
-
FileUtils.rm('tmp.rhtml')
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
context "Static.serve_dir" do
|
165
|
-
specify "should render a directory with all its entries" do
|
166
|
-
dir = File.dirname(__FILE__)
|
167
|
-
|
168
|
-
c = Dummy.new
|
169
|
-
c.socket = StringIO.new
|
170
|
-
c.path = dir
|
171
|
-
c.serve_dir(dir)
|
172
|
-
c.socket.rewind
|
173
|
-
resp = c.socket.read
|
174
|
-
|
175
|
-
Dir.entries(dir).each do |fn|
|
176
|
-
next if fn =~ /^\./
|
177
|
-
resp.should_match /<a href="#{dir/fn}">(#{fn})<\/a>/
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
context "Static.serve_static" do
|
183
|
-
specify "should serve directories" do
|
184
|
-
dir = File.dirname(__FILE__)
|
185
|
-
|
186
|
-
c = Dummy.new
|
187
|
-
c.socket = StringIO.new
|
188
|
-
c.path = dir
|
189
|
-
c.serve_static(dir)
|
190
|
-
c.socket.rewind
|
191
|
-
resp = c.socket.read
|
192
|
-
|
193
|
-
Dir.entries(dir).each do |fn|
|
194
|
-
next if fn =~ /^\./
|
195
|
-
resp.should_match /<a href="#{dir/fn}">(#{fn})<\/a>/
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
specify "should serve files" do
|
200
|
-
c = Dummy.new
|
201
|
-
c.socket = StringIO.new
|
202
|
-
c.serve_static(__FILE__)
|
203
|
-
c.socket.rewind
|
204
|
-
resp = c.socket.read
|
205
|
-
|
206
|
-
# normal response
|
207
|
-
resp.should_match /HTTP\/1.1\s200(.*)\r\n/
|
208
|
-
stat = File.stat(__FILE__)
|
209
|
-
etag = (ServerSide::Static::ETAG_FORMAT %
|
210
|
-
[stat.mtime.to_i, stat.size, stat.ino])
|
211
|
-
resp.should_match /ETag:\s"#{etag}"\r\n/
|
212
|
-
resp.should_match /Content-Length:\s#{stat.size.to_s}\r\n/
|
213
|
-
end
|
214
|
-
|
215
|
-
specify "should serve templates" do
|
216
|
-
Template.reset
|
217
|
-
IO.write('tmp.rhtml', '<%= 1 + 1%>')
|
218
|
-
|
219
|
-
c = Dummy.new
|
220
|
-
c.socket = StringIO.new
|
221
|
-
c.serve_static('tmp.rhtml')
|
222
|
-
c.socket.rewind
|
223
|
-
resp = c.socket.read
|
224
|
-
|
225
|
-
resp.should_match /HTTP\/1.1\s200(.*)\r\n/
|
226
|
-
resp.should_match /\r\n\r\n2$/
|
227
|
-
|
228
|
-
FileUtils.rm('tmp.rhtml')
|
229
|
-
end
|
230
|
-
|
231
|
-
specify "should serve index.html if exists in directory path" do
|
232
|
-
dir = File.dirname(__FILE__)/:tmp_dir
|
233
|
-
FileUtils.mkdir(dir) rescue nil
|
234
|
-
begin
|
235
|
-
IO.write(dir/'index.html', '<h1>HI</h1>')
|
236
|
-
c = Dummy.new
|
237
|
-
c.socket = StringIO.new
|
238
|
-
c.serve_static(dir)
|
239
|
-
c.socket.rewind
|
240
|
-
resp = c.socket.read
|
241
|
-
|
242
|
-
resp.should_match /HTTP\/1.1\s200(.*)\r\n/
|
243
|
-
resp.should_match /\r\n\r\n<h1>HI<\/h1>$/
|
244
|
-
resp.should_match /Content-Type: text\/html/
|
245
|
-
ensure
|
246
|
-
FileUtils.rmtree(dir) rescue nil
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
specify "should serve index.rhtml if exists in directory path" do
|
251
|
-
dir = File.dirname(__FILE__)/:tmp_dir
|
252
|
-
FileUtils.mkdir(dir) rescue puts "dir already exists"
|
253
|
-
begin
|
254
|
-
IO.write(dir/'index.rhtml', '<h1><%= @path %></h1>')
|
255
|
-
c = Dummy.new
|
256
|
-
c.socket = StringIO.new
|
257
|
-
c.path = dir
|
258
|
-
c.serve_static(dir)
|
259
|
-
c.socket.rewind
|
260
|
-
resp = c.socket.read
|
261
|
-
|
262
|
-
resp.should_match /HTTP\/1.1\s200(.*)\r\n/
|
263
|
-
resp.should_match /\r\n\r\n<h1>#{dir}<\/h1>$/
|
264
|
-
resp.should_match /Content-Type: text\/html/
|
265
|
-
ensure
|
266
|
-
FileUtils.rmtree(dir) rescue nil
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
specify "should serve a 404 response for invalid files" do
|
271
|
-
c = Dummy.new
|
272
|
-
c.socket = StringIO.new
|
273
|
-
c.serve_static('invalid_file.html')
|
274
|
-
c.socket.rewind
|
275
|
-
resp = c.socket.read
|
276
|
-
|
277
|
-
resp.should_match /HTTP\/1.1\s404(.*)\r\n/
|
278
|
-
end
|
279
|
-
end
|