dragonfly 1.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of dragonfly might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -4
- data/History.md +17 -0
- data/README.md +6 -2
- data/Rakefile +1 -0
- data/dragonfly.gemspec +17 -1
- data/lib/dragonfly/app.rb +10 -1
- data/lib/dragonfly/file_data_store.rb +1 -1
- data/lib/dragonfly/image_magick/plugin.rb +3 -2
- data/lib/dragonfly/job.rb +5 -178
- data/lib/dragonfly/job/fetch.rb +19 -0
- data/lib/dragonfly/job/fetch_file.rb +27 -0
- data/lib/dragonfly/job/fetch_url.rb +75 -0
- data/lib/dragonfly/job/generate.rb +27 -0
- data/lib/dragonfly/job/process.rb +27 -0
- data/lib/dragonfly/job/step.rb +44 -0
- data/lib/dragonfly/model/attachment.rb +0 -2
- data/lib/dragonfly/model/class_methods.rb +5 -0
- data/lib/dragonfly/rails/images.rb +1 -0
- data/lib/dragonfly/response.rb +11 -2
- data/lib/dragonfly/routed_endpoint.rb +15 -5
- data/lib/dragonfly/serializer.rb +2 -2
- data/lib/dragonfly/shell.rb +28 -5
- data/lib/dragonfly/version.rb +1 -1
- data/spec/dragonfly/file_data_store_spec.rb +29 -32
- data/spec/dragonfly/job/fetch_file_spec.rb +26 -0
- data/spec/dragonfly/job/fetch_spec.rb +26 -0
- data/spec/dragonfly/job/fetch_url_spec.rb +123 -0
- data/spec/dragonfly/job/generate_spec.rb +28 -0
- data/spec/dragonfly/job/process_spec.rb +28 -0
- data/spec/dragonfly/job_endpoint_spec.rb +17 -0
- data/spec/dragonfly/job_spec.rb +0 -187
- data/spec/dragonfly/model/model_spec.rb +27 -12
- data/spec/dragonfly/routed_endpoint_spec.rb +69 -28
- data/spec/dragonfly/shell_spec.rb +2 -2
- data/spec/support/simple_matchers.rb +1 -1
- metadata +43 -16
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'dragonfly/job/step'
|
2
|
+
|
3
|
+
module Dragonfly
|
4
|
+
class Job
|
5
|
+
class Generate < Step
|
6
|
+
def init
|
7
|
+
generator.update_url(job.url_attributes, *arguments) if generator.respond_to?(:update_url)
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
args.first
|
12
|
+
end
|
13
|
+
|
14
|
+
def generator
|
15
|
+
@generator ||= app.get_generator(name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def arguments
|
19
|
+
args[1..-1]
|
20
|
+
end
|
21
|
+
|
22
|
+
def apply
|
23
|
+
generator.call(job.content, *arguments)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'dragonfly/job/step'
|
2
|
+
|
3
|
+
module Dragonfly
|
4
|
+
class Job
|
5
|
+
class Process < Step
|
6
|
+
def init
|
7
|
+
processor.update_url(job.url_attributes, *arguments) if processor.respond_to?(:update_url)
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
args.first.to_sym
|
12
|
+
end
|
13
|
+
|
14
|
+
def arguments
|
15
|
+
args[1..-1]
|
16
|
+
end
|
17
|
+
|
18
|
+
def processor
|
19
|
+
@processor ||= app.get_processor(name)
|
20
|
+
end
|
21
|
+
|
22
|
+
def apply
|
23
|
+
processor.call(job.content, *arguments)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Dragonfly
|
2
|
+
class Job
|
3
|
+
class Step
|
4
|
+
|
5
|
+
class << self
|
6
|
+
# Dragonfly::Job::Fetch -> 'Fetch'
|
7
|
+
def basename
|
8
|
+
@basename ||= name.split('::').last
|
9
|
+
end
|
10
|
+
# Dragonfly::Job::Fetch -> :fetch
|
11
|
+
def step_name
|
12
|
+
@step_name ||= basename.gsub(/[A-Z]/){ "_#{$&.downcase}" }.sub('_','').to_sym
|
13
|
+
end
|
14
|
+
# Dragonfly::Job::Fetch -> 'f'
|
15
|
+
def abbreviation
|
16
|
+
@abbreviation ||= basename.scan(/[A-Z]/).join.downcase
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(job, *args)
|
21
|
+
@job, @args = job, args
|
22
|
+
init
|
23
|
+
end
|
24
|
+
|
25
|
+
def init # To be overridden
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :job, :args
|
29
|
+
|
30
|
+
def app
|
31
|
+
job.app
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_a
|
35
|
+
[self.class.abbreviation, *args]
|
36
|
+
end
|
37
|
+
|
38
|
+
def inspect
|
39
|
+
"#{self.class.step_name}(#{args.map{|a| a.inspect }.join(', ')})"
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -53,6 +53,11 @@ module Dragonfly
|
|
53
53
|
dragonfly_attachments[attribute].stored?
|
54
54
|
end
|
55
55
|
|
56
|
+
# Define the xxx_changed? method
|
57
|
+
define_method "#{attribute}_changed?" do
|
58
|
+
dragonfly_attachments[attribute].changed?
|
59
|
+
end
|
60
|
+
|
56
61
|
# Define the URL setter
|
57
62
|
define_method "#{attribute}_url=" do |url|
|
58
63
|
unless Utils.blank?(url)
|
@@ -0,0 +1 @@
|
|
1
|
+
raise LoadError, "\n*****\ndragonfly/rails/images no longer exists! Please use the rails generator instead\n\n\trails generate dragonfly\n\nsee the documentation at http://markevans.github.io/dragonfly/rails for more details\n*****\n"
|
data/lib/dragonfly/response.rb
CHANGED
@@ -80,7 +80,7 @@ module Dragonfly
|
|
80
80
|
{
|
81
81
|
"Content-Type" => job.mime_type,
|
82
82
|
"Content-Length" => job.size.to_s,
|
83
|
-
"Content-Disposition" =>
|
83
|
+
"Content-Disposition" => filename_string
|
84
84
|
}
|
85
85
|
end
|
86
86
|
|
@@ -97,6 +97,15 @@ module Dragonfly
|
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
|
+
def filename_string
|
101
|
+
return unless job.name
|
102
|
+
filename = request_from_msie? ? URI.encode(job.name) : job.name
|
103
|
+
%(filename="#{filename}")
|
104
|
+
end
|
105
|
+
|
106
|
+
def request_from_msie?
|
107
|
+
env["HTTP_USER_AGENT"] =~ /MSIE/
|
108
|
+
end
|
109
|
+
|
100
110
|
end
|
101
111
|
end
|
102
|
-
|
@@ -14,12 +14,20 @@ module Dragonfly
|
|
14
14
|
|
15
15
|
def call(env)
|
16
16
|
params = Utils.symbolize_keys Rack::Request.new(env).params
|
17
|
-
|
18
|
-
|
17
|
+
value = @block.call(params.merge(routing_params(env)), @app)
|
18
|
+
case value
|
19
|
+
when nil then plain_response(404, "Not Found")
|
20
|
+
when Job, Model::Attachment
|
21
|
+
job = value.is_a?(Model::Attachment) ? value.job : value
|
22
|
+
Response.new(job, env).to_response
|
23
|
+
else
|
24
|
+
Dragonfly.warn("can't handle return value from routed endpoint: #{value.inspect}")
|
25
|
+
plain_response(500, "Server Error")
|
26
|
+
end
|
19
27
|
rescue Job::NoSHAGiven => e
|
20
|
-
|
28
|
+
plain_response(400, "You need to give a SHA parameter")
|
21
29
|
rescue Job::IncorrectSHA => e
|
22
|
-
|
30
|
+
plain_response(400, "The SHA parameter you gave is incorrect")
|
23
31
|
end
|
24
32
|
|
25
33
|
def inspect
|
@@ -32,10 +40,12 @@ module Dragonfly
|
|
32
40
|
env['rack.routing_args'] ||
|
33
41
|
env['action_dispatch.request.path_parameters'] ||
|
34
42
|
env['router.params'] ||
|
35
|
-
env['usher.params'] ||
|
36
43
|
env['dragonfly.params'] ||
|
37
44
|
raise(NoRoutingParams, "couldn't find any routing parameters in env #{env.inspect}")
|
38
45
|
end
|
39
46
|
|
47
|
+
def plain_response(status, message)
|
48
|
+
[status, {"Content-Type" => "text/plain"}, [message]]
|
49
|
+
end
|
40
50
|
end
|
41
51
|
end
|
data/lib/dragonfly/serializer.rb
CHANGED
@@ -31,7 +31,7 @@ module Dragonfly
|
|
31
31
|
raise MaliciousString, "potentially malicious marshal string #{marshal_string.inspect}" if opts[:check_malicious] && marshal_string[/@[a-z_]/i]
|
32
32
|
Marshal.load(marshal_string)
|
33
33
|
rescue TypeError, ArgumentError => e
|
34
|
-
raise BadString, "couldn't decode
|
34
|
+
raise BadString, "couldn't marshal decode string - got #{e}"
|
35
35
|
end
|
36
36
|
|
37
37
|
def json_encode(object)
|
@@ -42,7 +42,7 @@ module Dragonfly
|
|
42
42
|
raise BadString, "can't decode blank string" if Utils.blank?(string)
|
43
43
|
MultiJson.decode(string)
|
44
44
|
rescue MultiJson::DecodeError => e
|
45
|
-
raise BadString, "couldn't decode
|
45
|
+
raise BadString, "couldn't json decode string - got #{e}"
|
46
46
|
end
|
47
47
|
|
48
48
|
def json_b64_encode(object)
|
data/lib/dragonfly/shell.rb
CHANGED
@@ -11,11 +11,7 @@ module Dragonfly
|
|
11
11
|
def run(command, opts={})
|
12
12
|
command = escape_args(command) unless opts[:escape] == false
|
13
13
|
Dragonfly.debug("shell command: #{command}")
|
14
|
-
|
15
|
-
status = wait_thread.value
|
16
|
-
raise CommandFailed, "Command failed (#{command}) with exit status #{status.exitstatus} and stderr #{stderr.read}" unless status.success?
|
17
|
-
stdout.read
|
18
|
-
end
|
14
|
+
run_command(command)
|
19
15
|
end
|
20
16
|
|
21
17
|
def escape_args(args)
|
@@ -29,5 +25,32 @@ module Dragonfly
|
|
29
25
|
q + string + q
|
30
26
|
end
|
31
27
|
|
28
|
+
private
|
29
|
+
|
30
|
+
# Annoyingly, Open3 seems buggy on jruby/1.8.7:
|
31
|
+
# Some versions don't yield a wait_thread in the block and
|
32
|
+
# you can't run sub-shells (if explicitly turning shell-escaping off)
|
33
|
+
if RUBY_PLATFORM == 'java' || RUBY_VERSION < '1.9'
|
34
|
+
|
35
|
+
# Unfortunately we have no control over stderr this way
|
36
|
+
def run_command(command)
|
37
|
+
result = `#{command}`
|
38
|
+
status = $?
|
39
|
+
raise CommandFailed, "Command failed (#{command}) with exit status #{status.exitstatus}" unless status.success?
|
40
|
+
result
|
41
|
+
end
|
42
|
+
|
43
|
+
else
|
44
|
+
|
45
|
+
def run_command(command)
|
46
|
+
Open3.popen3 command do |stdin, stdout, stderr, wait_thread|
|
47
|
+
status = wait_thread.value
|
48
|
+
raise CommandFailed, "Command failed (#{command}) with exit status #{status.exitstatus} and stderr #{stderr.read}" unless status.success?
|
49
|
+
stdout.read
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
32
55
|
end
|
33
56
|
end
|
data/lib/dragonfly/version.rb
CHANGED
@@ -16,6 +16,13 @@ describe Dragonfly::FileDataStore do
|
|
16
16
|
File.exists?(path).should be_false
|
17
17
|
end
|
18
18
|
|
19
|
+
def assert_contains(dir, filepattern)
|
20
|
+
entries = Dir["#{dir}/*"]
|
21
|
+
unless entries.any?{|f| filepattern === f}
|
22
|
+
raise "expected #{entries} to contain #{filepattern}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
19
26
|
let (:app) { test_app }
|
20
27
|
let (:content) { Dragonfly::Content.new(app, 'goobydoo') }
|
21
28
|
let (:new_content) { Dragonfly::Content.new(app) }
|
@@ -24,10 +31,10 @@ describe Dragonfly::FileDataStore do
|
|
24
31
|
|
25
32
|
before(:each) do
|
26
33
|
@data_store = Dragonfly::FileDataStore.new(:root_path => 'tmp/file_data_store_test')
|
34
|
+
FileUtils.rm_rf("#{@data_store.root_path}")
|
27
35
|
end
|
28
36
|
|
29
37
|
after(:each) do
|
30
|
-
# Clean up created files
|
31
38
|
FileUtils.rm_rf("#{@data_store.root_path}")
|
32
39
|
end
|
33
40
|
|
@@ -38,56 +45,51 @@ describe Dragonfly::FileDataStore do
|
|
38
45
|
before(:each) do
|
39
46
|
# Set 'now' to a date in the past
|
40
47
|
Time.stub(:now).and_return Time.mktime(1984,"may",4,14,28,1)
|
41
|
-
@
|
42
|
-
@file_pattern_prefix = "#{@data_store.root_path}/#{@file_pattern_prefix_without_root}"
|
48
|
+
@dir = "#{@data_store.root_path}/1984/05/04"
|
43
49
|
end
|
44
50
|
|
45
51
|
it "should store the file in a folder based on date, with default filename" do
|
46
52
|
@data_store.write(content)
|
47
|
-
|
53
|
+
assert_contains @dir, /file$/
|
48
54
|
end
|
49
55
|
|
50
56
|
it "should use the content name if it exists" do
|
51
57
|
content.should_receive(:name).at_least(:once).and_return('hello.there')
|
52
58
|
@data_store.write(content)
|
53
|
-
|
59
|
+
assert_contains @dir, /hello\.there$/
|
54
60
|
end
|
55
61
|
|
56
62
|
it "should get rid of funny characters in the content name" do
|
57
63
|
content.should_receive(:name).at_least(:once).and_return('A Picture with many spaces in its name (at 20:00 pm).png')
|
58
64
|
@data_store.write(content)
|
59
|
-
|
65
|
+
assert_contains @dir, /A_Picture_with_many_spaces_in_its_name_at_20_00_pm_\.png$/
|
60
66
|
end
|
61
67
|
|
62
68
|
it "stores meta as YAML" do
|
63
69
|
content.meta = {'wassup' => 'doc'}
|
64
|
-
@data_store.write(content)
|
65
|
-
File.read("#{@
|
70
|
+
uid = @data_store.write(content)
|
71
|
+
File.read("#{@data_store.root_path}/#{uid}.meta.yml").should =~ /---\s+wassup: doc/
|
66
72
|
end
|
67
73
|
|
68
74
|
describe "when the filename already exists" do
|
69
75
|
|
70
76
|
it "should use a different filename" do
|
71
|
-
touch_file("#{@
|
72
|
-
@data_store.should_receive(:disambiguate).with(
|
73
|
-
@data_store.write(content)
|
74
|
-
assert_exists "#{@
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should use a different filename taking into account the name and ext" do
|
78
|
-
content.should_receive(:name).at_least(:once).and_return('hello.png')
|
79
|
-
touch_file("#{@file_pattern_prefix}hello.png")
|
80
|
-
@data_store.should_receive(:disambiguate).with("#{@file_pattern_prefix}hello.png").and_return("#{@file_pattern_prefix}blah.png")
|
81
|
-
@data_store.write(content)
|
77
|
+
touch_file("#{@data_store.root_path}/blah")
|
78
|
+
@data_store.should_receive(:disambiguate).with(/blah/).and_return("#{@data_store.root_path}/blah2")
|
79
|
+
@data_store.write(content, :path => 'blah')
|
80
|
+
assert_exists "#{@data_store.root_path}/blah2"
|
82
81
|
end
|
83
82
|
|
84
83
|
it "should keep trying until it finds a free filename" do
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
84
|
+
path1 = "#{@data_store.root_path}/blah1"
|
85
|
+
path2 = "#{@data_store.root_path}/blah2"
|
86
|
+
path3 = "#{@data_store.root_path}/blah3"
|
87
|
+
touch_file(path1)
|
88
|
+
touch_file(path2)
|
89
|
+
@data_store.should_receive(:disambiguate).with(path1).and_return(path2)
|
90
|
+
@data_store.should_receive(:disambiguate).with(path2).and_return(path3)
|
91
|
+
@data_store.write(content, :path => 'blah1')
|
92
|
+
assert_exists path3
|
91
93
|
end
|
92
94
|
|
93
95
|
describe "specifying the uid" do
|
@@ -107,13 +109,8 @@ describe Dragonfly::FileDataStore do
|
|
107
109
|
|
108
110
|
describe "return value" do
|
109
111
|
|
110
|
-
it "should return the
|
111
|
-
@data_store.write(content).should
|
112
|
-
end
|
113
|
-
|
114
|
-
it "should return the filepath without the root of the stored file when a file name is provided" do
|
115
|
-
content.should_receive(:name).at_least(:once).and_return('hello.you.png')
|
116
|
-
@data_store.write(content).should == "#{@file_pattern_prefix_without_root}hello.you.png"
|
112
|
+
it "should return the relative path" do
|
113
|
+
@data_store.write(content).should =~ /^1984\/05\/04\/\w+$/
|
117
114
|
end
|
118
115
|
|
119
116
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dragonfly::Job::FetchFile do
|
4
|
+
|
5
|
+
let (:app) { test_app }
|
6
|
+
let (:job) { Dragonfly::Job.new(app) }
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
job.fetch_file!(SAMPLES_DIR.join('egg.png'))
|
10
|
+
end
|
11
|
+
|
12
|
+
it { job.steps.should match_steps([Dragonfly::Job::FetchFile]) }
|
13
|
+
|
14
|
+
it "should fetch the specified file when applied" do
|
15
|
+
job.size.should == 62664
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should set the url_attributes" do
|
19
|
+
job.url_attributes.name.should == 'egg.png'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should set the name" do
|
23
|
+
job.name.should == 'egg.png'
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dragonfly::Job::Fetch do
|
4
|
+
|
5
|
+
let (:app) { test_app }
|
6
|
+
let (:job) { Dragonfly::Job.new(app) }
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
job.fetch!('some_uid')
|
10
|
+
end
|
11
|
+
|
12
|
+
it { job.steps.should match_steps([Dragonfly::Job::Fetch]) }
|
13
|
+
|
14
|
+
it "should read from the app's datastore when applied" do
|
15
|
+
app.datastore.should_receive(:read).with('some_uid').and_return ["", {}]
|
16
|
+
job.apply
|
17
|
+
end
|
18
|
+
|
19
|
+
it "raises NotFound if the datastore returns nil" do
|
20
|
+
app.datastore.should_receive(:read).and_return(nil)
|
21
|
+
expect {
|
22
|
+
job.apply
|
23
|
+
}.to raise_error(Dragonfly::Job::Fetch::NotFound)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dragonfly::Job::FetchUrl do
|
4
|
+
|
5
|
+
let (:app) { test_app }
|
6
|
+
let (:job) { Dragonfly::Job.new(app) }
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
stub_request(:get, %r{http://place\.com/.*}).to_return(:body => 'result!')
|
10
|
+
end
|
11
|
+
|
12
|
+
it "adds a step" do
|
13
|
+
job.fetch_url!('some.url')
|
14
|
+
job.steps.should match_steps([Dragonfly::Job::FetchUrl])
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should fetch the specified url when applied" do
|
18
|
+
job.fetch_url!('http://place.com')
|
19
|
+
job.data.should == "result!"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should default to http" do
|
23
|
+
job.fetch_url!('place.com')
|
24
|
+
job.data.should == "result!"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should also work with https" do
|
28
|
+
stub_request(:get, /place.com/).to_return(:body => 'secure result!')
|
29
|
+
job.fetch_url!('https://place.com')
|
30
|
+
job.data.should == "secure result!"
|
31
|
+
end
|
32
|
+
|
33
|
+
[
|
34
|
+
"place.com",
|
35
|
+
"http://place.com",
|
36
|
+
"place.com/",
|
37
|
+
"place.com/stuff/",
|
38
|
+
"place.com/?things"
|
39
|
+
].each do |url|
|
40
|
+
it "doesn't set the name if there isn't one, e.g. for #{url}" do
|
41
|
+
job.fetch_url!(url)
|
42
|
+
job.name.should be_nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it "doesn't set the name url_attr if there isn't one, e.g. for #{url}" do
|
46
|
+
job.fetch_url!(url)
|
47
|
+
job.url_attributes.name.should be_nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
[
|
52
|
+
"place.com/dung.beetle",
|
53
|
+
"http://place.com/dung.beetle",
|
54
|
+
"place.com/stuff/dung.beetle",
|
55
|
+
"place.com/dung.beetle?morethings"
|
56
|
+
].each do |url|
|
57
|
+
it "sets the name if there is one, e.g. for #{url}" do
|
58
|
+
job.fetch_url!(url)
|
59
|
+
job.name.should == 'dung.beetle'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "sets the name url_attr if there is one, e.g. for #{url}" do
|
63
|
+
job.fetch_url!(url)
|
64
|
+
job.url_attributes.name.should == 'dung.beetle'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should raise an error if not found" do
|
69
|
+
stub_request(:get, "notfound.com").to_return(:status => 404, :body => "BLAH")
|
70
|
+
expect{
|
71
|
+
job.fetch_url!('notfound.com').apply
|
72
|
+
}.to raise_error(Dragonfly::Job::FetchUrl::ErrorResponse){|error|
|
73
|
+
error.status.should == 404
|
74
|
+
error.body.should == "BLAH"
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should raise an error if server error" do
|
79
|
+
stub_request(:get, "error.com").to_return(:status => 500, :body => "BLAH")
|
80
|
+
expect{
|
81
|
+
job.fetch_url!('error.com').apply
|
82
|
+
}.to raise_error(Dragonfly::Job::FetchUrl::ErrorResponse){|error|
|
83
|
+
error.status.should == 500
|
84
|
+
error.body.should == "BLAH"
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should follow redirects" do
|
89
|
+
stub_request(:get, "redirectme.com").to_return(:status => 302, :headers => {'Location' => 'http://ok.com'})
|
90
|
+
stub_request(:get, "ok.com").to_return(:body => "OK!")
|
91
|
+
job.fetch_url('redirectme.com').data.should == 'OK!'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "follows redirects to https" do
|
95
|
+
stub_request(:get, "redirectme.com").to_return(:status => 302, :headers => {'Location' => 'https://ok.com'})
|
96
|
+
stub_request(:get, /ok.com/).to_return(:body => "OK!")
|
97
|
+
job.fetch_url('redirectme.com').data.should == 'OK!'
|
98
|
+
end
|
99
|
+
|
100
|
+
it "raises if redirecting too many times" do
|
101
|
+
stub_request(:get, "redirectme.com").to_return(:status => 302, :headers => {'Location' => 'http://redirectme-back.com'})
|
102
|
+
stub_request(:get, "redirectme-back.com").to_return(:status => 302, :headers => {'Location' => 'http://redirectme.com'})
|
103
|
+
expect {
|
104
|
+
job.fetch_url('redirectme.com').apply
|
105
|
+
}.to raise_error(Dragonfly::Job::FetchUrl::TooManyRedirects)
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "data uris" do
|
109
|
+
it "accepts standard base64 encoded data uris" do
|
110
|
+
job.fetch_url!("data:text/plain;base64,aGVsbG8=\n")
|
111
|
+
job.data.should == 'hello'
|
112
|
+
job.mime_type.should == 'text/plain'
|
113
|
+
job.ext.should == 'txt'
|
114
|
+
end
|
115
|
+
|
116
|
+
it "doesn't accept other data uris" do
|
117
|
+
expect {
|
118
|
+
job.fetch_url!("data:text/html;charset=utf-8,<stuff />").apply
|
119
|
+
}.to raise_error(Dragonfly::Job::FetchUrl::CannotHandle)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|