Skip to content

Commit

Permalink
Merge 63c6910 into 3d85058
Browse files Browse the repository at this point in the history
  • Loading branch information
ericproulx committed Jan 5, 2024
2 parents 3d85058 + 63c6910 commit b56eb15
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 29 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/edge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ jobs:
fail-fast: false
matrix:
ruby: ['2.7', '3.0', '3.1', '3.2', '3.3', ruby-head, truffleruby-head, jruby-head]
gemfile: [rails_edge, rack_edge, rack_3_0]
gemfile: [rails_edge, rack_edge]
exclude:
- ruby: '2.7'
gemfile: rails_edge
- ruby: '3.0'
gemfile: rails_edge
runs-on: ubuntu-latest
continue-on-error: true
env:
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* [#2373](https://github.com/ruby-grape/grape/pull/2373): Fix markdown files for following 1-line format - [@jcagarcia](https://github.com/jcagarcia).
* [#2382](https://github.com/ruby-grape/grape/pull/2382): Fix values validator for params wrapped in `with` block - [@numbata](https://github.com/numbata).
* [#2387](https://github.com/ruby-grape/grape/pull/2387): Fix rubygems version within workflows - [@ericproulx](https://github.com/ericproulx).
* [#2405](https://github.com/ruby-grape/grape/pull/2405): Fix edge workflows - [@ericproulx](https://github.com/ericproulx).
* Your contribution here.

### 2.0.0 (2023/11/11)
Expand Down
38 changes: 19 additions & 19 deletions spec/grape/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ class DummyFormatClass
'example'
end
put '/example'
expect(last_response.headers[Rack::CONTENT_TYPE]).to eql 'text/plain'
expect(last_response.content_type).to eql 'text/plain'
end

describe 'adds an OPTIONS route that' do
Expand Down Expand Up @@ -1195,7 +1195,7 @@ class DummyFormatClass

it 'sets content type for txt format' do
get '/foo'
expect(last_response.headers[Rack::CONTENT_TYPE]).to eq('text/plain')
expect(last_response.content_type).to eq('text/plain')
end

it 'does not set Cache-Control' do
Expand All @@ -1205,22 +1205,22 @@ class DummyFormatClass

it 'sets content type for xml' do
get '/foo.xml'
expect(last_response.headers[Rack::CONTENT_TYPE]).to eq('application/xml')
expect(last_response.content_type).to eq('application/xml')
end

it 'sets content type for json' do
get '/foo.json'
expect(last_response.headers[Rack::CONTENT_TYPE]).to eq('application/json')
expect(last_response.content_type).to eq('application/json')
end

it 'sets content type for serializable hash format' do
get '/foo.serializable_hash'
expect(last_response.headers[Rack::CONTENT_TYPE]).to eq('application/json')
expect(last_response.content_type).to eq('application/json')
end

it 'sets content type for binary format' do
get '/foo.binary'
expect(last_response.headers[Rack::CONTENT_TYPE]).to eq('application/octet-stream')
expect(last_response.content_type).to eq('application/octet-stream')
end

it 'returns raw data when content type binary' do
Expand All @@ -1229,7 +1229,7 @@ class DummyFormatClass
subject.format :binary
subject.get('/binary_file') { File.binread(image_filename) }
get '/binary_file'
expect(last_response.headers[Rack::CONTENT_TYPE]).to eq('application/octet-stream')
expect(last_response.content_type).to eq('application/octet-stream')
expect(last_response.body).to eq(file)
end

Expand All @@ -1241,8 +1241,8 @@ class DummyFormatClass

subject.get('/file') { stream test_file }
get '/file'
expect(last_response.headers[Rack::CONTENT_LENGTH]).to eq('25')
expect(last_response.headers[Rack::CONTENT_TYPE]).to eq('text/plain')
expect(last_response.content_length).to eq(25)
expect(last_response.content_type).to eq('text/plain')
expect(last_response.body).to eq(file_content)
end

Expand All @@ -1252,12 +1252,12 @@ class DummyFormatClass
blk.yield ' file content'
end

subject.use Rack::Chunked
subject.use defined?(Rack::Chunked) ? Rack::Chunked : ChunkedResponse
subject.get('/stream') { stream test_stream }
get '/stream', {}, 'HTTP_VERSION' => 'HTTP/1.1', 'SERVER_PROTOCOL' => 'HTTP/1.1'

expect(last_response.headers[Rack::CONTENT_TYPE]).to eq('text/plain')
expect(last_response.headers[Rack::CONTENT_LENGTH]).to be_nil
expect(last_response.content_type).to eq('text/plain')
expect(last_response.content_length).to be_nil
expect(last_response.headers[Rack::CACHE_CONTROL]).to eq('no-cache')
expect(last_response.headers[Grape::Http::Headers::TRANSFER_ENCODING]).to eq('chunked')

Expand All @@ -1267,23 +1267,23 @@ class DummyFormatClass
it 'sets content type for error' do
subject.get('/error') { error!('error in plain text', 500) }
get '/error'
expect(last_response.headers[Rack::CONTENT_TYPE]).to eql 'text/plain'
expect(last_response.content_type).to eql 'text/plain'
end

it 'sets content type for json error' do
subject.format :json
subject.get('/error') { error!('error in json', 500) }
get '/error.json'
expect(last_response.status).to be 500
expect(last_response.headers[Rack::CONTENT_TYPE]).to eql 'application/json'
expect(last_response.content_type).to eql 'application/json'
end

it 'sets content type for xml error' do
subject.format :xml
subject.get('/error') { error!('error in xml', 500) }
get '/error'
expect(last_response.status).to be 500
expect(last_response.headers[Rack::CONTENT_TYPE]).to eql 'application/xml'
expect(last_response.content_type).to eql 'application/xml'
end

it 'includes extension in format' do
Expand Down Expand Up @@ -1313,12 +1313,12 @@ class DummyFormatClass

it 'sets content type' do
get '/custom.custom'
expect(last_response.headers[Rack::CONTENT_TYPE]).to eql 'application/custom'
expect(last_response.content_type).to eql 'application/custom'
end

it 'sets content type for error' do
get '/error.custom'
expect(last_response.headers[Rack::CONTENT_TYPE]).to eql 'application/custom'
expect(last_response.content_type).to eql 'application/custom'
end
end

Expand All @@ -1338,7 +1338,7 @@ class DummyFormatClass
image_filename = 'grape.png'
post url, file: Rack::Test::UploadedFile.new(image_filename, 'image/png', true)
expect(last_response.status).to eq(201)
expect(last_response.headers[Rack::CONTENT_TYPE]).to eq('image/png')
expect(last_response.content_type).to eq('image/png')
expect(last_response.headers['Content-Disposition']).to eq("attachment; filename*=UTF-8''grape.png")
File.open(image_filename, 'rb') do |io|
expect(last_response.body).to eq io.read
Expand All @@ -1350,7 +1350,7 @@ class DummyFormatClass
filename = __FILE__
post '/attachment.rb', file: Rack::Test::UploadedFile.new(filename, 'application/x-ruby', true)
expect(last_response.status).to eq(201)
expect(last_response.headers[Rack::CONTENT_TYPE]).to eq('application/x-ruby')
expect(last_response.content_type).to eq('application/x-ruby')
expect(last_response.headers['Content-Disposition']).to eq("attachment; filename*=UTF-8''api_spec.rb")
File.open(filename, 'rb') do |io|
expect(last_response.body).to eq io.read
Expand Down
8 changes: 4 additions & 4 deletions spec/grape/endpoint_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ def app
end

it 'responses with given content type in headers' do
expect(last_response.headers[Rack::CONTENT_TYPE]).to eq 'application/json; charset=utf-8'
expect(last_response.content_type).to eq 'application/json; charset=utf-8'
end
end

Expand Down Expand Up @@ -650,7 +650,7 @@ def app
end
get '/hey'
expect(last_response.status).to eq 302
expect(last_response.headers['Location']).to eq '/ha'
expect(last_response.location).to eq '/ha'
expect(last_response.body).to eq 'This resource has been moved temporarily to /ha.'
end

Expand All @@ -660,7 +660,7 @@ def app
end
post '/hey', {}, 'HTTP_VERSION' => 'HTTP/1.1'
expect(last_response.status).to eq 303
expect(last_response.headers['Location']).to eq '/ha'
expect(last_response.location).to eq '/ha'
expect(last_response.body).to eq 'An alternate resource is located at /ha.'
end

Expand All @@ -670,7 +670,7 @@ def app
end
get '/hey'
expect(last_response.status).to eq 301
expect(last_response.headers['Location']).to eq '/ha'
expect(last_response.location).to eq '/ha'
expect(last_response.body).to eq 'This resource has been moved permanently to /ha.'
end

Expand Down
6 changes: 3 additions & 3 deletions spec/grape/entity_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def initialize(args)
end
get '/example'
expect(last_response.status).to eq(200)
expect(last_response.headers['Content-type']).to eq('application/xml')
expect(last_response.content_type).to eq('application/xml')
expect(last_response.body).to eq <<~XML
<?xml version="1.0" encoding="UTF-8"?>
<hash>
Expand Down Expand Up @@ -266,7 +266,7 @@ def initialize(args)
end
get '/example'
expect(last_response.status).to eq(200)
expect(last_response.headers['Content-type']).to eq('application/json')
expect(last_response.content_type).to eq('application/json')
expect(last_response.body).to eq('{"example":{"name":"johnnyiller"}}')
end

Expand Down Expand Up @@ -298,7 +298,7 @@ def initialize(args)

get '/example?callback=abcDef'
expect(last_response.status).to eq(200)
expect(last_response.headers['Content-type']).to eq('application/javascript')
expect(last_response.content_type).to eq('application/javascript')
expect(last_response.body).to include 'abcDef({"example":{"name":"johnnyiller"}})'
end

Expand Down
4 changes: 2 additions & 2 deletions spec/grape/middleware/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
end

it 'header' do
expect(subject.response.header).to have_key(:abc)
expect(subject.response.headers).to have_key(:abc)
end

it 'returns the memoized Rack::Response instance' do
Expand All @@ -115,7 +115,7 @@
end

it 'header' do
expect(subject.response.header).to have_key(:abc)
expect(subject.response.headers).to have_key(:abc)
end

it 'returns the memoized Rack::Response instance' do
Expand Down
2 changes: 2 additions & 0 deletions spec/support/basic_auth_encode_helpers.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require 'base64'

module Spec
module Support
module Helpers
Expand Down
74 changes: 74 additions & 0 deletions spec/support/chunked_response.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# frozen_string_literal: true

# this is a copy of Rack::Chunked which has been removed in rack > 3.0

class ChunkedResponse
class Body
TERM = "\r\n"
TAIL = "0#{TERM}"

# Store the response body to be chunked.
def initialize(body)
@body = body
end

# For each element yielded by the response body, yield
# the element in chunked encoding.
def each(&block)
term = TERM
@body.each do |chunk|
size = chunk.bytesize
next if size == 0

yield [size.to_s(16), term, chunk.b, term].join
end
yield TAIL
yield_trailers(&block)
yield term
end

# Close the response body if the response body supports it.
def close
@body.close if @body.respond_to?(:close)
end

private

# Do nothing as this class does not support trailer headers.
def yield_trailers
end
end

class TrailerBody < Body
private

# Yield strings for each trailer header.
def yield_trailers
@body.trailers.each_pair do |k, v|
yield "#{k}: #{v}\r\n"
end
end
end

def initialize(app)
@app = app
end

def call(env)
status, headers, body = response = @app.call(env)

if !Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) &&
!headers[Rack::CONTENT_LENGTH] &&
!headers[Rack::TRANSFER_ENCODING]

headers[Rack::TRANSFER_ENCODING] = 'chunked'
if headers['trailer']
response[2] = TrailerBody.new(body)
else
response[2] = Body.new(body)
end
end

response
end
end

0 comments on commit b56eb15

Please sign in to comment.