class Shrine::Derivation::Response

Public Instance Methods

call(env) click to toggle source
# File lib/shrine/plugins/derivation_endpoint.rb, line 466
def call(env)
  if upload
    upload_response(env)
  else
    local_response(env)
  end
end

Private Instance Methods

content_disposition(file) click to toggle source

Returns disposition and filename formatted for the ‘Content-Disposition` header.

# File lib/shrine/plugins/derivation_endpoint.rb, line 557
def content_disposition(file)
  filename  = self.filename
  filename += File.extname(file.path) if File.extname(filename).empty?

  ContentDisposition.format(disposition: disposition, filename: filename)
end
file_response(file, env) click to toggle source

Generates a Rack response triple from a local file. Fills in ‘Content-Type` and `Content-Disposition` response headers from derivation options and file extension of the derivation result.

# File lib/shrine/plugins/derivation_endpoint.rb, line 485
def file_response(file, env)
  status, headers, body = rack_file_response(file.path, env)

  headers = Rack::Headers[headers] if Rack.release >= "3"
  headers = {
    "Content-Type"        => type || headers["Content-Type"],
    "Content-Length"      => headers["Content-Length"],
    "Content-Disposition" => content_disposition(file),
    "Content-Range"       => headers["Content-Range"],
    "Accept-Ranges"       => "bytes",
  }.compact

  body = Rack::BodyProxy.new(body) { File.delete(file.path) }

  file.close

  [status, headers, body]
end
local_response(env) click to toggle source
# File lib/shrine/plugins/derivation_endpoint.rb, line 476
def local_response(env)
  derivative = derivation.generate

  file_response(derivative, env)
end
rack_file_response(path, env) click to toggle source

We call ‘Rack::Files` with no default `Content-Type`, and make sure we stay compatible with both Rack 2.x and 1.6.x.

# File lib/shrine/plugins/derivation_endpoint.rb, line 538
def rack_file_response(path, env)
  if Rack.release >= "2.1"
    server = Rack::Files.new("", {}, nil)
  else
    server = Rack::File.new("", {}, nil)
  end

  if Rack.release > "2"
    server.serving(Rack::Request.new(env), path)
  else
    # :nocov:
    server.path = path
    server.serving(env)
    # :nocov:
  end
end
upload_response(env) click to toggle source

This is called when ‘:upload` is enabled. Checks the storage for already uploaded derivation result, otherwise calls the derivation block and uploads the result. If the derivation result is already uploaded, uses the `rack_response` plugin to generate a Rack response triple.

# File lib/shrine/plugins/derivation_endpoint.rb, line 508
def upload_response(env)
  uploaded_file = upload_redirect ? derivation.retrieve : derivation.opened

  unless uploaded_file
    derivative    = derivation.generate
    uploaded_file = derivation.upload(derivative, delete: upload_redirect)
  end

  if upload_redirect
    redirect_url = uploaded_file.url(**upload_redirect_url_options)
    headers = { "Location" => redirect_url }
    headers = Rack::Headers[headers] if Rack.release >= "3"

    [302, headers, []]
  else
    if derivative && File.exist?(derivative.path)
      file_response(derivative, env)
    else
      uploaded_file.to_rack_response(
        type:        type,
        disposition: disposition,
        filename:    filename,
        range:       env["HTTP_RANGE"],
      )
    end
  end
end