utopia 0.9.57 → 0.9.58
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/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.
|