Created
September 5, 2025 08:28
-
-
Save kuboon/165aae18033c274548dcb1d4d3318852 to your computer and use it in GitHub Desktop.
s3 presign 用に作ったけど aws-sdk-s3 が内部で uri encode するので事前に encode してはダメだったと判明し供養
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module HttpUtil | |
| class PathSegment < String | |
| MATCHER = Regexp.new("\\A#{URI::RFC3986_Parser::SEG_NC}+\\Z") | |
| def self.encode_from(str, allow_slash: false) | |
| return str if str.is_a?(PathSegment) | |
| raise 'should not include / in element or use allow_slash option to encode' if !allow_slash && str.include?('/') | |
| new(URI.encode_uri_component(str.unicode_normalize(:nfkc))) | |
| end | |
| def initialize(str) | |
| raise "invalid char: #{str}" unless MATCHER.match?(str) | |
| super.freeze | |
| end | |
| def decode | |
| URI.decode_uri_component(self) | |
| end | |
| end | |
| class Path < Array | |
| def self.build(str_or_arr, allow_slash: false) | |
| case str_or_arr | |
| when Path | |
| str_or_arr | |
| when String | |
| build(str_or_arr.split('/')) | |
| when Array | |
| raise 'should not include blank path segment' if str_or_arr.any?(&:blank?) | |
| Path[*str_or_arr.map { PathSegment.encode_from(_1, allow_slash:) }].freeze | |
| else | |
| raise 'invalid type' | |
| end | |
| end | |
| def to_s | |
| join('/') | |
| end | |
| end | |
| module_function | |
| def content_disposition_value(type, filename) | |
| raise 'type should be attachment or inline' unless type.in? %i[attachment inline] | |
| encoded = PathSegment.encode_from(filename) | |
| "#{type}; filename*=UTF-8''#{encoded.decode}" | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment