Skip to content

Commit

Permalink
Add DownloadStrategy and Cask::Headers for custom :headers support
Browse files Browse the repository at this point in the history
accepts a :user_agent argument and/or multiple :cookies
  headers :user_agent => 'Netscape/1.0', :cookies => { :cookey => "r00t" }

Also adds a standalone :fake_user_agent for a default UserAgent (Chrome)
  fake_user_agent
References #1175, #958
  • Loading branch information
jonahoffline committed Dec 13, 2013
1 parent 2441f71 commit 06be4b0
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 2 deletions.
2 changes: 2 additions & 0 deletions lib/cask.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ class Cask; end
require 'cask/cli'
require 'cask/container'
require 'cask/download'
require 'cask/download_strategy'
require 'cask/dsl'
require 'cask/exceptions'
require 'cask/fetcher'
require 'cask/headers'
require 'cask/installer'
require 'cask/link_checker'
require 'cask/locations'
Expand Down
4 changes: 2 additions & 2 deletions lib/cask/download.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ def perform
resource = Resource.new(cask.title) do |r|
r.url cask.url.to_s
r.version cask.version
end
downloader = CurlDownloadStrategy.new(cask.title, resource)
end
downloader = Cask::DownloadStrategy.new(cask, resource)
downloaded_path = downloader.fetch

_check_sums(downloaded_path, cask.sums) unless cask.sums === 0
Expand Down
25 changes: 25 additions & 0 deletions lib/cask/download_strategy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'cgi'

class Cask::DownloadStrategy < CurlDownloadStrategy
attr_reader :headers, :url

def initialize(cask, resource)
@cask = cask
@headers = cask.headers
@url = resource.url
super(cask.title, resource)
end

def _fetch
curl(*curl_options)
end

private
def default_options
[url, '-C', downloaded_size, '-o', temporary_path]
end

def curl_options
default_options.concat(headers.curl_options)
end
end
12 changes: 12 additions & 0 deletions lib/cask/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def artifacts; self.class.artifacts; end

def caveats; ''; end

def headers; self.class.headers; end

def fake_user_agent; self.class.fake_user_agent; end

module ClassMethods
def homepage(homepage=nil)
@homepage ||= homepage
Expand All @@ -27,6 +31,14 @@ def url(url=nil)
@url ||= Cask::UnderscoreSupportingURI.parse(url)
end

def headers(headers={})
@headers ||= Cask::Headers.new(headers)
end

def fake_user_agent
headers({:user_agent => 'Chrome/32.0.1000.00'})
end

def version(version=nil)
@version ||= version
end
Expand Down
37 changes: 37 additions & 0 deletions lib/cask/headers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require 'cgi'

class Cask::Headers
attr_reader :headers

def initialize(args)
@headers = args
create_methods_from_headers
end

def curl_options(options=[])
headers.map do |option, _|
options.concat(send("#{option}_args")) if (!!send(option))
end
options.flatten
end

private
def create_methods_from_headers
headers.map do |header, option|
(class << self; self; end).class_eval do
define_method(header.to_sym) { option }
end
end
end

def user_agent_args
['-A', user_agent]
end

def cookies_args
all_cookies = cookies.map do |name, value|
"#{CGI.escape(name.to_s)}=#{CGI.escape(value.to_s)}"
end
['-b', all_cookies.join(';')]
end
end
43 changes: 43 additions & 0 deletions test/cask/download_strategy_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
require 'test_helper'
require 'download_strategy'

describe Cask::DownloadStrategy do
class StubbedDownloadStrategy < Cask::DownloadStrategy
def curl(*args)
args
end
end

before do
@resource = Class.new
@resource.stubs(:url).returns('example.com')
@resource.stubs(:version).returns('3.1')
end

it 'provides user_agent options down to curl' do
cask = Cask.load('with-headers')
downloader = StubbedDownloadStrategy.new(cask, @resource)

downloader._fetch.must_include '-A'
downloader._fetch.must_include 'Mozilla/25.0.1'
downloader.must_respond_to :headers
end

it 'provides :cookie options down to curl' do
cask = Cask.load('with-cookies')
downloader = StubbedDownloadStrategy.new(cask, @resource)

downloader._fetch.must_include '-b'
downloader._fetch.must_include 'cookie_key=cookie_value'
downloader.must_respond_to :headers
end

it 'provides :fake_user_agent options down to curl' do
cask = Cask.load('with-fake-user-agent')
downloader = StubbedDownloadStrategy.new(cask, @resource)

downloader._fetch.must_include '-A'
downloader._fetch.must_include 'Chrome/32.0.1000.00'
downloader.must_respond_to :headers
end
end
25 changes: 25 additions & 0 deletions test/cask/dsl_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,29 @@ def caveats; <<-EOS.undent
instance = CaskWithInstallables.new
Array(instance.artifacts[:install]).sort.must_equal %w[Bar.pkg Foo.pkg]
end

it 'allows :user_agent to be specified via headers' do
options = { user_agent: 'Mozilla/25.0.1' }
test_cask = Cask.load('with-headers')

test_cask.headers.headers.must_equal options
test_cask.headers.user_agent.must_equal options[:user_agent]
end

it 'allows :cookies to be specified via headers' do
options = { cookies: { cookie_key: 'cookie_value' } }
test_cask = Cask.load('with-cookies')

test_cask.headers.headers.must_equal options
test_cask.headers.cookies.must_equal options[:cookies]
end

it 'configures a default fake :user_agent via fake_user_agent' do
options = { :user_agent => 'Chrome/32.0.1000.00' }
test_cask = Cask.load('with-fake-user-agent')

test_cask.headers.headers.must_equal options
test_cask.headers.user_agent.must_equal options[:user_agent]
test_cask.fake_user_agent.must_be_instance_of Cask::Headers
end
end
36 changes: 36 additions & 0 deletions test/cask/headers_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'test_helper'

describe Cask::Headers do
describe '#headers' do
it 'returns header options' do
options = { :user_agent => 'Netscape/1.0.1',
:cookies => { :cookey => 'nom_nom' } }
instance = Cask::Headers.new(options)

instance.headers.must_equal options
instance.user_agent.must_equal options[:user_agent]
instance.cookies.must_equal options[:cookies]
instance.cookies[:cookey].must_equal options[:cookies][:cookey]
end
end

describe '#user_agent' do
it 'returns user_agent' do
options = { user_agent: 'Mozilla/25.0.1' }
instance = Cask::Headers.new(options)

instance.headers.must_equal options
instance.user_agent.must_equal options[:user_agent]
end
end

describe '#cookies' do
it 'returns cookies' do
options = { cookies: { cookey: 'nom_nom' } }
instance = Cask::Headers.new(options)

instance.headers.must_equal options
instance.cookies.must_equal options[:cookies]
end
end
end
8 changes: 8 additions & 0 deletions test/support/Casks/with-cookies.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class WithCookies < TestCask
url 'http://example.com/file.dmg'
headers :cookies => { :cookie_key => 'cookie_value' }
homepage 'http://example.com/'
version '3.2'
sha1 '5a35b6d47150b60e0cf6892bfa7a37a9f9f30d76'
link 'Mac.app'
end
8 changes: 8 additions & 0 deletions test/support/Casks/with-fake-user-agent.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class WithFakeUserAgent < TestCask
url 'http://example.com/file.dmg'
fake_user_agent
homepage 'http://example.com/'
version '3.2'
sha1 '5a35b6d47150b60e0cf6892bfa7a37a9f9f30d76'
link 'Mac.app'
end
8 changes: 8 additions & 0 deletions test/support/Casks/with-headers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class WithHeaders < TestCask
url 'http://example.com/file.dmg'
headers :user_agent => 'Mozilla/25.0.1'
homepage 'http://example.com/'
version '3.2'
sha1 '5a35b6d47150b60e0cf6892bfa7a37a9f9f30d76'
link 'Mac.app'
end

0 comments on commit 06be4b0

Please sign in to comment.