oahu-dragonfly 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +1 -0
- data/.yardopts +24 -0
- data/Gemfile +30 -0
- data/History.md +323 -0
- data/LICENSE +20 -0
- data/README.md +88 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/config.ru +14 -0
- data/docs.watchr +1 -0
- data/dragonfly.gemspec +297 -0
- data/extra_docs/Analysers.md +66 -0
- data/extra_docs/Caching.md +23 -0
- data/extra_docs/Configuration.md +124 -0
- data/extra_docs/Couch.md +49 -0
- data/extra_docs/DataStorage.md +153 -0
- data/extra_docs/Encoding.md +67 -0
- data/extra_docs/GeneralUsage.md +121 -0
- data/extra_docs/Generators.md +60 -0
- data/extra_docs/Heroku.md +50 -0
- data/extra_docs/ImageMagick.md +125 -0
- data/extra_docs/Index.md +33 -0
- data/extra_docs/MimeTypes.md +40 -0
- data/extra_docs/Models.md +272 -0
- data/extra_docs/Mongo.md +45 -0
- data/extra_docs/Processing.md +77 -0
- data/extra_docs/Rack.md +52 -0
- data/extra_docs/Rails2.md +57 -0
- data/extra_docs/Rails3.md +62 -0
- data/extra_docs/Sinatra.md +25 -0
- data/extra_docs/URLs.md +169 -0
- data/features/images.feature +47 -0
- data/features/no_processing.feature +14 -0
- data/features/rails_3.0.5.feature +8 -0
- data/features/steps/common_steps.rb +8 -0
- data/features/steps/dragonfly_steps.rb +66 -0
- data/features/steps/rails_steps.rb +28 -0
- data/features/support/env.rb +13 -0
- data/features/support/setup.rb +32 -0
- data/fixtures/rails_3.0.5/files/app/models/album.rb +7 -0
- data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
- data/fixtures/rails_3.0.5/files/app/views/albums/show.html.erb +6 -0
- data/fixtures/rails_3.0.5/files/config/initializers/dragonfly.rb +4 -0
- data/fixtures/rails_3.0.5/files/features/manage_album_images.feature +38 -0
- data/fixtures/rails_3.0.5/files/features/step_definitions/helper_steps.rb +7 -0
- data/fixtures/rails_3.0.5/files/features/step_definitions/image_steps.rb +25 -0
- data/fixtures/rails_3.0.5/files/features/support/paths.rb +17 -0
- data/fixtures/rails_3.0.5/files/features/text_images.feature +7 -0
- data/fixtures/rails_3.0.5/template.rb +20 -0
- data/irbrc.rb +18 -0
- data/lib/dragonfly.rb +55 -0
- data/lib/dragonfly/active_model_extensions.rb +13 -0
- data/lib/dragonfly/active_model_extensions/attachment.rb +250 -0
- data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +148 -0
- data/lib/dragonfly/active_model_extensions/class_methods.rb +95 -0
- data/lib/dragonfly/active_model_extensions/instance_methods.rb +28 -0
- data/lib/dragonfly/active_model_extensions/validations.rb +41 -0
- data/lib/dragonfly/analyser.rb +58 -0
- data/lib/dragonfly/analysis/file_command_analyser.rb +32 -0
- data/lib/dragonfly/analysis/image_magick_analyser.rb +6 -0
- data/lib/dragonfly/app.rb +172 -0
- data/lib/dragonfly/config/heroku.rb +19 -0
- data/lib/dragonfly/config/image_magick.rb +6 -0
- data/lib/dragonfly/config/rails.rb +20 -0
- data/lib/dragonfly/configurable.rb +207 -0
- data/lib/dragonfly/core_ext/array.rb +7 -0
- data/lib/dragonfly/core_ext/hash.rb +7 -0
- data/lib/dragonfly/core_ext/object.rb +12 -0
- data/lib/dragonfly/core_ext/string.rb +9 -0
- data/lib/dragonfly/core_ext/symbol.rb +9 -0
- data/lib/dragonfly/data_storage.rb +9 -0
- data/lib/dragonfly/data_storage/couch_data_store.rb +64 -0
- data/lib/dragonfly/data_storage/file_data_store.rb +141 -0
- data/lib/dragonfly/data_storage/mongo_data_store.rb +86 -0
- data/lib/dragonfly/data_storage/s3data_store.rb +145 -0
- data/lib/dragonfly/encoder.rb +13 -0
- data/lib/dragonfly/encoding/image_magick_encoder.rb +6 -0
- data/lib/dragonfly/function_manager.rb +71 -0
- data/lib/dragonfly/generation/image_magick_generator.rb +6 -0
- data/lib/dragonfly/generator.rb +9 -0
- data/lib/dragonfly/hash_with_css_style_keys.rb +21 -0
- data/lib/dragonfly/image_magick/analyser.rb +51 -0
- data/lib/dragonfly/image_magick/config.rb +41 -0
- data/lib/dragonfly/image_magick/encoder.rb +57 -0
- data/lib/dragonfly/image_magick/generator.rb +145 -0
- data/lib/dragonfly/image_magick/processor.rb +99 -0
- data/lib/dragonfly/image_magick/utils.rb +72 -0
- data/lib/dragonfly/image_magick_utils.rb +4 -0
- data/lib/dragonfly/job.rb +451 -0
- data/lib/dragonfly/job_builder.rb +39 -0
- data/lib/dragonfly/job_definitions.rb +26 -0
- data/lib/dragonfly/job_endpoint.rb +15 -0
- data/lib/dragonfly/loggable.rb +28 -0
- data/lib/dragonfly/middleware.rb +20 -0
- data/lib/dragonfly/processing/image_magick_processor.rb +6 -0
- data/lib/dragonfly/processor.rb +9 -0
- data/lib/dragonfly/rails/images.rb +27 -0
- data/lib/dragonfly/response.rb +97 -0
- data/lib/dragonfly/routed_endpoint.rb +40 -0
- data/lib/dragonfly/serializer.rb +32 -0
- data/lib/dragonfly/server.rb +113 -0
- data/lib/dragonfly/simple_cache.rb +23 -0
- data/lib/dragonfly/temp_object.rb +175 -0
- data/lib/dragonfly/url_mapper.rb +78 -0
- data/samples/beach.png +0 -0
- data/samples/egg.png +0 -0
- data/samples/round.gif +0 -0
- data/samples/sample.docx +0 -0
- data/samples/taj.jpg +0 -0
- data/spec/dragonfly/active_model_extensions/model_spec.rb +1426 -0
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +91 -0
- data/spec/dragonfly/analyser_spec.rb +123 -0
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +48 -0
- data/spec/dragonfly/app_spec.rb +135 -0
- data/spec/dragonfly/configurable_spec.rb +461 -0
- data/spec/dragonfly/core_ext/array_spec.rb +19 -0
- data/spec/dragonfly/core_ext/hash_spec.rb +19 -0
- data/spec/dragonfly/core_ext/string_spec.rb +17 -0
- data/spec/dragonfly/core_ext/symbol_spec.rb +17 -0
- data/spec/dragonfly/data_storage/couch_data_store_spec.rb +76 -0
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +296 -0
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +57 -0
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +258 -0
- data/spec/dragonfly/data_storage/shared_data_store_examples.rb +77 -0
- data/spec/dragonfly/function_manager_spec.rb +154 -0
- data/spec/dragonfly/hash_with_css_style_keys_spec.rb +24 -0
- data/spec/dragonfly/image_magick/analyser_spec.rb +64 -0
- data/spec/dragonfly/image_magick/encoder_spec.rb +41 -0
- data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
- data/spec/dragonfly/image_magick/processor_spec.rb +233 -0
- data/spec/dragonfly/image_magick/utils_spec.rb +18 -0
- data/spec/dragonfly/job_builder_spec.rb +37 -0
- data/spec/dragonfly/job_definitions_spec.rb +35 -0
- data/spec/dragonfly/job_endpoint_spec.rb +173 -0
- data/spec/dragonfly/job_spec.rb +1046 -0
- data/spec/dragonfly/loggable_spec.rb +80 -0
- data/spec/dragonfly/middleware_spec.rb +47 -0
- data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
- data/spec/dragonfly/serializer_spec.rb +61 -0
- data/spec/dragonfly/server_spec.rb +278 -0
- data/spec/dragonfly/simple_cache_spec.rb +27 -0
- data/spec/dragonfly/temp_object_spec.rb +306 -0
- data/spec/dragonfly/url_mapper_spec.rb +126 -0
- data/spec/functional/deprecations_spec.rb +51 -0
- data/spec/functional/image_magick_app_spec.rb +27 -0
- data/spec/functional/model_urls_spec.rb +85 -0
- data/spec/functional/remote_on_the_fly_spec.rb +51 -0
- data/spec/functional/to_response_spec.rb +31 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/support/argument_matchers.rb +19 -0
- data/spec/support/image_matchers.rb +47 -0
- data/spec/support/simple_matchers.rb +53 -0
- data/yard/handlers/configurable_attr_handler.rb +38 -0
- data/yard/setup.rb +15 -0
- data/yard/templates/default/fulldoc/html/css/common.css +107 -0
- data/yard/templates/default/layout/html/layout.erb +89 -0
- data/yard/templates/default/module/html/configuration_summary.erb +31 -0
- data/yard/templates/default/module/setup.rb +17 -0
- metadata +544 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
class Testoast
|
|
4
|
+
include Dragonfly::Loggable
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
describe Dragonfly::Loggable do
|
|
8
|
+
|
|
9
|
+
before(:each) do
|
|
10
|
+
@object = Testoast.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
shared_examples_for "common" do
|
|
14
|
+
it "should return a log" do
|
|
15
|
+
@object.log.should be_a(Logger)
|
|
16
|
+
end
|
|
17
|
+
it "should cache the log" do
|
|
18
|
+
@object.log.should == @object.log
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "without being set" do
|
|
23
|
+
it "should return the log object as nil" do
|
|
24
|
+
@object.log_object.should be_nil
|
|
25
|
+
end
|
|
26
|
+
it_should_behave_like 'common'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "when set" do
|
|
30
|
+
before(:each) do
|
|
31
|
+
@log = Logger.new($stdout)
|
|
32
|
+
@object.log = @log
|
|
33
|
+
end
|
|
34
|
+
it "should return the new log" do
|
|
35
|
+
@object.log.should == @log
|
|
36
|
+
end
|
|
37
|
+
it "should return the log object" do
|
|
38
|
+
@object.log_object.should == @log
|
|
39
|
+
end
|
|
40
|
+
it_should_behave_like 'common'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe "when set as a proc" do
|
|
44
|
+
before(:each) do
|
|
45
|
+
@log = Logger.new($stdout)
|
|
46
|
+
@object.log = proc{ @log }
|
|
47
|
+
end
|
|
48
|
+
it "should return the new log" do
|
|
49
|
+
@object.log.should == @log
|
|
50
|
+
end
|
|
51
|
+
it "should return the log object" do
|
|
52
|
+
@object.log_object.should be_a(Proc)
|
|
53
|
+
end
|
|
54
|
+
it "should allow for changing logs" do
|
|
55
|
+
logs = [@log]
|
|
56
|
+
@object.log = proc{ logs[0] }
|
|
57
|
+
@object.log.should == @log
|
|
58
|
+
|
|
59
|
+
new_log = Logger.new($stdout)
|
|
60
|
+
logs[0] = new_log
|
|
61
|
+
|
|
62
|
+
@object.log.should == new_log
|
|
63
|
+
end
|
|
64
|
+
it_should_behave_like 'common'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe "sharing logs" do
|
|
68
|
+
before(:each) do
|
|
69
|
+
@log = Logger.new($stdout)
|
|
70
|
+
@obj1 = Testoast.new
|
|
71
|
+
@obj2 = Testoast.new
|
|
72
|
+
end
|
|
73
|
+
it "should enable sharing logs" do
|
|
74
|
+
@obj1.log = proc{ @log }
|
|
75
|
+
@obj2.use_same_log_as(@obj1)
|
|
76
|
+
@obj2.log.should == @log
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rack'
|
|
3
|
+
|
|
4
|
+
def dummy_rack_app
|
|
5
|
+
lambda{|env| [200, {"Content-Type" => "text/html"}, ["dummy_rack_app body"]] }
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
describe Dragonfly::Middleware do
|
|
9
|
+
|
|
10
|
+
def make_request(app, url)
|
|
11
|
+
Rack::MockRequest.new(app).get(url)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
before(:each) do
|
|
15
|
+
@stack = Rack::Builder.new do
|
|
16
|
+
use Dragonfly::Middleware, :images
|
|
17
|
+
run dummy_rack_app
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should pass through if the app returns X-Cascade: pass" do
|
|
22
|
+
Dragonfly[:images].should_receive(:call).and_return(
|
|
23
|
+
[404, {"Content-Type" => 'text/plain', 'X-Cascade' => 'pass'}, ['Not found']]
|
|
24
|
+
)
|
|
25
|
+
response = make_request(@stack, '/media/hello.png?howare=you')
|
|
26
|
+
response.body.should == 'dummy_rack_app body'
|
|
27
|
+
response.status.should == 200
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should return a 404 if the app returns a 404" do
|
|
31
|
+
Dragonfly[:images].should_receive(:call).and_return(
|
|
32
|
+
[404, {"Content-Type" => 'text/plain'}, ['Not found']]
|
|
33
|
+
)
|
|
34
|
+
response = make_request(@stack, '/media/hello.png?howare=you')
|
|
35
|
+
response.status.should == 404
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should return as per the dragonfly app if the app returns a 200" do
|
|
39
|
+
Dragonfly[:images].should_receive(:call).and_return(
|
|
40
|
+
[200, {"Content-Type" => 'text/plain'}, ['ABCD']]
|
|
41
|
+
)
|
|
42
|
+
response = make_request(@stack, '/media/hello.png?howare=you')
|
|
43
|
+
response.status.should == 200
|
|
44
|
+
response.body.should == 'ABCD'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
def response_for(array)
|
|
4
|
+
Rack::MockResponse.new(*array)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
describe Dragonfly::RoutedEndpoint do
|
|
8
|
+
|
|
9
|
+
def env_for(url, opts={})
|
|
10
|
+
Rack::MockRequest.env_for(url, opts)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
before(:each) do
|
|
14
|
+
@app = test_app
|
|
15
|
+
@endpoint = Dragonfly::RoutedEndpoint.new(@app) {|params, app|
|
|
16
|
+
app.fetch(params[:uid])
|
|
17
|
+
}
|
|
18
|
+
@app.datastore.stub!(:retrieve).with('some_uid').and_return Dragonfly::TempObject.new('wassup')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should raise an error when there are no routing parameters" do
|
|
22
|
+
lambda{
|
|
23
|
+
@endpoint.call(env_for('/blah'))
|
|
24
|
+
}.should raise_error(Dragonfly::RoutedEndpoint::NoRoutingParams)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
{
|
|
28
|
+
'Rails' => 'action_dispatch.request.path_parameters',
|
|
29
|
+
'Usher' => 'usher.params',
|
|
30
|
+
'HTTP Router' => 'router.params',
|
|
31
|
+
'Rack-Mount' => 'rack.routing_args',
|
|
32
|
+
'Dragonfly' => 'dragonfly.params'
|
|
33
|
+
}.each do |name, key|
|
|
34
|
+
|
|
35
|
+
it "should work with #{name} routing args" do
|
|
36
|
+
response = response_for @endpoint.call(env_for('/blah', key => {:uid => 'some_uid'}))
|
|
37
|
+
response.body.should == 'wassup'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should merge with query parameters" do
|
|
43
|
+
env = Rack::MockRequest.env_for('/big/buns?uid=some_uid', 'dragonfly.params' => {:something => 'else'})
|
|
44
|
+
response = response_for @endpoint.call(env)
|
|
45
|
+
response.body.should == 'wassup'
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe Dragonfly::Serializer do
|
|
5
|
+
|
|
6
|
+
include Dragonfly::Serializer
|
|
7
|
+
|
|
8
|
+
[
|
|
9
|
+
'a',
|
|
10
|
+
'sdhflasd',
|
|
11
|
+
'/2010/03/01/hello.png',
|
|
12
|
+
'//..',
|
|
13
|
+
'whats/up.egg.frog',
|
|
14
|
+
'£ñçùí;'
|
|
15
|
+
].each do |string|
|
|
16
|
+
it "should encode #{string.inspect} properly with no padding/line break" do
|
|
17
|
+
b64_encode(string).should_not =~ /\n|=/
|
|
18
|
+
end
|
|
19
|
+
it "should correctly encode and decode #{string.inspect} to the same string" do
|
|
20
|
+
str = b64_decode(b64_encode(string))
|
|
21
|
+
str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
|
|
22
|
+
str.should == string
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
[
|
|
27
|
+
:hello,
|
|
28
|
+
nil,
|
|
29
|
+
true,
|
|
30
|
+
4,
|
|
31
|
+
2.3,
|
|
32
|
+
'wassup man',
|
|
33
|
+
[3,4,5],
|
|
34
|
+
{:wo => 'there'},
|
|
35
|
+
[{:this => 'should', :work => [3, 5.3, nil, {false => 'egg'}]}, [], true]
|
|
36
|
+
].each do |object|
|
|
37
|
+
it "should correctly marshal encode #{object.inspect} properly with no padding/line break" do
|
|
38
|
+
encoded = marshal_encode(object)
|
|
39
|
+
# raise encoded.index("\n").inspect
|
|
40
|
+
encoded.should be_a(String)
|
|
41
|
+
encoded.should_not =~ /\n|=/
|
|
42
|
+
end
|
|
43
|
+
it "should correctly marshal encode and decode #{object.inspect} to the same object" do
|
|
44
|
+
marshal_decode(marshal_encode(object)).should == object
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "marshal_decode" do
|
|
49
|
+
it "should raise an error if the string passed in is empty" do
|
|
50
|
+
lambda{
|
|
51
|
+
marshal_decode('')
|
|
52
|
+
}.should raise_error(Dragonfly::Serializer::BadString)
|
|
53
|
+
end
|
|
54
|
+
it "should raise an error if the string passed in is gobbledeegook" do
|
|
55
|
+
lambda{
|
|
56
|
+
marshal_decode('ahasdkjfhasdkfjh')
|
|
57
|
+
}.should raise_error(Dragonfly::Serializer::BadString)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rack/mock'
|
|
3
|
+
require 'rack/cache'
|
|
4
|
+
|
|
5
|
+
def request(app, path)
|
|
6
|
+
Rack::MockRequest.new(app).get(path)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe Dragonfly::Server do
|
|
10
|
+
|
|
11
|
+
describe "responses" do
|
|
12
|
+
|
|
13
|
+
before(:each) do
|
|
14
|
+
@app = test_app
|
|
15
|
+
@uid = @app.store('HELLO THERE')
|
|
16
|
+
@server = Dragonfly::Server.new(@app)
|
|
17
|
+
@server.url_format = '/media/:job'
|
|
18
|
+
@job = @app.fetch(@uid)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
after(:each) do
|
|
22
|
+
@app.destroy(@uid)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe "successful urls" do
|
|
26
|
+
before(:each) do
|
|
27
|
+
@server.url_format = '/media/:job/:name.:format'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
[
|
|
31
|
+
'',
|
|
32
|
+
'/name',
|
|
33
|
+
'/name.ext'
|
|
34
|
+
].each do |suffix|
|
|
35
|
+
|
|
36
|
+
it "should return successfully when given the url with suffix #{suffix.inspect}" do
|
|
37
|
+
url = "/media/#{@job.serialize}#{suffix}"
|
|
38
|
+
response = request(@server, url)
|
|
39
|
+
response.status.should == 200
|
|
40
|
+
response.body.should == 'HELLO THERE'
|
|
41
|
+
response.content_type.should == 'application/octet-stream'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should return successfully with the correct sha given and protection on" do
|
|
47
|
+
@server.protect_from_dos_attacks = true
|
|
48
|
+
url = "/media/#{@job.serialize}?sha=#{@job.sha}"
|
|
49
|
+
response = request(@server, url)
|
|
50
|
+
response.status.should == 200
|
|
51
|
+
response.body.should == 'HELLO THERE'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should return successfully even if the job is in the query string" do
|
|
57
|
+
@server.url_format = '/'
|
|
58
|
+
url = "/?job=#{@job.serialize}"
|
|
59
|
+
response = request(@server, url)
|
|
60
|
+
response.status.should == 200
|
|
61
|
+
response.body.should == 'HELLO THERE'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should return a 400 if no sha given but protection on" do
|
|
65
|
+
@server.protect_from_dos_attacks = true
|
|
66
|
+
url = "/media/#{@job.serialize}"
|
|
67
|
+
response = request(@server, url)
|
|
68
|
+
response.status.should == 400
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should return a 400 if wrong sha given and protection on" do
|
|
72
|
+
@server.protect_from_dos_attacks = true
|
|
73
|
+
url = "/media/#{@job.serialize}?sha=asdfs"
|
|
74
|
+
response = request(@server, url)
|
|
75
|
+
response.status.should == 400
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
['/media', '/media/'].each do |url|
|
|
79
|
+
it "should return a 404 when no job given, e.g. #{url.inspect}" do
|
|
80
|
+
response = request(@server, url)
|
|
81
|
+
response.status.should == 404
|
|
82
|
+
response.body.should == 'Not found'
|
|
83
|
+
response.content_type.should == 'text/plain'
|
|
84
|
+
response.headers['X-Cascade'].should == 'pass'
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should return a 404 when the url matches but doesn't correspond to a job" do
|
|
89
|
+
response = request(@server, '/media/sadhfasdfdsfsdf')
|
|
90
|
+
response.status.should == 404
|
|
91
|
+
response.body.should == 'Not found'
|
|
92
|
+
response.content_type.should == 'text/plain'
|
|
93
|
+
response.headers['X-Cascade'].should be_nil
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "should return a 404 when the url isn't known at all" do
|
|
97
|
+
response = request(@server, '/jfasd/dsfa')
|
|
98
|
+
response.status.should == 404
|
|
99
|
+
response.body.should == 'Not found'
|
|
100
|
+
response.content_type.should == 'text/plain'
|
|
101
|
+
response.headers['X-Cascade'].should == 'pass'
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "should return a 404 when the url is a well-encoded but bad array" do
|
|
105
|
+
url = "/media/#{Dragonfly::Serializer.marshal_encode([[:egg, {:some => 'args'}]])}"
|
|
106
|
+
response = request(@server, url)
|
|
107
|
+
response.status.should == 404
|
|
108
|
+
response.body.should == 'Not found'
|
|
109
|
+
response.content_type.should == 'text/plain'
|
|
110
|
+
response.headers['X-Cascade'].should be_nil
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "should return a cacheable response" do
|
|
114
|
+
url = "/media/#{@job.serialize}"
|
|
115
|
+
cache = Rack::Cache.new(@server, :entitystore => 'heap:/')
|
|
116
|
+
response = request(cache, url)
|
|
117
|
+
response.status.should == 200
|
|
118
|
+
response.headers['X-Rack-Cache'].should == "miss, store"
|
|
119
|
+
response = request(cache, url)
|
|
120
|
+
response.status.should == 200
|
|
121
|
+
response.headers['X-Rack-Cache'].should == "fresh"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
describe "dragonfly response" do
|
|
127
|
+
before(:each) do
|
|
128
|
+
@app = test_app
|
|
129
|
+
@server = Dragonfly::Server.new(@app)
|
|
130
|
+
@server.url_format = '/media/:job'
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "should return a simple text response" do
|
|
134
|
+
request(@server, '/dragonfly').should be_a_text_response
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "should be configurable" do
|
|
138
|
+
@server.dragonfly_url = '/hello'
|
|
139
|
+
request(@server, '/hello').should be_a_text_response
|
|
140
|
+
request(@server, '/dragonfly').status.should == 404
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "should be possible to turn it off" do
|
|
144
|
+
@server.dragonfly_url = nil
|
|
145
|
+
request(@server, '/').status.should == 404
|
|
146
|
+
request(@server, '/dragonfly').status.should == 404
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
describe "urls" do
|
|
151
|
+
|
|
152
|
+
before(:each) do
|
|
153
|
+
@app = test_app
|
|
154
|
+
@server = Dragonfly::Server.new(@app)
|
|
155
|
+
@server.url_format = '/media/:job/:basename.:format'
|
|
156
|
+
@job = @app.fetch('some_uid')
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "should generate the correct url when no basename/format" do
|
|
160
|
+
@server.url_for(@job).should == "/media/#{@job.serialize}"
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it "should generate the correct url when there is a basename and no format" do
|
|
164
|
+
@server.url_for(@job, :basename => 'hello').should == "/media/#{@job.serialize}/hello"
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "should generate the correct url when there is a basename and different format" do
|
|
168
|
+
@server.url_for(@job, :basename => 'hello', :format => 'gif').should == "/media/#{@job.serialize}/hello.gif"
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "should add extra params to the url query string" do
|
|
172
|
+
@server.url_for(@job, :a => 'thing', :b => 'nuther').should == "/media/#{@job.serialize}?a=thing&b=nuther"
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "should add the host to the url if configured" do
|
|
176
|
+
@server.url_host = 'http://some.server:4000'
|
|
177
|
+
@server.url_for(@job).should == "http://some.server:4000/media/#{@job.serialize}"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "should add the host to the url if passed in" do
|
|
181
|
+
@server.url_for(@job, :host => 'https://bungle.com').should == "https://bungle.com/media/#{@job.serialize}"
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "should favour the passed in host" do
|
|
185
|
+
@server.url_host = 'http://some.server:4000'
|
|
186
|
+
@server.url_for(@job, :host => 'https://smeedy').should == "https://smeedy/media/#{@job.serialize}"
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
describe "Denial of Service protection" do
|
|
190
|
+
before(:each) do
|
|
191
|
+
@app = test_app
|
|
192
|
+
@server = Dragonfly::Server.new(@app)
|
|
193
|
+
@server.protect_from_dos_attacks = true
|
|
194
|
+
@job = @app.fetch('some_uid')
|
|
195
|
+
end
|
|
196
|
+
it "should generate the correct url" do
|
|
197
|
+
@server.url_for(@job).should == "/#{@job.serialize}?sha=#{@job.sha}"
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
describe "before_serve callback" do
|
|
204
|
+
|
|
205
|
+
context "with no stop in the callback" do
|
|
206
|
+
before(:each) do
|
|
207
|
+
@app = test_app
|
|
208
|
+
@app.generator.add(:test){ "TEST" }
|
|
209
|
+
@server = Dragonfly::Server.new(@app)
|
|
210
|
+
@job = @app.generate(:test)
|
|
211
|
+
@x = x = ""
|
|
212
|
+
@server.before_serve do |job, env|
|
|
213
|
+
x << job.data
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it "should be called before serving" do
|
|
218
|
+
response = request(@server, "/#{@job.serialize}")
|
|
219
|
+
response.body.should == 'TEST'
|
|
220
|
+
@x.should == 'TEST'
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it "should not be called before serving a 404 page" do
|
|
224
|
+
response = request(@server, "blah")
|
|
225
|
+
response.status.should == 404
|
|
226
|
+
@x.should == ""
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
context "with a throw :halt in the callback" do
|
|
231
|
+
before(:each) do
|
|
232
|
+
@app = test_app
|
|
233
|
+
@app.generator.add(:test){ "TEST" }
|
|
234
|
+
@server = Dragonfly::Server.new(@app)
|
|
235
|
+
@job = @app.generate(:test)
|
|
236
|
+
@x = x = ""
|
|
237
|
+
@server.before_serve do |job, env|
|
|
238
|
+
x << job.data
|
|
239
|
+
throw :halt, [200, {}, 'hello']
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
it 'return the response instead the job.result' do
|
|
243
|
+
response = request(@server, "/#{@job.serialize}")
|
|
244
|
+
response.body.should == 'hello'
|
|
245
|
+
@x.should == 'TEST'
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
describe "after_serve callback" do
|
|
252
|
+
|
|
253
|
+
before(:each) do
|
|
254
|
+
@app = test_app
|
|
255
|
+
@app.generator.add(:test){ "TEST" }
|
|
256
|
+
@server = Dragonfly::Server.new(@app)
|
|
257
|
+
@job = @app.generate(:test)
|
|
258
|
+
@x = x = ""
|
|
259
|
+
@server.after_serve do |job, env|
|
|
260
|
+
x << job.data
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it "should be called after serving" do
|
|
265
|
+
response = request(@server, "/#{@job.serialize}")
|
|
266
|
+
response.body.should == 'TEST'
|
|
267
|
+
@x.should == 'TEST'
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "should not be called after serving a 404 page" do
|
|
271
|
+
response = request(@server, "blah")
|
|
272
|
+
response.status.should == 404
|
|
273
|
+
@x.should == ""
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
end
|