Class: PublicAssets

Inherits:
Object
  • Object
show all
Defined in:
lib/yodel/middleware/public_assets.rb

Overview

some code copied from Rack::File

Constant Summary collapse

SEPARATORS =
Regexp.union(*[::File::SEPARATOR, ::File::ALT_SEPARATOR].compact)

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ PublicAssets

Returns a new instance of PublicAssets.



8
9
10
# File 'lib/yodel/middleware/public_assets.rb', line 8

def initialize(app)
  @app = app
end

Instance Method Details

#call(env) ⇒ Object

Raises:



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/yodel/middleware/public_assets.rb', line 12

def call(env)
  parts = Rack::Utils.unescape(env["PATH_INFO"]).split(SEPARATORS)
  return [403, {"Content-Type" => "text/plain"}, "Forbidden"] if parts.include? ".."
  request = Rack::Request.new(env)
  site = env['yodel.site']
  
  # when a site is missing, use the default set of public directories
  unless site.nil?
    public_directories = site.public_directories
  else
    public_directories = Yodel.config.public_directories
  end
  
  # attachments are handled separately to normal public resources; to handle
  # /attachments/* the same way as other public folders, the site root would
  # need to be used as a public folder. Adding attachments as a public folder
  # and removing /attachments/ from the url, or making the path of all
  # attachments in development have no /attachments/ prefix could cause issues.
  if !site.nil? && parts[1] == 'attachments'
    path = File.join(site.attachments_directory, *parts[2..-1])
    if File.file?(path) && File.readable?(path)
      return dup.serve_file(path, env)
    end
  else
    public_directories.each do |public_dir|
      path = File.join(public_dir, *parts)
      if File.file?(path) && File.readable?(path)
        return dup.serve_file(path, env)
      end
    end
  end
  
  # raise any delayed exceptions. These are delayed till this middleware so
  # the assets needed to render the error pages for them are available. Without
  # this delay, a DomainNotFound exception raised in SiteDetector would prevent
  # PublicAssest from serving the css or images used on the error page.
  raise DomainNotFound.new(request.host, request.port) if site.nil?
  raise MissingRootDirectory.new(site, request.port) if !File.directory?(site.root_directory)
  @app.call(env)
end

#eachObject



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/yodel/middleware/public_assets.rb', line 53

def each
  File.open(@path, 'rb') do |file|
    file.seek(@range.begin)
    remaining_len = @range.end - @range.begin + 1
    while remaining_len > 0
      part = file.read([8192, remaining_len].min)
      break unless part
      remaining_len -= part.length
      yield part
    end
  end
end