From 5716649cd3eb967566d84f591ce06968ba9eba2c Mon Sep 17 00:00:00 2001 From: Dan Corneanu Date: Sun, 31 May 2015 13:49:02 +1200 Subject: [PATCH 1/3] Handling large files. Add new example for uploading.downloading big files. Add a failing test to demonstrate handling files through a IO like, streamin interface. --- api/upload_big_file.rb | 30 ++++++++++++++++++++++++++++++ app/api.rb | 1 + spec/api/upload_big_file_spec.rb | 20 ++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 api/upload_big_file.rb create mode 100644 spec/api/upload_big_file_spec.rb diff --git a/api/upload_big_file.rb b/api/upload_big_file.rb new file mode 100644 index 0000000..f1da4eb --- /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] + body 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..0351807 --- /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") + File.open(image_filename, 'rb') do |io| + expect(last_response.body).to eq io.read + end + end +end From 0a2a5d9bfbc8273b36fdd16a344a43d344c1a837 Mon Sep 17 00:00:00 2001 From: Dan Corneanu Date: Thu, 4 Jun 2015 12:30:49 +1200 Subject: [PATCH 2/3] use local custome version of grape --- Gemfile.lock | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) 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 From af4d7fe7ae76b83c302b914a0a34b9e5dc3ba23f Mon Sep 17 00:00:00 2001 From: "Daniel (dB.) Doubrovkine" Date: Sat, 18 Jun 2022 12:39:57 -0400 Subject: [PATCH 3/3] Fixed streaming of data. --- api/upload_big_file.rb | 2 +- spec/api/upload_big_file_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/upload_big_file.rb b/api/upload_big_file.rb index f1da4eb..d644b03 100644 --- a/api/upload_big_file.rb +++ b/api/upload_big_file.rb @@ -11,7 +11,7 @@ class UploadBigFile < Grape::API header 'Content-Disposition', "attachment; filename*=UTF-8''#{URI.escape(filename)}" temp_file = params[:file][:tempfile] - body FileStreamer.new temp_file.path + stream FileStreamer.new temp_file.path nil end end diff --git a/spec/api/upload_big_file_spec.rb b/spec/api/upload_big_file_spec.rb index 0351807..6064f18 100644 --- a/spec/api/upload_big_file_spec.rb +++ b/spec/api/upload_big_file_spec.rb @@ -13,8 +13,8 @@ def app 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") - File.open(image_filename, 'rb') do |io| - expect(last_response.body).to eq io.read - end + 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