oahu-dragonfly 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- 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,39 @@
|
|
1
|
+
module Dragonfly
|
2
|
+
class JobBuilder
|
3
|
+
|
4
|
+
def initialize(&block)
|
5
|
+
@block = block
|
6
|
+
end
|
7
|
+
|
8
|
+
def build(job, *args)
|
9
|
+
evaluate_block(job, false, *args)
|
10
|
+
end
|
11
|
+
|
12
|
+
def build!(job, *args)
|
13
|
+
evaluate_block(job, true, *args)
|
14
|
+
end
|
15
|
+
|
16
|
+
Job.step_names.each do |step|
|
17
|
+
|
18
|
+
# fetch, process, etc.
|
19
|
+
define_method step do |*args|
|
20
|
+
if @perform_with_bangs
|
21
|
+
@job.send("#{step}!", *args)
|
22
|
+
else
|
23
|
+
@job = @job.send(step, *args)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def evaluate_block(job, perform_with_bangs, *args)
|
32
|
+
@job = job
|
33
|
+
@perform_with_bangs = perform_with_bangs
|
34
|
+
instance_exec(*args, &@block)
|
35
|
+
@job
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Dragonfly
|
2
|
+
class JobDefinitions < Module
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@job_definitions = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def add(name, &definition_proc)
|
9
|
+
job_definitions[name] = JobBuilder.new(&definition_proc)
|
10
|
+
jd = job_definitions # Needed because we're about to change 'self'
|
11
|
+
|
12
|
+
define_method name do |*args|
|
13
|
+
jd[name].build(self, *args)
|
14
|
+
end
|
15
|
+
|
16
|
+
define_method "#{name}!" do |*args|
|
17
|
+
jd[name].build!(self, *args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :job_definitions
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Dragonfly
|
4
|
+
module Loggable
|
5
|
+
|
6
|
+
def log
|
7
|
+
case @log_object
|
8
|
+
when nil
|
9
|
+
@log_object = Logger.new($stdout)
|
10
|
+
when Proc
|
11
|
+
@log_object[]
|
12
|
+
when Logger
|
13
|
+
@log_object
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def log=(object)
|
18
|
+
@log_object = object
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :log_object
|
22
|
+
|
23
|
+
def use_same_log_as(object)
|
24
|
+
self.log = proc{ object.log }
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Dragonfly
|
2
|
+
class Middleware
|
3
|
+
|
4
|
+
def initialize(app, dragonfly_app_name, deprecated_arg=nil)
|
5
|
+
raise ArgumentError, "mounting Dragonfly::Middleware with a mount point is deprecated - just use Dragonfly::Middleware, #{dragonfly_app_name.inspect}" if deprecated_arg
|
6
|
+
@app = app
|
7
|
+
@dragonfly_app_name = dragonfly_app_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
response = Dragonfly[@dragonfly_app_name].call(env)
|
12
|
+
if response[1]['X-Cascade'] == 'pass'
|
13
|
+
@app.call(env)
|
14
|
+
else
|
15
|
+
response
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'dragonfly'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
### The dragonfly app ###
|
5
|
+
app = Dragonfly[:images]
|
6
|
+
app.configure_with(:rails)
|
7
|
+
app.configure_with(:imagemagick)
|
8
|
+
|
9
|
+
### Extend active record ###
|
10
|
+
if defined?(ActiveRecord::Base)
|
11
|
+
app.define_macro(ActiveRecord::Base, :image_accessor)
|
12
|
+
app.define_macro(ActiveRecord::Base, :file_accessor)
|
13
|
+
end
|
14
|
+
|
15
|
+
### Insert the middleware ###
|
16
|
+
Rails.application.middleware.insert 0, 'Dragonfly::Middleware', :images
|
17
|
+
|
18
|
+
begin
|
19
|
+
require 'rack/cache'
|
20
|
+
Rails.application.middleware.insert_before 'Dragonfly::Middleware', 'Rack::Cache', {
|
21
|
+
:verbose => true,
|
22
|
+
:metastore => URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/meta"), # URI encoded because Windows
|
23
|
+
:entitystore => URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/body") # has problems with spaces
|
24
|
+
}
|
25
|
+
rescue LoadError => e
|
26
|
+
app.log.warn("Warning: couldn't find rack-cache for caching dragonfly content")
|
27
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Dragonfly
|
4
|
+
class Response
|
5
|
+
|
6
|
+
DEFAULT_FILENAME = proc{|job, request|
|
7
|
+
if job.basename
|
8
|
+
extname = job.encoded_extname || (".#{job.ext}" if job.ext)
|
9
|
+
"#{job.basename}#{extname}"
|
10
|
+
end
|
11
|
+
}
|
12
|
+
|
13
|
+
def initialize(job, env)
|
14
|
+
@job, @env = job, env
|
15
|
+
@app = @job.app
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_response
|
19
|
+
if !(request.head? || request.get?)
|
20
|
+
[405, method_not_allowed_headers, ["#{request.request_method} method not allowed"]]
|
21
|
+
elsif etag_matches?
|
22
|
+
[304, cache_headers, []]
|
23
|
+
elsif request.head?
|
24
|
+
[200, success_headers.merge(cache_headers), []]
|
25
|
+
elsif request.get?
|
26
|
+
[200, success_headers.merge(cache_headers), job.result]
|
27
|
+
end
|
28
|
+
rescue DataStorage::DataNotFound => e
|
29
|
+
app.log.warn(e.message)
|
30
|
+
[404, {"Content-Type" => 'text/plain'}, ['Not found']]
|
31
|
+
end
|
32
|
+
|
33
|
+
def served?
|
34
|
+
request.get? && !etag_matches?
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_reader :job, :env, :app
|
40
|
+
|
41
|
+
def request
|
42
|
+
@request ||= Rack::Request.new(env)
|
43
|
+
end
|
44
|
+
|
45
|
+
def cache_headers
|
46
|
+
{
|
47
|
+
"Cache-Control" => "public, max-age=#{app.cache_duration}",
|
48
|
+
"ETag" => %("#{job.unique_signature}")
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def etag_matches?
|
53
|
+
return @etag_matches unless @etag_matches.nil?
|
54
|
+
if_none_match = env['HTTP_IF_NONE_MATCH']
|
55
|
+
@etag_matches = if if_none_match
|
56
|
+
if_none_match.tr!('"','')
|
57
|
+
if_none_match.split(',').include?(job.unique_signature) || if_none_match == '*'
|
58
|
+
else
|
59
|
+
false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def success_headers
|
64
|
+
{
|
65
|
+
"Content-Type" => job.mime_type,
|
66
|
+
"Content-Length" => job.size.to_s
|
67
|
+
}.merge(content_disposition_header)
|
68
|
+
end
|
69
|
+
|
70
|
+
def content_disposition_header
|
71
|
+
parts = []
|
72
|
+
parts << content_disposition if content_disposition
|
73
|
+
parts << %(filename="#{URI.encode(filename)}") if filename
|
74
|
+
parts.any? ? {"Content-Disposition" => parts.join('; ')} : {}
|
75
|
+
end
|
76
|
+
|
77
|
+
def method_not_allowed_headers
|
78
|
+
{
|
79
|
+
'Content-Type' => 'text/plain',
|
80
|
+
'Allow' => 'GET, HEAD'
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
def content_disposition
|
85
|
+
@content_disposition ||= evaluate(app.content_disposition)
|
86
|
+
end
|
87
|
+
|
88
|
+
def filename
|
89
|
+
@filename ||= evaluate(app.content_filename)
|
90
|
+
end
|
91
|
+
|
92
|
+
def evaluate(attribute)
|
93
|
+
attribute.respond_to?(:call) ? attribute.call(job, request) : attribute
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Dragonfly
|
2
|
+
class RoutedEndpoint
|
3
|
+
|
4
|
+
class NoRoutingParams < RuntimeError; end
|
5
|
+
|
6
|
+
def initialize(app, &block)
|
7
|
+
@app = app
|
8
|
+
@block = block
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
params = symbolize_keys_of Rack::Request.new(env).params
|
13
|
+
job = @block.call(params.merge(routing_params(env)), @app)
|
14
|
+
Response.new(job, env).to_response
|
15
|
+
rescue Job::NoSHAGiven => e
|
16
|
+
[400, {"Content-Type" => 'text/plain'}, ["You need to give a SHA parameter"]]
|
17
|
+
rescue Job::IncorrectSHA => e
|
18
|
+
[400, {"Content-Type" => 'text/plain'}, ["The SHA parameter you gave (#{e}) is incorrect"]]
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def routing_params(env)
|
24
|
+
env['rack.routing_args'] ||
|
25
|
+
env['action_dispatch.request.path_parameters'] ||
|
26
|
+
env['router.params'] ||
|
27
|
+
env['usher.params'] ||
|
28
|
+
env['dragonfly.params'] ||
|
29
|
+
raise(NoRoutingParams, "couldn't find any routing parameters in env #{env.inspect}")
|
30
|
+
end
|
31
|
+
|
32
|
+
def symbolize_keys_of(hash)
|
33
|
+
hash.inject({}) do |h, (key, value)|
|
34
|
+
h[(key.to_sym rescue key) || key] = value
|
35
|
+
h
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module Dragonfly
|
5
|
+
module Serializer
|
6
|
+
|
7
|
+
# Exceptions
|
8
|
+
class BadString < RuntimeError; end
|
9
|
+
|
10
|
+
extend self # So we can do Serializer.b64_encode, etc.
|
11
|
+
|
12
|
+
def b64_encode(string)
|
13
|
+
Base64.encode64(string).tr("\n=",'')
|
14
|
+
end
|
15
|
+
|
16
|
+
def b64_decode(string)
|
17
|
+
padding_length = string.length % 4
|
18
|
+
Base64.decode64(string + '=' * padding_length)
|
19
|
+
end
|
20
|
+
|
21
|
+
def marshal_encode(object)
|
22
|
+
b64_encode(Marshal.dump(object))
|
23
|
+
end
|
24
|
+
|
25
|
+
def marshal_decode(string)
|
26
|
+
Marshal.load(b64_decode(string))
|
27
|
+
rescue TypeError, ArgumentError => e
|
28
|
+
raise BadString, "couldn't decode #{string} - got #{e}"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Dragonfly
|
2
|
+
class Server
|
3
|
+
|
4
|
+
include Loggable
|
5
|
+
include Configurable
|
6
|
+
|
7
|
+
configurable_attr :dragonfly_url, '/dragonfly'
|
8
|
+
configurable_attr :protect_from_dos_attacks, false
|
9
|
+
configurable_attr :url_format, '/:job/:basename.:format'
|
10
|
+
configurable_attr :url_host
|
11
|
+
|
12
|
+
extend Forwardable
|
13
|
+
def_delegator :url_mapper, :params_in_url
|
14
|
+
|
15
|
+
def initialize(app)
|
16
|
+
@app = app
|
17
|
+
use_same_log_as(app)
|
18
|
+
use_as_fallback_config(app)
|
19
|
+
end
|
20
|
+
|
21
|
+
def before_serve(&block)
|
22
|
+
self.before_serve_callback = block
|
23
|
+
end
|
24
|
+
configuration_method :before_serve
|
25
|
+
|
26
|
+
def after_serve(&block)
|
27
|
+
self.after_serve_callback = block
|
28
|
+
end
|
29
|
+
configuration_method :after_serve
|
30
|
+
|
31
|
+
def call(env)
|
32
|
+
if dragonfly_url == env["PATH_INFO"]
|
33
|
+
dragonfly_response
|
34
|
+
elsif (params = url_mapper.params_for(env["PATH_INFO"], env["QUERY_STRING"])) && params['job']
|
35
|
+
job = Job.deserialize(params['job'], app)
|
36
|
+
job.validate_sha!(params['sha']) if protect_from_dos_attacks
|
37
|
+
response = Response.new(job, env)
|
38
|
+
catch(:halt) do
|
39
|
+
if before_serve_callback && response.served?
|
40
|
+
before_serve_callback.call(job, env)
|
41
|
+
end
|
42
|
+
resp = response.to_response
|
43
|
+
if after_serve_callback && resp[0] == 200 && resp[2].is_a?(Dragonfly::TempObject)
|
44
|
+
after_serve_callback.call(job, env)
|
45
|
+
end
|
46
|
+
resp
|
47
|
+
end
|
48
|
+
else
|
49
|
+
[404, {'Content-Type' => 'text/plain', 'X-Cascade' => 'pass'}, ['Not found']]
|
50
|
+
end
|
51
|
+
rescue Serializer::BadString, Job::InvalidArray => e
|
52
|
+
log.warn(e.message)
|
53
|
+
[404, {'Content-Type' => 'text/plain'}, ['Not found']]
|
54
|
+
rescue Job::NoSHAGiven => e
|
55
|
+
[400, {"Content-Type" => 'text/plain'}, ["You need to give a SHA parameter"]]
|
56
|
+
rescue Job::IncorrectSHA => e
|
57
|
+
[400, {"Content-Type" => 'text/plain'}, ["The SHA parameter you gave (#{e}) is incorrect"]]
|
58
|
+
end
|
59
|
+
|
60
|
+
def url_for(job, opts={})
|
61
|
+
opts = opts.dup
|
62
|
+
host = opts.delete(:host) || url_host
|
63
|
+
params = stringify_keys(opts)
|
64
|
+
params['job'] = job.serialize
|
65
|
+
params['sha'] = job.sha if protect_from_dos_attacks
|
66
|
+
url = url_mapper.url_for(params)
|
67
|
+
"#{host}#{url}"
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
attr_reader :app
|
73
|
+
attr_accessor :before_serve_callback
|
74
|
+
attr_accessor :after_serve_callback
|
75
|
+
|
76
|
+
def url_mapper
|
77
|
+
@url_mapper ||= UrlMapper.new(url_format,
|
78
|
+
:job => '\w',
|
79
|
+
:basename => '[^\/]',
|
80
|
+
:format => '[^\.]'
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def stringify_keys(params)
|
85
|
+
params.inject({}) do |hash, (k, v)|
|
86
|
+
hash[k.to_s] = v
|
87
|
+
hash
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def dragonfly_response
|
92
|
+
body = <<-DRAGONFLY
|
93
|
+
_o|o_
|
94
|
+
_~~---._( )_.---~~_
|
95
|
+
( . \\ / . )
|
96
|
+
`-.~--' |=| '--~.-'
|
97
|
+
_~-.~'" /|=|\\ "'~.-~_
|
98
|
+
( ./ |=| \\. )
|
99
|
+
`~~`"` |=| `"'ME"
|
100
|
+
|-|
|
101
|
+
<->
|
102
|
+
V
|
103
|
+
DRAGONFLY
|
104
|
+
[200, {
|
105
|
+
'Content-Type' => 'text/plain',
|
106
|
+
'Content-Size' => body.bytesize.to_s
|
107
|
+
},
|
108
|
+
[body]
|
109
|
+
]
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|