Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rack 3 compatibility #682

Merged
merged 7 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 27 additions & 21 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI

on:
push:
branches: [ master ]
branches: [master]
pull_request:
branches: [ '**' ]
branches: ["**"]

env:
RACK_ENV: development
Expand All @@ -24,32 +24,38 @@ jobs:
fail-fast: false
matrix:
ruby:
- "2.3"
- "2.4"
- "2.5"
- "2.6"
- "2.7"
- "3.0"
- "3.1"
- "3.2"
- "3.3"
- "jruby-9.4"
rack:
- "2"
- "3"

steps:
- uses: actions/checkout@v3

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
rubygems: ${{ matrix.ruby <= '2.5' && '3.3.26' || 'latest' }}

- name: Set up Minio
run: |
mkdir -p "${GITHUB_WORKSPACE}"/minio/data/minio-bucket
wget -nc -O "${GITHUB_WORKSPACE}"/minio/minio https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x "${GITHUB_WORKSPACE}"/minio/minio
${GITHUB_WORKSPACE}/minio/minio server ${GITHUB_WORKSPACE}/minio/data --address localhost:9000 &>${GITHUB_WORKSPACE}/minio/data/server.log &

- name: Run tests
run: bundle exec rake test
- uses: actions/checkout@v3

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
rubygems: ${{ matrix.ruby <= '2.5' && '3.3.26' || 'latest' }}

- name: Set up Minio
run: |
mkdir -p "${GITHUB_WORKSPACE}"/minio/data/minio-bucket
wget -nc -O "${GITHUB_WORKSPACE}"/minio/minio https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x "${GITHUB_WORKSPACE}"/minio/minio
${GITHUB_WORKSPACE}/minio/minio server ${GITHUB_WORKSPACE}/minio/data --address localhost:9000 &>${GITHUB_WORKSPACE}/minio/data/server.log &

- name: Install dependencies
run: bundle exec appraisal install

