Docker compose, and I’m using Minio as a middleware equivalent to s3 in my local environment. In this configuration, when I want to achieve multipart direct upload, if I use this gem normally, the signature generated by presgined_post is based on the host inside the container, but Actually, I upload from the host os side to localhost:xxxx (=forward port), so the host is different from the signature and becomes localhost, resulting in 403.
As a workaround for this, I replaced the host with localhost when signing and avoided it. However, since this extension became a redundant response, is there a way to flexibly replace Aws::S3::Presigner used in Uppy::S3Multipart::Client?
For now, I’ll share the implementation where I replaced that part.
# config/initializer/shrine.rb
Shrine.plugin :uppy_s3_multipart
if Rails.env.development?
module ShrineUppyS3MultipartEx
def uppy_s3_multipart(storage_key, **options) # rubocop:disable Metrics/CyclomaticComplexity
s3 = find_storage(storage_key)
raise Error, "expected storage to be a Shrine::Storage::S3, but was #{s3.inspect}" unless defined?(Shrine::Storage::S3) && s3.is_a?(Shrine::Storage::S3)
options[:bucket] ||= s3.bucket
options[:prefix] ||= s3.prefix
options[:public] ||= s3.public if s3.respond_to?(:public)
options[:options] ||= opts[:uppy_s3_multipart_options]
MyUppyMultipartApp.new(**options)
end
end
Shrine.singleton_class.prepend(ShrineUppyS3MultipartEx)
class MyUppyMultipartApp < Uppy::S3Multipart::App
def initialize(bucket:, prefix: nil, public: nil, options: {})
super
@router.opts[:client] = MyUppyMultipartClient.new(bucket:)
end
end
class MyUppyMultipartClient < Uppy::S3Multipart::Client
def presigner
MyPresigner.new(client:)
end
end
class MyPresigner < Aws::S3::Presigner
def initialize(*, **)
super
end
def handle_presigned_url_context(req)
super.tap do
handle_host_context(req)
end
end
def handle_host_context(req)
req.handle(priority: 10) do |context|
uri = context.http_request.endpoint
uri.host = 'localhost' # replace host for sign
@handler.call(context)
end
end
end
end
Docker compose, and I’m using Minio as a middleware equivalent to s3 in my local environment. In this configuration, when I want to achieve multipart direct upload, if I use this gem normally, the signature generated by presgined_post is based on the host inside the container, but Actually, I upload from the host os side to
localhost:xxxx
(=forward port), so the host is different from the signature and becomes localhost, resulting in 403.As a workaround for this, I replaced the host with localhost when signing and avoided it. However, since this extension became a redundant response, is there a way to flexibly replace Aws::S3::Presigner used in Uppy::S3Multipart::Client?
For now, I’ll share the implementation where I replaced that part.