Class: Radio::HTTP::FileResponse

Inherits:
Object
  • Object
show all
Defined in:
lib/radio/http/file.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env, filename, content_type = nil) ⇒ FileResponse

Returns a new instance of FileResponse.



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
52
53
54
55
56
57
# File 'lib/radio/http/file.rb', line 20

def initialize(env, filename, content_type = nil)
  @env = env
  @filename = filename
  @status = 200
  @headers = {}
  @body = []
    
  begin
    raise Errno::EPERM unless File.file?(filename) and File.readable?(filename)
  rescue SystemCallError
    @body = ["404 Not Found\n"]
    @headers["Content-Length"] = @body.first.size.to_s
    @headers["Content-Type"] = 'text/plain'
    @headers["X-Cascade"] = 'pass'
    @status = 404
    return
  end
    
  # Caching strategy
  mod_since = Time.httpdate(env['HTTP_IF_MODIFIED_SINCE']) rescue nil
  last_modified = File.mtime(filename)
  @status = 304 and return if last_modified == mod_since
  @headers["Last-Modified"] = last_modified.httpdate
  if env['QUERY_STRING'] =~ /^[0-9]{9,10}$/ and last_modified == Time.at(env['QUERY_STRING'].to_i)
    @headers["Cache-Control"] = 'max-age=86400, public' # one day
  else
    @headers["Cache-Control"] = 'max-age=0, private, must-revalidate'
  end
    
  # Sending the file or reading an unknown length stream to send
  @body = self
  unless size = File.size?(filename)
    @body = [File.read(filename)]
    size = @body.first.respond_to?(:bytesize) ? @body.first.bytesize : @body.first.size
  end
  @headers["Content-Length"] = size.to_s
  @headers["Content-Type"] = content_type || Rack::Mime.mime_type(File.extname(filename), 'text/plain')
end

Instance Attribute Details

#filenameString (readonly) Also known as: to_path

Filename attribute. Alias is used by some rack servers to detach from Ruby early.

Returns:

  • (String)


72
73
74
# File 'lib/radio/http/file.rb', line 72

def filename
  @filename
end

Instance Method Details

#each {|String| ... } ⇒ Object

Support using self as a response body.

Yields:

  • (String)

    8k blocks



61
62
63
64
65
66
67
# File 'lib/radio/http/file.rb', line 61

def each
  File.open(@filename, "rb") do |file|
    while part = file.read(8192)
      yield part
    end
  end
end

#finishArray

Present the final response for rack.

Returns:

  • (Array)
    status, headers, body


82
83
84
# File 'lib/radio/http/file.rb', line 82

def finish
  [@status, @headers, @body]
end

#found?Boolean

Was the file in the system and ready to be served?

Returns:

  • (Boolean)


76
77
78
# File 'lib/radio/http/file.rb', line 76

def found?
  @status == 200 or @status == 304
end