Some checks failed
Tests / test (6, 2.7) (pull_request) Failing after 19s
Tests / test (6, 3.0) (pull_request) Failing after 3s
Tests / test (6, 3.1) (pull_request) Failing after 3s
Tests / test (7, 2.7) (pull_request) Failing after 3s
Tests / test (7, 3.0) (pull_request) Failing after 3s
Tests / test (7, 3.1) (pull_request) Failing after 3s
We encode the URLs ourselves, and the default option for the aws-sigv4 gem breaks that functionality.
99 lines
2.4 KiB
Ruby
99 lines
2.4 KiB
Ruby
require "remote_storage/rest_provider"
|
|
require "digest"
|
|
require "base64"
|
|
require "cgi"
|
|
require "openssl"
|
|
|
|
module RemoteStorage
|
|
class S3
|
|
include RestProvider
|
|
|
|
private
|
|
|
|
def s3_signer
|
|
signer ||= Aws::Sigv4::Signer.new(
|
|
service: 's3',
|
|
region: settings.s3["region"],
|
|
access_key_id: settings.s3["access_key_id"].to_s,
|
|
secret_access_key: settings.s3["secret_key_id"].to_s,
|
|
uri_escape_path: false
|
|
)
|
|
end
|
|
|
|
# S3 already wraps the ETag with quotes
|
|
def format_etag(etag)
|
|
etag
|
|
end
|
|
|
|
def do_put_request(url, data, content_type)
|
|
deal_with_unauthorized_requests do
|
|
headers = { "Content-Type" => content_type }
|
|
auth_headers = auth_headers_for("PUT", url, headers, data)
|
|
|
|
res = RestClient.put(url, data, headers.merge(auth_headers))
|
|
|
|
return [
|
|
res.headers[:etag].delete('"'),
|
|
timestamp_for(res.headers[:date]) # S3 does not return a Last-Modified response header on PUTs
|
|
]
|
|
end
|
|
end
|
|
|
|
def do_get_request(url, &block)
|
|
deal_with_unauthorized_requests do
|
|
headers = {}
|
|
headers["Range"] = server.env["HTTP_RANGE"] if server.env["HTTP_RANGE"]
|
|
auth_headers = auth_headers_for("GET", url, headers)
|
|
RestClient.get(url, headers.merge(auth_headers), &block)
|
|
end
|
|
end
|
|
|
|
def do_head_request(url, &block)
|
|
deal_with_unauthorized_requests do
|
|
auth_headers = auth_headers_for("HEAD", url)
|
|
RestClient.head(url, auth_headers, &block)
|
|
end
|
|
end
|
|
|
|
def do_delete_request(url)
|
|
deal_with_unauthorized_requests do
|
|
auth_headers = auth_headers_for("DELETE", url)
|
|
RestClient.delete(url, auth_headers)
|
|
end
|
|
end
|
|
|
|
def try_to_delete(url)
|
|
found = true
|
|
|
|
begin
|
|
do_head_request(url)
|
|
rescue RestClient::ResourceNotFound
|
|
found = false
|
|
end
|
|
|
|
do_delete_request(url) if found
|
|
|
|
return found
|
|
end
|
|
|
|
def auth_headers_for(http_method, url, headers = {}, data = nil)
|
|
signature = s3_signer.sign_request(
|
|
http_method: http_method, url: url, headers: headers, body: data
|
|
)
|
|
signature.headers
|
|
end
|
|
|
|
def uri_escape(s)
|
|
CGI.escape(s).gsub('%5B', '[').gsub('%5D', ']')
|
|
end
|
|
|
|
def base_url
|
|
@base_url ||= settings.s3["endpoint"]
|
|
end
|
|
|
|
def container_url_for(user)
|
|
"#{base_url}/#{settings.s3["bucket"]}/#{user}"
|
|
end
|
|
end
|
|
end
|