- name: Run tests
run: bundle exec appraisal rack-${{ matrix.rack }} rake test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ website/build
coverage/
node_modules
.docusaurus
gemfiles/*.lock
7 changes: 7 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
appraise "rack-2" do
gem "rack", "~> 2"
end

appraise "rack-3" do
gem "rack", "~> 3"
end
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ gem "simplecov"

gem "hanna", require: false

gem "activerecord-jdbcsqlite3-adapter", "~> 70.0", platform: :jruby if RUBY_ENGINE == "jruby"
gem "activerecord-jdbcsqlite3-adapter", "~> 51.0", platform: :jruby if RUBY_ENGINE == "jruby"
10 changes: 10 additions & 0 deletions gemfiles/rack_2.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "pry"
gem "simplecov"
gem "hanna", require: false
gem "rack", "~> 2"

gemspec path: "../"
10 changes: 10 additions & 0 deletions gemfiles/rack_3.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "pry"
gem "simplecov"
gem "hanna", require: false
gem "rack", "~> 3"

gemspec path: "../"
45 changes: 36 additions & 9 deletions lib/shrine/plugins/derivation_endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,16 @@ def call(env)
handle_request(request)
end

headers["Content-Length"] ||= body.map(&:bytesize).inject(0, :+).to_s
headers ||= {}

if Rack.release >= "3"
headers["content-length"] ||= body.respond_to?(:bytesize) ? body.bytesize.to_s :
body.map(&:bytesize).inject(0, :+).to_s
else
headers["Content-Length"] ||= body.map(&:bytesize).inject(0, :+).to_s
end

headers = headers.transform_keys(&:downcase) if Rack.release >= "3"

[status, headers, body]
end
Expand Down Expand Up @@ -411,6 +420,8 @@ def handle_request(request)
headers["Cache-Control"] = derivation.option(:cache_control)
end

headers = headers.transform_keys(&:downcase) if Rack.release >= "3"

[status, headers, body]
end

Expand Down Expand Up @@ -444,7 +455,11 @@ def expires_in(request)

# Halts the request with the error message.
def error!(status, message)
throw :halt, [status, { "Content-Type" => "text/plain" }, [message]]
headers = { "Content-Type" => "text/plain" }

headers = headers.transform_keys(&:downcase) if Rack.release >= "3"

throw :halt, [status, headers, [message]]
end

def secret_key
Expand Down Expand Up @@ -485,18 +500,30 @@ def file_response(file, env)

status = response[0]

headers = {
"Content-Type" => type || response[1]["Content-Type"],
"Content-Length" => response[1]["Content-Length"],
"Content-Disposition" => content_disposition(file),
"Content-Range" => response[1]["Content-Range"],
"Accept-Ranges" => "bytes",
}.compact
headers = if Rack.release >= "3"
{
"content-type" => type || response[1]["content-type"],
"content-length" => response[1]["content-length"],
"content-disposition" => content_disposition(file),
"content-range" => response[1]["content-range"],
"accept-ranges" => "bytes",
}.compact
else
{
"Content-Type" => type || response[1]["Content-Type"],
"Content-Length" => response[1]["Content-Length"],
"Content-Disposition" => content_disposition(file),
"Content-Range" => response[1]["Content-Range"],
"Accept-Ranges" => "bytes",
}.compact
end

body = Rack::BodyProxy.new(response[2]) { File.delete(file.path) }

file.close

headers = headers.transform_keys(&:downcase) if Rack.release >= "3"

[status, headers, body]
end

Expand Down
15 changes: 13 additions & 2 deletions lib/shrine/plugins/download_endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,14 @@ def call(env)
handle_request(request)
end

headers["Content-Length"] ||= body.map(&:bytesize).inject(0, :+).to_s
if Rack.release >= "3"
headers["content-length"] ||= body.respond_to?(:bytesize) ? body.bytesize.to_s :
body.map(&:bytesize).inject(0, :+).to_s
else
headers["Content-Length"] ||= body.map(&:bytesize).inject(0, :+).to_s
end

headers = headers.transform_keys(&:downcase) if Rack.release >= "3"

[status, headers, body]
end
Expand Down Expand Up @@ -197,7 +204,11 @@ def bad_request!(message)

# Halts the request with the error message.
def error!(status, message)
throw :halt, [status, { "Content-Type" => "text/plain" }, [message]]
headers = { "Content-Type" => "text/plain" }

headers = headers.transform_keys(&:downcase) if Rack.release >= "3"

throw :halt, [status, headers, [message]]
end
end
end
15 changes: 13 additions & 2 deletions lib/shrine/plugins/presign_endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,14 @@ def call(env)
end
end

headers["Content-Length"] ||= body.map(&:bytesize).inject(0, :+).to_s
if Rack.release >= "3"
headers["content-length"] ||= body.respond_to?(:bytesize) ? body.bytesize.to_s :
body.map(&:bytesize).inject(0, :+).to_s
else
headers["Content-Length"] ||= body.map(&:bytesize).inject(0, :+).to_s
end

headers = headers.transform_keys(&:downcase) if Rack.release >= "3"

[status, headers, body]
end
Expand Down Expand Up @@ -172,7 +179,11 @@ def make_response(object, request)

# Used for early returning an error response.
def error!(status, message)
throw :halt, [status, { "Content-Type" => CONTENT_TYPE_TEXT }, [message]]
headers = { "Content-Type" => CONTENT_TYPE_TEXT }

headers = headers.transform_keys(&:downcase) if Rack.release >= "3"

throw :halt, [status, headers, [message]]
end

# Returns the uploader around the specified storage.
Expand Down
10 changes: 9 additions & 1 deletion lib/shrine/plugins/rack_response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ def call(**options)
headers = rack_headers(**options)
body = rack_body(**options)

[status, headers, body]
if Rack.release >= "3"
[status, headers.transform_keys(&:downcase), body]
else
[status, headers, body]
end
end

private
Expand Down Expand Up @@ -141,6 +145,10 @@ def close
file.close
end

def bytesize
each.inject(0) { |sum, chunk| sum += chunk.length }
end

# Rack::Sendfile is activated when response body responds to #to_path.
def respond_to_missing?(name, include_private = false)
name == :to_path && path
Expand Down
15 changes: 13 additions & 2 deletions lib/shrine/plugins/upload_endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,14 @@ def call(env)
handle_request(request)
end

headers["Content-Length"] ||= body.map(&:bytesize).inject(0, :+).to_s
if Rack.release >= "3"
headers["content-length"] ||= body.respond_to?(:bytesize) ? body.bytesize.to_s :
body.map(&:bytesize).inject(0, :+).to_s
else
headers["Content-Length"] ||= body.map(&:bytesize).inject(0, :+).to_s
end

headers = headers.transform_keys(&:downcase) if Rack.release >= "3"

[status, headers, body]
end
Expand Down Expand Up @@ -210,7 +217,11 @@ def verify_checksum!(file, request)

# Used for early returning an error response.
def error!(status, message)
throw :halt, [status, { "Content-Type" => CONTENT_TYPE_TEXT }, [message]]
headers = { "Content-Type" => CONTENT_TYPE_TEXT }

headers = headers.transform_keys(&:downcase) if Rack.release >= "3"

throw :halt, [status, headers, [message]]
end

# Returns the uploader around the specified storage.
Expand Down
3 changes: 2 additions & 1 deletion shrine.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ direct uploads for fully asynchronous user experience.
gem.add_dependency "content_disposition", "~> 1.0"

# general testing helpers
gem.add_development_dependency "appraisal", "~> 2.5"
gem.add_development_dependency "rake", ">= 11.1"
gem.add_development_dependency "minitest", "~> 5.8"
gem.add_development_dependency "mocha", "~> 1.11"

# for endpoint plugins
gem.add_development_dependency "rack", "~> 2.0"
gem.add_development_dependency "rack", ">= 2", "< 4"
gem.add_development_dependency "http-form_data", "~> 2.2"
gem.add_development_dependency "rack-test_app"

Expand Down
Loading
Loading