utopia 0.9.57 → 0.9.58
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/utopia/extensions/rack.rb +17 -0
- data/lib/utopia/http_status_codes.rb +1 -0
- data/lib/utopia/middleware.rb +11 -0
- data/lib/utopia/middleware/static.rb +52 -9
- data/lib/utopia/setup/pages/_page.xnode +2 -2
- data/lib/utopia/version.rb +1 -1
- metadata +7 -20
@@ -2,6 +2,19 @@
|
|
2
2
|
# Copyright 2010 Samuel Williams. All rights reserved.
|
3
3
|
# See <utopia.rb> for licensing details.
|
4
4
|
|
5
|
+
class Rack::Request
|
6
|
+
def url_with_path(path = "")
|
7
|
+
url = scheme + "://"
|
8
|
+
url << host
|
9
|
+
|
10
|
+
if scheme == "https" && port != 443 || scheme == "http" && port != 80
|
11
|
+
url << ":#{port}"
|
12
|
+
end
|
13
|
+
|
14
|
+
url << path
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
5
18
|
class Rack::Response
|
6
19
|
def do_not_cache!
|
7
20
|
self["Cache-Control"] = "no-cache, must-revalidate"
|
@@ -14,4 +27,8 @@ class Rack::Response
|
|
14
27
|
self["Expires"] = (Time.now + duration).httpdate
|
15
28
|
end
|
16
29
|
end
|
30
|
+
|
31
|
+
def content_type!(value)
|
32
|
+
self["Content-Type"] = value.to_s
|
33
|
+
end
|
17
34
|
end
|
data/lib/utopia/middleware.rb
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
require 'pathname'
|
6
6
|
require 'logger'
|
7
7
|
|
8
|
+
require 'utopia/http_status_codes'
|
8
9
|
require 'utopia/extensions/rack'
|
9
10
|
|
10
11
|
module Utopia
|
@@ -15,6 +16,16 @@ module Utopia
|
|
15
16
|
def self.default_root(subdir = "pages")
|
16
17
|
Pathname.new(Dir.pwd).join(subdir).cleanpath.to_s
|
17
18
|
end
|
19
|
+
|
20
|
+
def self.failure(status = 500, message = "Non-specific error")
|
21
|
+
body = "#{HTTP_STATUS_DESCRIPTIONS[status] || status.to_s}: #{message}"
|
22
|
+
|
23
|
+
return [status, {
|
24
|
+
"Content-Type" => "text/plain",
|
25
|
+
"Content-Length" => body.size.to_s,
|
26
|
+
"X-Cascade" => "pass"
|
27
|
+
}, [body]]
|
28
|
+
end
|
18
29
|
end
|
19
30
|
end
|
20
31
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# This file is part of the "Utopia Framework" project, and is licensed under the GNU AGPLv3.
|
2
2
|
# Copyright 2010 Samuel Williams. All rights reserved.
|
3
3
|
# See <utopia.rb> for licensing details.
|
4
|
+
|
4
5
|
require 'utopia/middleware'
|
5
6
|
require 'utopia/path'
|
6
7
|
|
@@ -50,11 +51,14 @@ module Utopia
|
|
50
51
|
@root = root
|
51
52
|
@path = path
|
52
53
|
@etag = Digest::SHA1.hexdigest("#{File.size(full_path)}#{mtime_date}")
|
54
|
+
|
55
|
+
@range = nil
|
53
56
|
end
|
54
57
|
|
55
58
|
attr :root
|
56
59
|
attr :path
|
57
60
|
attr :etag
|
61
|
+
attr :range
|
58
62
|
|
59
63
|
# Fit in with Rack::Sendfile
|
60
64
|
def to_path
|
@@ -74,8 +78,15 @@ module Utopia
|
|
74
78
|
end
|
75
79
|
|
76
80
|
def each
|
77
|
-
File.open(full_path, "rb") do |
|
78
|
-
|
81
|
+
File.open(full_path, "rb") do |file|
|
82
|
+
file.seek(@range.begin)
|
83
|
+
remaining = @range.end - @range.begin+1
|
84
|
+
|
85
|
+
while remaining > 0
|
86
|
+
break unless part = file.read([8192, remaining].min)
|
87
|
+
|
88
|
+
remaining -= part.length
|
89
|
+
|
79
90
|
yield part
|
80
91
|
end
|
81
92
|
end
|
@@ -93,6 +104,38 @@ module Utopia
|
|
93
104
|
|
94
105
|
return true
|
95
106
|
end
|
107
|
+
|
108
|
+
def serve(env, response_headers)
|
109
|
+
ranges = Rack::Utils.byte_ranges(env, size)
|
110
|
+
response = [200, response_headers, self]
|
111
|
+
|
112
|
+
# LOG.info("Requesting ranges: #{ranges.inspect} (#{size})")
|
113
|
+
|
114
|
+
if ranges.nil? || ranges.length > 1
|
115
|
+
# No ranges, or multiple ranges (which we don't support):
|
116
|
+
# TODO: Support multiple byte-ranges
|
117
|
+
response[0] = 200
|
118
|
+
response[1]["Content-Length"] = size.to_s
|
119
|
+
@range = 0..size-1
|
120
|
+
elsif ranges.empty?
|
121
|
+
# Unsatisfiable. Return error, and file size:
|
122
|
+
response = Middleware::failure(416, "Invalid range specified.")
|
123
|
+
response[1]["Content-Range"] = "bytes */#{size}"
|
124
|
+
return response
|
125
|
+
else
|
126
|
+
# Partial content:
|
127
|
+
@range = ranges[0]
|
128
|
+
response[0] = 206
|
129
|
+
response[1]["Content-Range"] = "bytes #{@range.begin}-#{@range.end}/#{size}"
|
130
|
+
response[1]["Content-Length"] = (@range.end - @range.begin+1).to_s
|
131
|
+
size = @range.end - @range.begin + 1
|
132
|
+
end
|
133
|
+
|
134
|
+
# LOG.info("Response for #{self.full_path}: #{response.inspect}")
|
135
|
+
LOG.info "Serving file #{full_path.inspect}, range #{@range.inspect}"
|
136
|
+
|
137
|
+
return response
|
138
|
+
end
|
96
139
|
end
|
97
140
|
|
98
141
|
def load_mime_types(types)
|
@@ -141,15 +184,15 @@ module Utopia
|
|
141
184
|
def initialize(app, options = {})
|
142
185
|
@app = app
|
143
186
|
@root = options[:root] || Utopia::Middleware::default_root
|
144
|
-
|
187
|
+
|
145
188
|
if options[:types]
|
146
189
|
@extensions = load_mime_types(options[:types])
|
147
190
|
else
|
148
191
|
@extensions = load_mime_types(MIME_TYPES[:default])
|
149
192
|
end
|
150
|
-
|
193
|
+
|
151
194
|
@cache_control = options[:cache_control] || "public, max-age=3600"
|
152
|
-
|
195
|
+
|
153
196
|
LOG.info "** #{self.class.name}: Running in #{@root} with #{extensions.size} filetypes"
|
154
197
|
# LOG.info @extensions.inspect
|
155
198
|
end
|
@@ -203,21 +246,21 @@ module Utopia
|
|
203
246
|
def call(env)
|
204
247
|
request = Rack::Request.new(env)
|
205
248
|
ext = File.extname(request.path_info)
|
249
|
+
|
206
250
|
if @extensions.key? ext.downcase
|
207
251
|
path = Path.create(request.path_info).simplify
|
208
|
-
|
252
|
+
|
209
253
|
if file = fetch_file(path)
|
210
254
|
response_headers = {
|
211
255
|
"Last-Modified" => file.mtime_date,
|
212
256
|
"Content-Type" => @extensions[ext],
|
213
257
|
"Cache-Control" => @cache_control,
|
214
258
|
"ETag" => file.etag,
|
259
|
+
"Accept-Ranges" => "bytes"
|
215
260
|
}
|
216
261
|
|
217
262
|
if file.modified?(env)
|
218
|
-
|
219
|
-
|
220
|
-
return [200, response_headers, file]
|
263
|
+
return file.serve(env, response_headers)
|
221
264
|
else
|
222
265
|
return [304, response_headers, []]
|
223
266
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
3
|
<head>
|
4
|
-
<?r response
|
5
|
-
<?r response
|
4
|
+
<?r response.content_type! "text/html; charset=utf-8" ?>
|
5
|
+
<?r response.cache! ?>
|
6
6
|
|
7
7
|
<?r if title = (attributes["title"] || @title) ?>
|
8
8
|
<title>#{title.gsub(/<.*?>/, "")} - Utopia</title>
|
data/lib/utopia/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: utopia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
4
|
+
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
8
|
+
- 58
|
9
|
+
version: 0.9.58
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Samuel Williams
|
@@ -15,17 +14,16 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date:
|
17
|
+
date: 2012-01-12 00:00:00 +13:00
|
18
|
+
default_executable: utopia
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: mime-types
|
22
22
|
prerelease: false
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
-
none: false
|
25
24
|
requirements:
|
26
25
|
- - ">="
|
27
26
|
- !ruby/object:Gem::Version
|
28
|
-
hash: 3
|
29
27
|
segments:
|
30
28
|
- 0
|
31
29
|
version: "0"
|
@@ -35,11 +33,9 @@ dependencies:
|
|
35
33
|
name: rack
|
36
34
|
prerelease: false
|
37
35
|
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
-
none: false
|
39
36
|
requirements:
|
40
37
|
- - ">="
|
41
38
|
- !ruby/object:Gem::Version
|
42
|
-
hash: 3
|
43
39
|
segments:
|
44
40
|
- 0
|
45
41
|
version: "0"
|
@@ -49,11 +45,9 @@ dependencies:
|
|
49
45
|
name: rack-cache
|
50
46
|
prerelease: false
|
51
47
|
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
-
none: false
|
53
48
|
requirements:
|
54
49
|
- - ">="
|
55
50
|
- !ruby/object:Gem::Version
|
56
|
-
hash: 3
|
57
51
|
segments:
|
58
52
|
- 0
|
59
53
|
version: "0"
|
@@ -63,11 +57,9 @@ dependencies:
|
|
63
57
|
name: rack-contrib
|
64
58
|
prerelease: false
|
65
59
|
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
60
|
requirements:
|
68
61
|
- - ">="
|
69
62
|
- !ruby/object:Gem::Version
|
70
|
-
hash: 3
|
71
63
|
segments:
|
72
64
|
- 0
|
73
65
|
version: "0"
|
@@ -77,11 +69,9 @@ dependencies:
|
|
77
69
|
name: rmagick
|
78
70
|
prerelease: false
|
79
71
|
requirement: &id005 !ruby/object:Gem::Requirement
|
80
|
-
none: false
|
81
72
|
requirements:
|
82
73
|
- - ">="
|
83
74
|
- !ruby/object:Gem::Version
|
84
|
-
hash: 3
|
85
75
|
segments:
|
86
76
|
- 0
|
87
77
|
version: "0"
|
@@ -155,6 +145,7 @@ files:
|
|
155
145
|
- lib/utopia/xnode.rb
|
156
146
|
- lib/utopia.rb
|
157
147
|
- bin/utopia
|
148
|
+
has_rdoc: true
|
158
149
|
homepage: http://www.oriontransfer.co.nz/software/utopia
|
159
150
|
licenses: []
|
160
151
|
|
@@ -164,27 +155,23 @@ rdoc_options: []
|
|
164
155
|
require_paths:
|
165
156
|
- lib
|
166
157
|
required_ruby_version: !ruby/object:Gem::Requirement
|
167
|
-
none: false
|
168
158
|
requirements:
|
169
159
|
- - ">="
|
170
160
|
- !ruby/object:Gem::Version
|
171
|
-
hash: 3
|
172
161
|
segments:
|
173
162
|
- 0
|
174
163
|
version: "0"
|
175
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
176
|
-
none: false
|
177
165
|
requirements:
|
178
166
|
- - ">="
|
179
167
|
- !ruby/object:Gem::Version
|
180
|
-
hash: 3
|
181
168
|
segments:
|
182
169
|
- 0
|
183
170
|
version: "0"
|
184
171
|
requirements: []
|
185
172
|
|
186
173
|
rubyforge_project:
|
187
|
-
rubygems_version: 1.
|
174
|
+
rubygems_version: 1.3.6
|
188
175
|
signing_key:
|
189
176
|
specification_version: 3
|
190
177
|
summary: Utopia is a framework for building websites.
|