Skip to content

Commit

Permalink
Revert "Rack::ETag now supports SHA-1 and SHA-2 in addition to MD5"
Browse files Browse the repository at this point in the history
Let's keep ETag simple. See the following for discussion:

http://github.com/jamesarosen/rack-contrib/commit/5f2aa98
  • Loading branch information
rtomayko committed Feb 9, 2010
1 parent 7390e3f commit e205d29
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 76 deletions.
49 changes: 4 additions & 45 deletions lib/rack/contrib/etag.rb
@@ -1,61 +1,20 @@
require 'digest/md5'

module Rack
# Automatically sets the ETag header on all String bodies
# if none is set.
#
# By default, uses an MD5 hash to generate the ETag.
#
# @param [#call] app the underlying Rack application. Required.
# @param [Symbol] digest the digest to use. Optional. Options are [:md5, :sha1, :sha256, :sha384, :sha512].
class ETag
def initialize(app, digest = :md5)
def initialize(app)
@app = app
load_digest(digest)
@digest_method = self.method("#{digest}_hash")
end

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

if !headers.has_key?('ETag') && body.is_a?(String)
headers['ETag'] = %("#{@digest_method.call(body)}")
headers['ETag'] = %("#{Digest::MD5.hexdigest(body)}")
end

[status, headers, body]
end

private

def load_digest(digest)
case digest
when :md5
require 'digest/md5'
when :sha1
require 'digest/sha1'
when :sha256, :sha384, :sha512
require 'digest/sha2'
else
raise ArgumentError.new("Digest #{digest} is not supported.")
end
end

def md5_hash(body)
Digest::MD5.hexdigest(body)
end

def sha1_hash(body)
Digest::SHA1.hexdigest(body)
end

def sha256_hash(body)
Digest::SHA2.hexdigest(body)
end

def sha384_hash(body)
(Digest::SHA2.new(384) << body).to_s
end

def sha512_hash(body)
(Digest::SHA2.new(512) << body).to_s
end
end
end
36 changes: 5 additions & 31 deletions test/spec_rack_etag.rb
@@ -1,38 +1,12 @@
require 'test/spec'
require 'rack/mock'
require 'rack/contrib/etag'
require 'digest/md5'
require 'digest/sha1'
require 'digest/sha2'

context "Rack::ETag" do

body = 'Hello, World!'

context('if no ETag is set on a String body') do
before(:each) do
@app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, body] }
end
specify 'sets ETag' do
response = Rack::ETag.new(@app).call({})
response[1]['ETag'].should.equal "\"#{Digest::MD5.hexdigest(body)}\""
end
specify 'uses SHA-1 if specified' do
response = Rack::ETag.new(@app, :sha1).call({})
response[1]['ETag'].should.equal "\"#{Digest::SHA1.hexdigest(body)}\""
end
specify 'uses SHA-256 if specified' do
response = Rack::ETag.new(@app, :sha256).call({})
response[1]['ETag'].should.equal "\"#{Digest::SHA2.hexdigest(body)}\""
end
specify 'uses SHA-384 if specified' do
response = Rack::ETag.new(@app, :sha384).call({})
response[1]['ETag'].should.equal "\"#{(Digest::SHA2.new(384) << body).to_s}\""
end
specify 'uses SHA-512 if specified' do
response = Rack::ETag.new(@app, :sha512).call({})
response[1]['ETag'].should.equal "\"#{(Digest::SHA2.new(512) << body).to_s}\""
end
specify "sets ETag if none is set" do
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
response = Rack::ETag.new(app).call({})
response[1]['ETag'].should.equal "\"65a8e27d8879283831b664bd8b7f0ad4\""
end

specify "does not change ETag if it is already set" do
Expand All @@ -41,7 +15,7 @@
response[1]['ETag'].should.equal "\"abc\""
end

specify "does not set ETag if streaming body" do
specify "does not set ETag if steaming body" do
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Hello", "World"]] }
response = Rack::ETag.new(app).call({})
response[1]['ETag'].should.equal nil
Expand Down

0 comments on commit e205d29

Please sign in to comment.