Module: CarrierWave::Uploader::Download

Extended by:
ActiveSupport::Concern
Includes:
Cache, Callbacks, Configuration
Included in:
Base
Defined in:
lib/carrierwave/uploader/download.rb

Defined Under Namespace

Classes: RemoteFile

Instance Method Summary collapse

Methods included from Cache

#cache!, #cache_name, #cache_path, #cache_stored_file!, #cached?, #retrieve_from_cache!, #sanitized_file

Methods included from Callbacks

#with_callbacks

Instance Method Details

#download!(uri, remote_headers = {}) ⇒ Object

Caches the file by downloading it from the given URL.

Parameters

url (String)

The URL where the remote file is stored

remote_headers (Hash)

Request headers



100
101
102
103
104
105
# File 'lib/carrierwave/uploader/download.rb', line 100

def download!(uri, remote_headers = {})
  processed_uri = process_uri(uri)
  file = RemoteFile.new(processed_uri, remote_headers, skip_ssrf_protection: skip_ssrf_protection?(processed_uri))
  raise CarrierWave::DownloadError, "trying to download a file which is not served over HTTP" unless file.http?
  cache!(file)
end

#process_uri(uri) ⇒ Object

Processes the given URL by parsing and escaping it. Public to allow overriding.

Parameters

url (String)

The URL where the remote file is stored



114
115
116
117
118
119
120
121
122
# File 'lib/carrierwave/uploader/download.rb', line 114

def process_uri(uri)
  URI.parse(uri)
rescue URI::InvalidURIError
  uri_parts = uri.split('?')
  # regexp from Ruby's URI::Parser#regexp[:UNSAFE], with [] specifically removed
  encoded_uri = URI::DEFAULT_PARSER.escape(uri_parts.shift, /[^\-_.!~*'()a-zA-Z\d;\/?:@&=+$,]/)
  encoded_uri << '?' << URI::DEFAULT_PARSER.escape(uri_parts.join('?')) if uri_parts.any?
  URI.parse(encoded_uri) rescue raise CarrierWave::DownloadError, "couldn't parse URL"
end

#skip_ssrf_protection?(uri) ⇒ Boolean

If this returns true, SSRF protection will be bypassed. You can override this if you want to allow accessing specific local URIs that are not SSRF exploitable.

Parameters

uri (URI)

The URI where the remote file is stored

Examples

class MyUploader < CarrierWave::Uploader::Base
  def skip_ssrf_protection?(uri)
    uri.hostname == 'localhost' && uri.port == 80
  end
end

Returns:

  • (Boolean)


140
141
142
# File 'lib/carrierwave/uploader/download.rb', line 140

def skip_ssrf_protection?(uri)
  false
end