module FmRest
module V1
module ContainerFields
DEFAULT_UPLOAD_CONTENT_TYPE = "application/octet-stream".freeze
def fetch_container_data(container_field_url, base_connection = nil)
require "open-uri"
begin
url = URI(container_field_url)
rescue ::URI::InvalidURIError
raise FmRest::ContainerFieldError, "Invalid container field URL `#{container_field_url}'"
end
unless url.scheme.match(/\Ahttps?\Z/)
raise FmRest::ContainerFieldError, "Container URL is not HTTP (#{container_field_url})"
end
ssl_options = base_connection && base_connection.ssl && base_connection.ssl.to_hash
proxy_options = base_connection && base_connection.proxy && base_connection.proxy.to_hash
conn =
Faraday.new(nil,
ssl: ssl_options || FmRest.default_connection_settings[:ssl],
proxy: proxy_options || FmRest.default_connection_settings[:proxy]
)
openuri_options =
faraday_connection_to_openuri_options(conn).merge(redirect: false)
begin
url.open(openuri_options)
rescue OpenURI::HTTPRedirect => e
unless cookie = e.io.metas.dig("set-cookie", 0)
raise FmRest::ContainerFieldError, "Container field's initial request didn't return a session cookie, the URL may be stale (try downloading it again immediately after retrieving the record)"
end
url = URI(e.io.meta["location"])
url.open(openuri_options.merge("Cookie" => cookie))
end
end
def upload_container_data(connection, container_path, filename_or_io, options = {})
content_type = options[:content_type] || DEFAULT_UPLOAD_CONTENT_TYPE
connection.post do |request|
request.url container_path
request.['Content-Type'] = ::Faraday::Multipart::Middleware.mime_type
filename = options[:filename] || filename_or_io.try(:original_filename)
request.body = { upload: Faraday::Multipart::FilePart.new(filename_or_io, content_type, filename) }
end
end
private
def faraday_connection_to_openuri_options(conn)
openuri_opts = {}
if !conn.ssl.empty?
openuri_opts[:ssl_verify_mode] =
conn.ssl.fetch(:verify, true) ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
openuri_opts[:ssl_ca_cert] = conn.ssl.cert_store if conn.ssl.cert_store
end
if conn.proxy && !conn.proxy.empty?
if conn.proxy.user && conn.proxy.password
openuri_opts[:proxy_http_basic_authentication] =
[conn.proxy.uri.tap { |u| u.userinfo = ""}, conn.proxy.user, conn.proxy.password]
else
openuri_opts[:proxy] = conn.proxy.uri
end
end
openuri_opts
end
end
end
end