diff --git a/Gemfile.lock b/Gemfile.lock index 7078d544cbb50..a45fa1029285b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,6 +2,7 @@ PATH remote: . specs: activefile (0.1) + actionpack (>= 5.1) activejob (>= 5.1) activerecord (>= 5.1) activesupport (>= 5.1) @@ -9,6 +10,19 @@ PATH GEM remote: https://rubygems.org/ specs: + actionpack (5.1.1) + actionview (= 5.1.1) + activesupport (= 5.1.1) + rack (~> 2.0) + rack-test (~> 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.1.1) + activesupport (= 5.1.1) + builder (~> 3.1) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) activejob (5.1.1) activesupport (= 5.1.1) globalid (>= 0.3.6) @@ -34,11 +48,13 @@ GEM aws-sdk-resources (2.10.7) aws-sdk-core (= 2.10.7) aws-sigv4 (1.0.0) + builder (3.2.3) byebug (9.0.6) concurrent-ruby (1.0.5) declarative (0.0.9) declarative-option (0.1.0) digest-crc (0.4.1) + erubi (1.6.0) faraday (0.12.1) multipart-post (>= 1.2, < 3) globalid (0.4.0) @@ -161,15 +177,28 @@ GEM logging (2.2.2) little-plugger (~> 1.1) multi_json (~> 1.10) + loofah (2.0.3) + nokogiri (>= 1.5.9) memoist (0.16.0) mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) + mini_portile2 (2.1.0) minitest (5.10.2) multi_json (1.12.1) multipart-post (2.0.0) + nokogiri (1.7.2) + mini_portile2 (~> 2.1.0) os (0.9.6) public_suffix (2.0.5) + rack (2.0.3) + rack-test (0.6.3) + rack (>= 1.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.0.3) + loofah (~> 2.0) rake (12.0.0) representable (3.0.4) declarative (< 0.1.0) diff --git a/activefile.gemspec b/activefile.gemspec index e05421102df2a..cc338087808f3 100644 --- a/activefile.gemspec +++ b/activefile.gemspec @@ -11,6 +11,7 @@ Gem::Specification.new do |s| s.add_dependency "activesupport", ">= 5.1" s.add_dependency "activerecord", ">= 5.1" + s.add_dependency "actionpack", ">= 5.1" s.add_dependency "activejob", ">= 5.1" s.add_development_dependency "bundler", "~> 1.15" diff --git a/lib/active_file/disk_controller.rb b/lib/active_file/disk_controller.rb index 5140c91f0a992..d778cf066f664 100644 --- a/lib/active_file/disk_controller.rb +++ b/lib/active_file/disk_controller.rb @@ -1,8 +1,17 @@ +require "action_controller" +require "active_file/blob" +require "active_file/verified_key_with_expiration" + +require "active_support/core_ext/object/inclusion" + class ActiveFile::DiskController < ActionController::Base def show if key = decode_verified_key blob = ActiveFile::Blob.find_by!(key: key) - send_data blob.download, filename: blob.filename, type: blob.content_type, disposition: disposition_param + + if stale?(etag: blob.checksum) + send_data blob.download, filename: blob.filename, type: blob.content_type, disposition: disposition_param + end else head :not_found end @@ -10,7 +19,7 @@ def show private def decode_verified_key - ActiveFile::Site::DiskSite::VerifiedKeyWithExpiration.decode(params[:encoded_key]) + ActiveFile::VerifiedKeyWithExpiration.decode(params[:encoded_key]) end def disposition_param diff --git a/lib/active_file/site/disk_site.rb b/lib/active_file/site/disk_site.rb index ec60175bbfa83..7916a642c0391 100644 --- a/lib/active_file/site/disk_site.rb +++ b/lib/active_file/site/disk_site.rb @@ -40,7 +40,7 @@ def exist?(key) def url(key, expires_in:, disposition:, filename:) verified_key_with_expiration = ActiveFile::VerifiedKeyWithExpiration.encode(key, expires_in: expires_in) - if defined?(Rails) + if defined?(Rails) && defined?(Rails.application) Rails.application.routes.url_helpers.rails_disk_blob_path(verified_key_with_expiration, disposition: disposition) else "/rails/blobs/#{verified_key_with_expiration}?disposition=#{disposition}" diff --git a/test/disk_controller_test.rb b/test/disk_controller_test.rb new file mode 100644 index 0000000000000..ee172b23f781b --- /dev/null +++ b/test/disk_controller_test.rb @@ -0,0 +1,34 @@ +require "test_helper" +require "database/setup" + +require "action_controller" +require "action_controller/test_case" + +require "active_file/disk_controller" +require "active_file/verified_key_with_expiration" + +class ActiveFile::DiskControllerTest < ActionController::TestCase + Routes = ActionDispatch::Routing::RouteSet.new.tap do |routes| + routes.draw do + get "/rails/blobs/:encoded_key" => "active_file/disk#show", as: :rails_disk_blob + end + end + + setup do + @blob = create_blob + @routes = Routes + @controller = ActiveFile::DiskController.new + end + + test "showing blob inline" do + get :show, params: { encoded_key: ActiveFile::VerifiedKeyWithExpiration.encode(@blob.key, expires_in: 5.minutes) } + assert_equal "inline; filename=\"#{@blob.filename}\"", @response.headers["Content-Disposition"] + assert_equal "text/plain", @response.headers["Content-Type"] + end + + test "sending blob as attachment" do + get :show, params: { encoded_key: ActiveFile::VerifiedKeyWithExpiration.encode(@blob.key, expires_in: 5.minutes), disposition: :attachment } + assert_equal "attachment; filename=\"#{@blob.filename}\"", @response.headers["Content-Disposition"] + assert_equal "text/plain", @response.headers["Content-Type"] + end +end