Class: Utopia::Static

Inherits:
Object
  • Object
show all
Defined in:
lib/utopia/static.rb

Overview

Serve static files and include recursive name resolution using @rel@ directory entries.

Defined Under Namespace

Classes: LocalFile

Constant Summary collapse

MIME_TYPES =
{
  :xiph => {
    "ogx" => "application/ogg",
    "ogv" => "video/ogg",
    "oga" => "audio/ogg",
    "ogg" => "audio/ogg",
    "spx" => "audio/ogg",
    "flac" => "audio/flac",
    "anx" => "application/annodex",
    "axa" => "audio/annodex",
    "xspf" => "application/xspf+xml",
  },
  :media => [
    :xiph, "mp3", "mp4", "wav", "aiff", ["aac", "audio/x-aac"], "mov", "avi", "wmv", "mpg"
  ],
  :text => [
    "html", "css", "js", ["map", "application/json"], "txt", "rtf", "xml", "pdf"
  ],
  :fonts => [
    "otf", ["eot", "application/vnd.ms-fontobject"], "ttf", "woff"
  ],
  :archive => [
    "zip", "tar", "tgz", "tar.gz", "tar.bz2", ["dmg", "application/x-apple-diskimage"],
    ["torrent", "application/x-bittorrent"]
  ],
  :images => [
    "png", "gif", "jpeg", "tiff", "svg"
  ],
  :default => [
    :media, :text, :archive, :images, :fonts
  ]
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, **options) ⇒ Static



197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/utopia/static.rb', line 197

def initialize(app, **options)
  @app = app
  @root = (options[:root] || Utopia::default_root).freeze

  if options[:types]
    @extensions = load_mime_types(options[:types])
  else
    @extensions = load_mime_types(MIME_TYPES[:default])
  end

  @cache_control = (options[:cache_control] || "public, max-age=3600")
  
  self.freeze
end

Instance Attribute Details

#extensionsObject (readonly)

Returns the value of attribute extensions.



231
232
233
# File 'lib/utopia/static.rb', line 231

def extensions
  @extensions
end

Instance Method Details

#call(env) ⇒ Object



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/utopia/static.rb', line 233

def call(env)
  path_info = env[Rack::PATH_INFO]
  extension = File.extname(path_info)

  if @extensions.key? extension.downcase
    path = Path[path_info].simplify
    
    if locale = env[Localization::CURRENT_LOCALE_KEY]
      path.last.insert(path.last.rindex('.') || -1, ".#{locale}")
    end
    
    if file = fetch_file(path)
      response_headers = {
        "Last-Modified" => file.mtime_date,
        "Content-Type" => @extensions[extension],
        "Cache-Control" => @cache_control,
        "ETag" => file.etag,
        "Accept-Ranges" => "bytes"
      }

      if file.modified?(env)
        return file.serve(env, response_headers)
      else
        return [304, response_headers, []]
      end
    end
  end

  # else if no file was found:
  return @app.call(env)
end

#fetch_file(path) ⇒ Object



220
221
222
223
224
225
226
227
228
229
# File 'lib/utopia/static.rb', line 220

def fetch_file(path)
  # We need file_path to be an absolute path for X-Sendfile to work correctly.
  file_path = File.join(@root, path.components)
  
  if File.exist?(file_path)
    return LocalFile.new(@root, path)
  else
    return nil
  end
end

#freezeObject



212
213
214
215
216
217
218
# File 'lib/utopia/static.rb', line 212

def freeze
  @root.freeze
  @extensions.freeze
  @cache_control.freeze
  
  super
end