Class: CarrierWave::Downloader::Base
- Inherits:
-
Object
- Object
- CarrierWave::Downloader::Base
- Defined in:
- lib/carrierwave/downloader/base.rb
Instance Attribute Summary collapse
-
#uploader ⇒ Object
readonly
Returns the value of attribute uploader.
Instance Method Summary collapse
-
#download(url, remote_headers = {}) ⇒ Object
Downloads a file from given URL and returns a RemoteFile.
-
#initialize(uploader) ⇒ Base
constructor
A new instance of Base.
-
#process_uri(uri) ⇒ Object
Processes the given URL by parsing it, and escaping if necessary.
-
#skip_ssrf_protection?(uri) ⇒ Boolean
If this returns true, SSRF protection will be bypassed.
Constructor Details
#initialize(uploader) ⇒ Base
Returns a new instance of Base.
11 12 13 |
# File 'lib/carrierwave/downloader/base.rb', line 11 def initialize(uploader) @uploader = uploader end |
Instance Attribute Details
#uploader ⇒ Object (readonly)
Returns the value of attribute uploader.
9 10 11 |
# File 'lib/carrierwave/downloader/base.rb', line 9 def uploader @uploader end |
Instance Method Details
#download(url, remote_headers = {}) ⇒ Object
Downloads a file from given URL and returns a RemoteFile.
Parameters
- url (String)
-
The URL where the remote file is stored
- remote_headers (Hash)
-
Request headers
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/carrierwave/downloader/base.rb', line 23 def download(url, remote_headers = {}) headers = remote_headers. reverse_merge('User-Agent' => "CarrierWave/#{CarrierWave::VERSION}") uri = process_uri(url.to_s) begin if skip_ssrf_protection?(uri) response = OpenURI.open_uri(process_uri(url.to_s), headers) else request = nil if ::SsrfFilter::VERSION.to_f < 1.1 response = SsrfFilter.get(uri, headers: headers) do |req| request = req end else response = SsrfFilter.get(uri, headers: headers, request_proc: ->(req) { request = req }) do |res| res.body # ensure to read body end end response.uri = request.uri response.value end rescue StandardError => e raise CarrierWave::DownloadError, "could not download file: #{e.}" end CarrierWave::Downloader::RemoteFile.new(response) end |
#process_uri(uri) ⇒ Object
Processes the given URL by parsing it, and escaping if necessary. Public to allow overriding.
Parameters
- url (String)
-
The URL where the remote file is stored
57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/carrierwave/downloader/base.rb', line 57 def process_uri(uri) uri_parts = uri.split('?') encoded_uri = Addressable::URI.parse(uri_parts.shift).normalize.to_s query = uri_parts.any? ? "?#{uri_parts.join('?')}" : '' begin URI.parse("#{encoded_uri}#{query}") rescue URI::InvalidURIError URI.parse("#{encoded_uri}#{URI::DEFAULT_PARSER.escape(query)}") end rescue URI::InvalidURIError, Addressable::URI::InvalidURIError raise CarrierWave::DownloadError, "couldn't parse URL: #{uri}" 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 CarrierWave::Downloader::CustomDownloader < CarrierWave::Downloader::Base
def skip_ssrf_protection?(uri)
uri.hostname == 'localhost' && uri.port == 80
end
end
my_uploader.downloader = CarrierWave::Downloader::CustomDownloader
88 89 90 |
# File 'lib/carrierwave/downloader/base.rb', line 88 def skip_ssrf_protection?(uri) false end |