diff --git a/Gemfile.lock b/Gemfile.lock index 1cb08af..429dd03 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -68,8 +68,8 @@ GEM pry (>= 0.13.0) shellany (~> 0.0) thor (>= 0.18.1) - guard-bundler (2.2.1) - bundler (>= 1.3.0, < 3) + guard-bundler (3.0.0) + bundler (>= 2.1, < 3) guard (~> 2.2) guard-compat (~> 1.1) guard-compat (1.2.1) @@ -90,7 +90,6 @@ GEM mime-types-data (~> 3.2015) mime-types-data (3.2022.0105) mini_mime (1.1.2) - mini_portile2 (2.8.0) minitest (5.16.0) multi_json (1.15.0) mustermann (1.1.1) @@ -99,8 +98,7 @@ GEM mustermann (>= 1.0.0) nenv (0.3.0) newrelic_rpm (8.8.0) - nokogiri (1.13.6) - mini_portile2 (~> 2.8.0) + nokogiri (1.13.6-x86_64-darwin) racc (~> 1.4) notiffany (0.1.3) nenv (~> 0.1) @@ -153,7 +151,7 @@ GEM parser (>= 3.1.1.0) rubocop-rake (0.6.0) rubocop (~> 1.0) - rubocop-rspec (2.9.0) + rubocop-rspec (2.11.1) rubocop (~> 1.19) ruby-progressbar (1.11.0) ruby2_keywords (0.0.5) @@ -174,7 +172,7 @@ GEM zeitwerk (2.6.0) PLATFORMS - ruby + x86_64-darwin-19 DEPENDENCIES capybara @@ -202,4 +200,4 @@ RUBY VERSION ruby 2.6.5p114 BUNDLED WITH - 1.17.3 + 2.3.15 diff --git a/api/upload_big_file.rb b/api/upload_big_file.rb new file mode 100644 index 0000000..d644b03 --- /dev/null +++ b/api/upload_big_file.rb @@ -0,0 +1,30 @@ +module Acme + class UploadBigFile < Grape::API + content_type :png, 'image/png' + + desc 'Upload and download a big file of any format using IO.' + post 'big_download' do + filename = params[:file][:filename] + # content_type MIME::Types.type_for(filename)[0].to_s + content_type 'image/png' + env['api.format'] = :png + header 'Content-Disposition', "attachment; filename*=UTF-8''#{URI.escape(filename)}" + + temp_file = params[:file][:tempfile] + stream FileStreamer.new temp_file.path + nil + end + end + + class FileStreamer + def initialize(file_path) + @file_path = file_path + end + + def each(&blk) + File.open(@file_path, 'r') do |file| + file.each(10, &blk) + end + end + end +end diff --git a/app/api.rb b/app/api.rb index 3378cd2..005f281 100644 --- a/app/api.rb +++ b/app/api.rb @@ -12,6 +12,7 @@ class API < Grape::API mount ::Acme::GetJson mount ::Acme::ContentType mount ::Acme::UploadFile + mount ::Acme::UploadBigFile mount ::Acme::Entities::API mount ::Acme::Headers add_swagger_documentation api_version: 'v1' diff --git a/spec/api/upload_big_file_spec.rb b/spec/api/upload_big_file_spec.rb new file mode 100644 index 0000000..6064f18 --- /dev/null +++ b/spec/api/upload_big_file_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe Acme::API do + include Rack::Test::Methods + + def app + Acme::API + end + + it 'uploads and downloads a PNG file' do + image_filename = 'spec/fixtures/grape_logo.png' + post '/api/big_download.png', file: Rack::Test::UploadedFile.new(image_filename, 'image/png', true) + expect(last_response.status).to eq(201) + expect(last_response.headers['Content-Type']).to eq('image/png') + expect(last_response.headers['Content-Disposition']).to eq("attachment; filename*=UTF-8''grape_logo.png") + data = File.read(image_filename, encoding: 'UTF-8') + expect(last_response.body.encoding).to eq data.encoding + expect(last_response.body).to eq data + end +end