Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

add threaded option with timeout to avoid blocking

  • Loading branch information...
commit 4172d203da180732042f608de5ba2af9f9c848cc 1 parent c72a8af
Daniel Mendler authored
Showing with 35 additions and 3 deletions.
  1. +15 −3 lib/rack/embed.rb
  2. +20 −0 test/test_rack_embed.rb
18 lib/rack/embed.rb
View
@@ -5,8 +5,10 @@ module Rack
class Embed
def initialize(app, opts = {})
@app = app
- @max_size = opts[:max_size] || 1024000
+ @max_size = opts[:max_size] || 1024
@mime_types = opts[:mime_types] || %w(text/css application/xhtml+xml text/html)
+ @threaded = opts[:threaded] || false
+ @timeout = opts[:timeout] || 0.5
end
def call(env)
@@ -83,7 +85,17 @@ def get_image(env, src)
'REQUEST_METHOD' => 'GET',
'QUERY_STRING' => query)
inclusion_env.delete('rack.request')
- status, header, body = @app.call(inclusion_env)
+
+ status, header, body = if @threaded
+ app = @app
+ result = nil
+ thread = Thread.new { result = app.call(inclusion_env) }
+ return src if !thread.join(@timeout)
+ result
+ else
+ @app.call(inclusion_env)
+ end
+
type = content_type(header)
return src if status != 200 || !type
@@ -98,7 +110,7 @@ def get_image(env, src)
body = [body].pack('m')
body.gsub!("\n", '')
"data:#{type};base64,#{body}"
- rescue
+ rescue => ex
src
end
end
20 test/test_rack_embed.rb
View
@@ -41,6 +41,26 @@ def test_css
assert_equal ['background: url(data:image/png;base64,aW1hZ2VfZGF0YQ==)'], esi_app.call('SCRIPT_NAME' => '', 'PATH_INFO' => '/', 'HTTP_USER_AGENT' => 'WebKit')[2]
end
+ def test_threaded
+ app = Rack::URLMap.new({
+ '/' => const([200, {'Content-Type' => 'text/css'}, ['background: url(/image)']]),
+ '/image' => const([200, {'Content-Type' => 'image/png'}, ['image_data']])
+ })
+
+ esi_app = Rack::Embed.new(app, :threaded => true)
+ assert_equal ['background: url(data:image/png;base64,aW1hZ2VfZGF0YQ==)'], esi_app.call('SCRIPT_NAME' => '', 'PATH_INFO' => '/', 'HTTP_USER_AGENT' => 'WebKit')[2]
+ end
+
+ def test_threaded_timeout
+ app = Rack::URLMap.new({
+ '/' => const([200, {'Content-Type' => 'text/css'}, ['background: url(/image)']]),
+ '/image' => proc { sleep 2 }
+ })
+
+ esi_app = Rack::Embed.new(app, :threaded => true, :timeout => 1)
+ assert_equal ['background: url(/image)'], esi_app.call('SCRIPT_NAME' => '', 'PATH_INFO' => '/', 'HTTP_USER_AGENT' => 'WebKit')[2]
+ end
+
def test_too_large
app = Rack::URLMap.new({
'/' => const([200, {'Content-Type' => 'text/css'}, ['background: url(/image)']]),
Please sign in to comment.
Something went wrong with that request. Please try again.