./lib/lux/response/lib/file.rb in lux-fw-0.5.37 vs ./lib/lux/response/lib/file.rb in lux-fw-0.6.2
- old
+ new
@@ -1,81 +1,103 @@
# frozen_string_literal: true
-class Lux::Response::File
- MIMME_TYPES = {
- txt: 'text/plain',
- html: 'text/html',
- gif: 'image/gif',
- jpg: 'image/jpeg',
- jpeg: 'image/jpeg',
- png: 'image/png',
- ico: 'image/png', # image/x-icon
- css: 'text/css',
- map: 'application/json',
- js: 'application/javascript',
- gz: 'application/x-gzip',
- zip: 'application/x-gzip',
- svg: 'image/svg+xml',
- mp3: 'application/mp3',
- woff: 'application/x-font-woff',
- woff2: 'application/x-font-woff',
- ttf: 'application/font-ttf',
- eot: 'application/vnd.ms-fontobject',
- otf: 'application/font-otf',
- doc: 'application/msword'
- }
+module Lux
+ class Response
+ class File
+ class << self
+ def deliver_from_current
+ path = './public' + Lux.current.request.path
+ ext = path.split('.').last
+ return unless ext.length > 1 && ext.length < 5
+ rack_file = new file: path, inline: true
+ rack_file.send if rack_file.is_static_file?
+ end
- ###
- # all parametars are optional
- # :name - file name
- # :cache - client cache in seconds
- # :content_type - string type
- # :inline - sets disposition to inline if true
- # :disposition - inline or attachment
- # :content - raw file data
- def initialize file, in_opts={}
- opts = in_opts.to_opts :name, :cache, :content_type, :inline, :disposition, :content
- opts.disposition ||= opts.inline.class == TrueClass ? 'inline' : 'attachment'
- opts.cache = true if opts.cache.nil?
+ def type name
+ MIMME_TYPES[name.to_sym]
+ end
+ end
- file = 'public/%s' % file unless file[0, 1] == '/'
+ ###
- @ext = file.include?('.') ? file.split('.').last.to_sym : nil
- @file = file
- @opts = opts
- end
+ MIMME_TYPES = {
+ css: 'text/css',
+ doc: 'application/msword',
+ eot: 'application/vnd.ms-fontobject',
+ gif: 'image/gif',
+ gz: 'application/x-gzip',
+ html: 'text/html',
+ ico: 'image/png', # image/x-icon
+ jpeg: 'image/jpeg',
+ jpg: 'image/jpeg',
+ js: 'text/javascript',
+ json: 'application/json',
+ map: 'application/json',
+ mp3: 'application/mp3',
+ otf: 'application/font-otf',
+ png: 'image/png',
+ svg: 'image/svg+xml',
+ text: 'text/plain',
+ ttf: 'application/font-ttf',
+ txt: 'text/plain',
+ webp: 'image/webp',
+ woff: 'application/x-font-woff',
+ woff2: 'application/x-font-woff',
+ xml: 'application/xml',
+ zip: 'application/x-gzip'
+ }
- define_method(:request) { Lux.current.request }
- define_method(:response) { Lux.current.response }
+ OPTS = Struct.new 'LuxResponseFileOpts', :name, :file, :content_type, :inline, :disposition, :content, :ext, :path
- def is_static_file?
- return false unless @ext
- File.exist?(@file)
- end
+ ###
+ # all parametars are optional
+ # :name - file name
+ # :content_type - string type
+ # :inline - sets disposition to inline if true
+ # :disposition - inline or attachment
+ # :content - raw file data
+ def initialize in_opts = {}
+ opts = OPTS.new **in_opts
+ opts.disposition ||= opts.inline.class == TrueClass ? 'inline' : 'attachment'
+ opts.file = Pathname.new(opts.file) unless opts.file.class == Pathname
+ opts.path = opts.file.to_s
+ opts.ext = opts.path.include?('.') ? opts.path.split('.').last.to_sym : nil
- def send
- file = File.exist?(@file) ? @file : Lux.root.join("public#{@file}").to_s
+ @opts = opts
+ end
- raise Lux::Error.not_found('Static file not found') unless File.exists?(file)
+ define_method(:request) { Lux.current.request }
+ define_method(:response) { Lux.current.response }
- response.content_type(@opts.content_type || MIMME_TYPES[@ext || '_'] || 'application/octet-stream')
+ def is_static_file?
+ return false unless @opts.ext
+ @opts.file.exist?
+ end
- file_mtime = File.mtime(file).utc.to_s
- key = Crypt.sha1(file + (@opts.content || file_mtime.to_s))
+ def etag key
+ response.headers['etag'] = '"%s"' % key
+ response.body('not-modified', status: 304) if request.env['HTTP_IF_NONE_MATCH'] == key
+ end
- if @opts.disposition == 'attachment'
- @opts.name ||= @file.split('/').last
- response.headers['content-disposition'] = 'attachment; filename=%s' % @opts.name
- end
+ def send
+ @opts.name ||= @opts.path.split('/').last
+ if @opts.disposition == 'attachment'
+ response.headers['content-disposition'] = 'attachment; filename=%s' % @opts.name
+ end
- response.headers['cache-control'] = 'max-age=%d, public' % (@opts.cache ? 31536000 : 0)
- response.headers['etag'] = '"%s"' % key
- response.headers['last-modified'] = file_mtime
+ response.content_type(@opts.content_type || MIMME_TYPES[@opts.ext || '_'] || 'application/octet-stream')
+ response.headers['access-control-allow-origin'] ||= '*'
- # IF etags match, returnfrom cache
- if request.env['HTTP_IF_NONE_MATCH'] == key
- response.body('not-modified', 304)
- else
- response.body @opts.content || File.read(file)
+ if @opts.content
+ etag Crypt.sha1 @opts.content
+ response.body @opts.content
+ else
+ raise Lux::Error.not_found('File not found') unless @opts.file.exist?
+ file_mtime = @opts.file.mtime.utc.to_s
+ response.headers['last-modified'] = file_mtime
+ etag Crypt.sha1(@opts.path + (@opts.content || file_mtime.to_s))
+ response.body @opts.file.read
+ end
+ end
end
end
-end
\ No newline at end of file
+end