mirror of
				https://gitea.invidious.io/iv-org/shard-kemal.git
				synced 2024-08-15 00:53:36 +00:00 
			
		
		
		
	moved static file handler code to send_file (#330)
This commit is contained in:
		
							parent
							
								
									e276c0a278
								
							
						
					
					
						commit
						298a4b234b
					
				
					 2 changed files with 76 additions and 78 deletions
				
			
		|  | @ -81,7 +81,8 @@ def headers(env, additional_headers) | ||||||
|   env.response.headers.merge!(additional_headers) |   env.response.headers.merge!(additional_headers) | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| # Send a file with given path and default `application/octet-stream` mime_type. | # Send a file with given path and base the mime-type on the file extension | ||||||
|  | # or default `application/octet-stream` mime_type. | ||||||
| # | # | ||||||
| #   send_file env, "./path/to/file" | #   send_file env, "./path/to/file" | ||||||
| # | # | ||||||
|  | @ -89,11 +90,82 @@ end | ||||||
| # | # | ||||||
| #   send_file env, "./path/to/file", "image/jpeg" | #   send_file env, "./path/to/file", "image/jpeg" | ||||||
| def send_file(env, path : String, mime_type : String? = nil) | def send_file(env, path : String, mime_type : String? = nil) | ||||||
|  |   config = Kemal.config.serve_static | ||||||
|   file_path = File.expand_path(path, Dir.current) |   file_path = File.expand_path(path, Dir.current) | ||||||
|   mime_type ||= "application/octet-stream" |   mime_type ||= Kemal::Utils.mime_type(file_path) | ||||||
|   env.response.content_type = mime_type |   env.response.content_type = mime_type | ||||||
|   env.response.content_length = File.size(file_path) |   minsize = 860 # http://webmasters.stackexchange.com/questions/31750/what-is-recommended-minimum-object-size-for-gzip-performance-benefits ?? | ||||||
|  |   request_headers = env.request.headers | ||||||
|  |   filesize = File.size(file_path) | ||||||
|   File.open(file_path) do |file| |   File.open(file_path) do |file| | ||||||
|  |     if env.request.method == "GET" && env.request.headers.has_key?("Range") | ||||||
|  |       next multipart(file, env) | ||||||
|  |     end | ||||||
|  |     if request_headers.includes_word?("Accept-Encoding", "gzip") && config.is_a?(Hash) && config["gzip"] == true && filesize > minsize && Kemal::Utils.zip_types(file_path) | ||||||
|  |       env.response.headers["Content-Encoding"] = "gzip" | ||||||
|  |       Gzip::Writer.open(env.response) do |deflate| | ||||||
|  |         IO.copy(file, deflate) | ||||||
|  |       end | ||||||
|  |     elsif request_headers.includes_word?("Accept-Encoding", "deflate") && config.is_a?(Hash) && config["gzip"]? == true && filesize > minsize && Kemal::Utils.zip_types(file_path) | ||||||
|  |       env.response.headers["Content-Encoding"] = "deflate" | ||||||
|  |       Flate::Writer.new(env.response) do |deflate| | ||||||
|  |         IO.copy(file, deflate) | ||||||
|  |       end | ||||||
|  |     else | ||||||
|  |       env.response.content_length = filesize | ||||||
|  |       IO.copy(file, env.response) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | private def multipart(file, env) | ||||||
|  |   # See http://httpwg.org/specs/rfc7233.html | ||||||
|  |   fileb = file.size | ||||||
|  | 
 | ||||||
|  |   range = env.request.headers["Range"] | ||||||
|  |   match = range.match(/bytes=(\d{1,})-(\d{0,})/) | ||||||
|  | 
 | ||||||
|  |   startb = 0 | ||||||
|  |   endb = 0 | ||||||
|  | 
 | ||||||
|  |   if match | ||||||
|  |     if match.size >= 2 | ||||||
|  |       startb = match[1].to_i { 0 } | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     if match.size >= 3 | ||||||
|  |       endb = match[2].to_i { 0 } | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   if endb == 0 | ||||||
|  |     endb = fileb | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   if startb < endb && endb <= fileb | ||||||
|  |     env.response.status_code = 206 | ||||||
|  |     env.response.content_length = endb - startb | ||||||
|  |     env.response.headers["Accept-Ranges"] = "bytes" | ||||||
|  |     env.response.headers["Content-Range"] = "bytes #{startb}-#{endb - 1}/#{fileb}" # MUST | ||||||
|  | 
 | ||||||
|  |     if startb > 1024 | ||||||
|  |       skipped = 0 | ||||||
|  |       # file.skip only accepts values less or equal to 1024 (buffer size, undocumented) | ||||||
|  |       until skipped + 1024 > startb | ||||||
|  |         file.skip(1024) | ||||||
|  |         skipped += 1024 | ||||||
|  |       end | ||||||
|  |       if skipped - startb > 0 | ||||||
|  |         file.skip(skipped - startb) | ||||||
|  |       end | ||||||
|  |     else | ||||||
|  |       file.skip(startb) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     IO.copy(file, env.response, endb - startb) | ||||||
|  |   else | ||||||
|  |     env.response.content_length = fileb | ||||||
|  |     env.response.status_code = 200 # Range not satisfable, see 4.4 Note | ||||||
|     IO.copy(file, env.response) |     IO.copy(file, env.response) | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -51,29 +51,7 @@ module Kemal | ||||||
|         end |         end | ||||||
|       elsif File.exists?(file_path) |       elsif File.exists?(file_path) | ||||||
|         return if etag(context, file_path) |         return if etag(context, file_path) | ||||||
|         minsize = 860 # http://webmasters.stackexchange.com/questions/31750/what-is-recommended-minimum-object-size-for-gzip-performance-benefits ?? |         send_file(context, file_path) | ||||||
|         context.response.content_type = Utils.mime_type(file_path) |  | ||||||
|         request_headers = context.request.headers |  | ||||||
|         filesize = File.size(file_path) |  | ||||||
|         File.open(file_path) do |file| |  | ||||||
|           if context.request.method == "GET" && context.request.headers.has_key?("Range") |  | ||||||
|             next multipart(file, context) |  | ||||||
|           end |  | ||||||
|           if request_headers.includes_word?("Accept-Encoding", "gzip") && config.is_a?(Hash) && config["gzip"] == true && filesize > minsize && Utils.zip_types(file_path) |  | ||||||
|             context.response.headers["Content-Encoding"] = "gzip" |  | ||||||
|             Gzip::Writer.open(context.response) do |deflate| |  | ||||||
|               IO.copy(file, deflate) |  | ||||||
|             end |  | ||||||
|           elsif request_headers.includes_word?("Accept-Encoding", "deflate") && config.is_a?(Hash) && config["gzip"]? == true && filesize > minsize && Utils.zip_types(file_path) |  | ||||||
|             context.response.headers["Content-Encoding"] = "deflate" |  | ||||||
|             Flate::Writer.new(context.response) do |deflate| |  | ||||||
|               IO.copy(file, deflate) |  | ||||||
|             end |  | ||||||
|           else |  | ||||||
|             context.response.content_length = filesize |  | ||||||
|             IO.copy(file, context.response) |  | ||||||
|           end |  | ||||||
|         end |  | ||||||
|       else |       else | ||||||
|         call_next(context) |         call_next(context) | ||||||
|       end |       end | ||||||
|  | @ -88,57 +66,5 @@ module Kemal | ||||||
|       context.response.status_code = 304 # not modified |       context.response.status_code = 304 # not modified | ||||||
|       return true |       return true | ||||||
|     end |     end | ||||||
| 
 |  | ||||||
|     private def multipart(file, env) |  | ||||||
|       # See http://httpwg.org/specs/rfc7233.html |  | ||||||
|       fileb = file.size |  | ||||||
| 
 |  | ||||||
|       range = env.request.headers["Range"] |  | ||||||
|       match = range.match(/bytes=(\d{1,})-(\d{0,})/) |  | ||||||
| 
 |  | ||||||
|       startb = 0 |  | ||||||
|       endb = 0 |  | ||||||
| 
 |  | ||||||
|       if match |  | ||||||
|         if match.size >= 2 |  | ||||||
|           startb = match[1].to_i { 0 } |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         if match.size >= 3 |  | ||||||
|           endb = match[2].to_i { 0 } |  | ||||||
|         end |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|       if endb == 0 |  | ||||||
|         endb = fileb |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|       if startb < endb && endb <= fileb |  | ||||||
|         env.response.status_code = 206 |  | ||||||
|         env.response.content_length = endb - startb |  | ||||||
|         env.response.headers["Accept-Ranges"] = "bytes" |  | ||||||
|         env.response.headers["Content-Range"] = "bytes #{startb}-#{endb - 1}/#{fileb}" # MUST |  | ||||||
| 
 |  | ||||||
|         if startb > 1024 |  | ||||||
|           skipped = 0 |  | ||||||
|           # file.skip only accepts values less or equal to 1024 (buffer size, undocumented) |  | ||||||
|           until skipped + 1024 > startb |  | ||||||
|             file.skip(1024) |  | ||||||
|             skipped += 1024 |  | ||||||
|           end |  | ||||||
|           if skipped - startb > 0 |  | ||||||
|             file.skip(skipped - startb) |  | ||||||
|           end |  | ||||||
|         else |  | ||||||
|           file.skip(startb) |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         IO.copy(file, env.response, endb - startb) |  | ||||||
|       else |  | ||||||
|         env.response.content_length = fileb |  | ||||||
|         env.response.status_code = 200 # Range not satisfable, see 4.4 Note |  | ||||||
|         IO.copy(file, env.response) |  | ||||||
|       end |  | ||||||
|     end |  | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue