Skip to content

Commit

Permalink
downcased header keys as per HTTP2 standard
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Evans committed Sep 2, 2024
1 parent 0171800 commit bf74075
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 59 deletions.
2 changes: 1 addition & 1 deletion dev/test.ru
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class App
end
[
200,
{'Content-Type' => 'text/html'},
{'content-type' => 'text/html'},
[%(
<style>
form, input {
Expand Down
3 changes: 2 additions & 1 deletion lib/dragonfly/middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ def initialize(app, dragonfly_app_name=nil)

def call(env)
response = Dragonfly.app(@dragonfly_app_name).call(env)
if response[1]['X-Cascade'] == 'pass'
headers = response[1].transform_keys(&:downcase)
if headers['x-cascade'] == 'pass'
@app.call(env)
else
response
Expand Down
18 changes: 9 additions & 9 deletions lib/dragonfly/response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ def to_response
end
rescue Job::Fetch::NotFound => e
Dragonfly.warn(e.message)
[404, {"Content-Type" => "text/plain"}, ["Not found"]]
[404, {"content-type" => "text/plain"}, ["Not found"]]
rescue RuntimeError => e
Dragonfly.warn("caught error - #{e.message}")
[500, {"Content-Type" => "text/plain"}, ["Internal Server Error"]]
[500, {"content-type" => "text/plain"}, ["Internal Server Error"]]
end
log_response(response)
response
Expand Down Expand Up @@ -65,8 +65,8 @@ def etag_matches?

def method_not_allowed_headers
{
'Content-Type' => 'text/plain',
'Allow' => 'GET, HEAD'
'content-type' => 'text/plain',
'allow' => 'GET, HEAD'
}
end

Expand All @@ -78,16 +78,16 @@ def success_headers

def standard_headers
{
"Content-Type" => job.mime_type,
"Content-Length" => job.size.to_s,
"Content-Disposition" => filename_string
"content-type" => job.mime_type,
"content-length" => job.size.to_s,
"content-disposition" => filename_string
}
end

def cache_headers
{
"Cache-Control" => "public, max-age=31536000", # (1 year)
"ETag" => %("#{job.signature}")
"cache-control" => "public, max-age=31536000", # (1 year)
"etag" => %("#{job.signature}")
}
end

Expand Down
2 changes: 1 addition & 1 deletion lib/dragonfly/routed_endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def routing_params(env)
end

def plain_response(status, message)
[status, {"Content-Type" => "text/plain"}, [message]]
[status, {"content-type" => "text/plain"}, [message]]
end
end
end
14 changes: 7 additions & 7 deletions lib/dragonfly/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,18 @@ def call(env)
response.to_response
end
else
[404, {'Content-Type' => 'text/plain', 'X-Cascade' => 'pass'}, ['Not found']]
[404, {'content-type' => 'text/plain', 'x-cascade' => 'pass'}, ['Not found']]
end
rescue Job::NoSHAGiven => e
[400, {"Content-Type" => 'text/plain'}, ["You need to give a SHA parameter"]]
[400, {"content-type" => 'text/plain'}, ["You need to give a SHA parameter"]]
rescue Job::IncorrectSHA => e
[400, {"Content-Type" => 'text/plain'}, ["The SHA parameter you gave is incorrect"]]
[400, {"content-type" => 'text/plain'}, ["The SHA parameter you gave is incorrect"]]
rescue JobNotAllowed => e
Dragonfly.warn(e.message)
[403, {"Content-Type" => 'text/plain'}, ["Forbidden"]]
[403, {"content-type" => 'text/plain'}, ["Forbidden"]]
rescue Serializer::BadString, Serializer::MaliciousString, Job::InvalidArray => e
Dragonfly.warn(e.message)
[404, {'Content-Type' => 'text/plain'}, ['Not found']]
[404, {'content-type' => 'text/plain'}, ['Not found']]
end

def url_for(job, opts={})
Expand Down Expand Up @@ -111,8 +111,8 @@ def dragonfly_response
V
DRAGONFLY
[200, {
'Content-Type' => 'text/plain',
'Content-Size' => body.bytesize.to_s
'content-type' => 'text/plain',
'content-size' => body.bytesize.to_s
},
[body]
]
Expand Down
2 changes: 1 addition & 1 deletion spec/dragonfly/job/fetch_url_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
end

it "should set the mime_type when returned by the request" do
stub_request(:get, %r{http://thing\.com.*}).to_return(:body => '<ok />', :headers => {'Content-Type' => 'text/html'})
stub_request(:get, %r{http://thing\.com.*}).to_return(:body => '<ok />', :headers => {'content-type' => 'text/html'})
expect(job.fetch_url('http://place.com').mime_type).to eq('application/octet-stream')
expect(job.fetch_url('http://thing.com').mime_type).to eq('text/html')
end
Expand Down
52 changes: 26 additions & 26 deletions spec/dragonfly/job_endpoint_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,22 @@ def make_request(job, opts={})
it "should return a correct response to a successful GET request" do
response = make_request(@job)
response.status.should == 200
response['ETag'].should =~ /^"\w+"$/
response['Cache-Control'].should == "public, max-age=31536000"
response['Content-Type'].should == 'text/plain'
response['Content-Length'].should == '6'
response['Content-Disposition'].should == 'filename="gung.txt"'
response['etag'].should =~ /^"\w+"$/
response['cache-control'].should == "public, max-age=31536000"
response['content-type'].should == 'text/plain'
response['content-length'].should == '6'
response['content-disposition'].should == 'filename="gung.txt"'
response.body.should == 'GUNGLE'
end

it "should return the correct headers and no content to a successful HEAD request" do
response = make_request(@job, :method => :head)
response.status.should == 200
response['ETag'].should =~ /^"\w+"$/
response['Cache-Control'].should == "public, max-age=31536000"
response['Content-Type'].should == 'text/plain'
response['Content-Length'].should == '6'
response['Content-Disposition'].should == 'filename="gung.txt"'
response['etag'].should =~ /^"\w+"$/
response['cache-control'].should == "public, max-age=31536000"
response['content-type'].should == 'text/plain'
response['content-length'].should == '6'
response['content-disposition'].should == 'filename="gung.txt"'
response.body.should == ''
end

Expand All @@ -74,8 +74,8 @@ def make_request(job, opts={})
it "should return a 405 error for a #{method} request" do
response = make_request(@job, :method => method)
response.status.should == 405
response['Allow'].should == "GET, HEAD"
response['Content-Type'].should == 'text/plain'
response['allow'].should == "GET, HEAD"
response['content-type'].should == 'text/plain'
response.body.should == "method not allowed"
end

Expand All @@ -102,12 +102,12 @@ def make_request(job, opts={})

it "doesn't encode utf8 characters" do
response = make_request(@job)
response['Content-Disposition'].should == 'filename="güng.txt"'
response['content-disposition'].should == 'filename="güng.txt"'
end

it "does encode them if the request is from IE" do
response = make_request(@job, 'HTTP_USER_AGENT' => "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; el-GR)")
response['Content-Disposition'].should == 'filename="g%C3%BCng.txt"'
response['content-disposition'].should == 'filename="g%C3%BCng.txt"'
end
end

Expand All @@ -121,7 +121,7 @@ def make_request(job, opts={})
describe "ETag" do
it "should return an ETag" do
response = make_request(@job)
response.headers['ETag'].should =~ /^"\w+"$/
response.headers['etag'].should =~ /^"\w+"$/
end

[
Expand All @@ -134,8 +134,8 @@ def make_request(job, opts={})
@job.should_receive(:signature).at_least(:once).and_return('dingle')
response = make_request(@job, 'HTTP_IF_NONE_MATCH' => header)
response.status.should == 304
response['ETag'].should == '"dingle"'
response['Cache-Control'].should == "public, max-age=31536000"
response['etag'].should == '"dingle"'
response['cache-control'].should == "public, max-age=31536000"
response.body.should be_empty
end
end
Expand All @@ -151,25 +151,25 @@ def make_request(job, opts={})
@app.configure{ response_header 'This-is', 'brill' }
end
it "should allow specifying custom headers" do
make_request(@job).headers['This-is'].should == 'brill'
make_request(@job).headers['this-is'].should == 'brill'
end
it "should not interfere with other headers" do
make_request(@job).headers['Content-Length'].should == '6'
make_request(@job).headers['content-length'].should == '6'
end
it "should allow overridding other headers" do
@app.response_headers['Cache-Control'] = 'try me'
make_request(@job).headers['Cache-Control'].should == 'try me'
@app.response_headers['cache-control'] = 'try me'
make_request(@job).headers['cache-control'].should == 'try me'
end
it "should allow giving a proc" do
@app.response_headers['Cache-Control'] = proc{|job, request, headers|
[job.basename.reverse.upcase, request['a'], headers['Cache-Control'].chars.first].join(',')
@app.response_headers['cache-control'] = proc{|job, request, headers|
[job.basename.reverse.upcase, request.params['a'], headers['cache-control'].chars.first].join(',')
}
response = make_request(@job, 'QUERY_STRING' => 'a=egg')
response['Cache-Control'].should == 'GNUG,egg,p'
response['cache-control'].should == 'GNUG,egg,p'
end
it "should allow removing by setting to nil" do
@app.response_headers['Cache-Control'] = nil
make_request(@job).headers.should_not have_key('Cache-Control')
@app.response_headers['cache-control'] = nil
make_request(@job).headers.should_not have_key('cache-control')
end
end

Expand Down
21 changes: 15 additions & 6 deletions spec/dragonfly/middleware_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
require 'rack'

def dummy_rack_app
lambda{|env| [200, {"Content-Type" => "text/html"}, ["dummy_rack_app body"]] }
lambda{|env| [200, {"content-type" => "text/html"}, ["dummy_rack_app body"]] }
end

describe Dragonfly::Middleware do
Expand All @@ -19,9 +19,18 @@ def make_request(app, url)
end
end

it "should pass through if the app returns X-Cascade: pass" do
it "should pass through if the app returns x-cascade: pass" do
Dragonfly.app.should_receive(:call).and_return(
[404, {"Content-Type" => 'text/plain', 'X-Cascade' => 'pass'}, ['Not found']]
[404, {"content-type" => 'text/plain', 'x-cascade' => 'pass'}, ['Not found']]
)
response = make_request(@stack, '/media/hello.png?howare=you')
response.body.should == 'dummy_rack_app body'
response.status.should == 200
end

it "should still pass through using deprecated uppercase X-Cascade: pass" do
Dragonfly.app.should_receive(:call).and_return(
[404, {"content-type" => 'text/plain', 'X-Cascade' => 'pass'}, ['Not found']]
)
response = make_request(@stack, '/media/hello.png?howare=you')
response.body.should == 'dummy_rack_app body'
Expand All @@ -30,15 +39,15 @@ def make_request(app, url)

it "should return a 404 if the app returns a 404" do
Dragonfly.app.should_receive(:call).and_return(
[404, {"Content-Type" => 'text/plain'}, ['Not found']]
[404, {"content-type" => 'text/plain'}, ['Not found']]
)
response = make_request(@stack, '/media/hello.png?howare=you')
response.status.should == 404
end

it "should return as per the dragonfly app if the app returns a 200" do
Dragonfly.app.should_receive(:call).and_return(
[200, {"Content-Type" => 'text/plain'}, ['ABCD']]
[200, {"content-type" => 'text/plain'}, ['ABCD']]
)
response = make_request(@stack, '/media/hello.png?howare=you')
response.status.should == 200
Expand All @@ -57,7 +66,7 @@ def make_request(app, url)
it "should use the specified dragonfly app" do
Dragonfly.app.should_not_receive(:call)
Dragonfly.app(:images).should_receive(:call).and_return([
200, {"Content-Type" => 'text/plain'}, ['booboo']
200, {"content-type" => 'text/plain'}, ['booboo']
])
response = make_request(@stack, '/media/hello.png?howare=you')
response.body.should == 'booboo'
Expand Down
8 changes: 4 additions & 4 deletions spec/dragonfly/server_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
response.status.should == 404
response.body.should == 'Not found'
response.content_type.should == 'text/plain'
response.headers['X-Cascade'].should == 'pass'
response.headers['x-cascade'].should == 'pass'
end
end

Expand All @@ -90,15 +90,15 @@
response.status.should == 404
response.body.should == 'Not found'
response.content_type.should == 'text/plain'
response.headers['X-Cascade'].should be_nil
response.headers['x-cascade'].should be_nil
end

it "should return a 404 when the url isn't known at all" do
response = request(@server, '/jfasd/dsfa')
response.status.should == 404
response.body.should == 'Not found'
response.content_type.should == 'text/plain'
response.headers['X-Cascade'].should == 'pass'
response.headers['x-cascade'].should == 'pass'
end

it "should return a 404 when the url is a well-encoded but bad array" do
Expand All @@ -107,7 +107,7 @@
response.status.should == 404
response.body.should == 'Not found'
response.content_type.should == 'text/plain'
response.headers['X-Cascade'].should be_nil
response.headers['x-cascade'].should be_nil
end

it "should return a 403 Forbidden when someone uses fetch_url" do
Expand Down
4 changes: 2 additions & 2 deletions spec/functional/to_response_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
response.should be_a(Array)
response.length.should == 3
response[0].should == 200
response[1]['Content-Type'].should == 'application/octet-stream'
response[1]['content-type'].should == 'application/octet-stream'
response[2].data.should == 'bunheads'
end

Expand All @@ -24,7 +24,7 @@
response.should be_a(Array)
response.length.should == 3
response[0].should == 405
response[1]['Content-Type'].should == 'text/plain'
response[1]['content-type'].should == 'text/plain'
response[2].should == ["method not allowed"]
end

Expand Down
2 changes: 1 addition & 1 deletion spec/functional/urls_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def job_should_match(array)
Dragonfly::Response.should_receive(:new).with(
satisfy{|job| job.to_a == array },
instance_of(Hash)
).and_return(double('response', :to_response => [200, {'Content-Type' => 'text/plain'}, ["OK"]]))
).and_return(double('response', :to_response => [200, {'content-type' => 'text/plain'}, ["OK"]]))
end

let (:app) {
Expand Down

0 comments on commit bf74075

Please sign in to comment.