diff --git a/lib/paperclip.rb b/lib/paperclip.rb index 621564d..cf2e5e0 100644 --- a/lib/paperclip.rb +++ b/lib/paperclip.rb @@ -27,6 +27,7 @@ require 'tempfile' require 'fastimage' +require 'addressable' require 'paperclip/upfile' require 'paperclip/iostream' require 'paperclip/geometry' diff --git a/lib/paperclip/storage/no_cache_s3.rb b/lib/paperclip/storage/no_cache_s3.rb index f56b573..32ebf33 100644 --- a/lib/paperclip/storage/no_cache_s3.rb +++ b/lib/paperclip/storage/no_cache_s3.rb @@ -180,14 +180,15 @@ module Paperclip # К ссылке, сформированной по паттерну (например, через наш CDN), добавляем параметры с подписью def presigned_url(style) - uri = URI.parse(Addressable::URI.escape(storage_url(style))) - basic_params = CGI.parse(uri.query || '') - presign_params = CGI.parse(URI.parse(self.class.store_by(self.class.main_store_id).object(key(style)) - .presigned_url(:get)).query) + uri = Addressable::URI.parse(storage_url(style)) + basic_params = uri.query_values || {} + presign_params = Addressable::URI.parse( + self.class.store_by(self.class.main_store_id).object(key(style)).presigned_url(:get) + ).query_values result_params = basic_params.merge(presign_params) - uri.query = URI.encode_www_form(result_params) - uri.to_s + uri.query_values = result_params + uri.normalize.to_s end def synced_to?(store_id) diff --git a/test/fixtures/кириллица.txt b/test/fixtures/кириллица.txt deleted file mode 100644 index e69de29..0000000 diff --git a/test/storage/no_cache_s3_test.rb b/test/storage/no_cache_s3_test.rb index 8e7fe9a..ec819ae 100644 --- a/test/storage/no_cache_s3_test.rb +++ b/test/storage/no_cache_s3_test.rb @@ -41,7 +41,7 @@ class NoCacheS3Test < Test::Unit::TestCase @store1_stub.stubs(:url).returns('http://store.local') @store2_stub.stubs(:url).returns('http://store.local') @instance.avatar.class.stubs(:stores).returns({ store_1: @store1_stub, store_2: @store2_stub }) - Dummy::AvatarAttachment.any_instance.stubs(:to_file).returns(stub_file('кириллица.txt', 'qwe')) + Dummy::AvatarAttachment.any_instance.stubs(:to_file).returns(stub_file('text.txt', 'qwe')) end teardown { TEST_ROOT.rmtree if TEST_ROOT.exist? } @@ -80,6 +80,24 @@ class NoCacheS3Test < Test::Unit::TestCase end end end + + context 'generating presigned_url' do + setup do + Dummy::AvatarAttachment.any_instance.stubs(:storage_url).returns('http://домен.pф/ключ?param1=параметр') + object_stub = mock + object_stub.stubs(:presigned_url).returns('http://другой.домен?param2=param_value') + @store1_stub.stubs(:object).returns(object_stub) + end + + should 'escape cyrillic and work' do + @instance.avatar = stub_file('кириллица.txt', 'qwe') + assert_equal( + "http://xn--d1acufc.xn--p-eub/%D0%BA%D0%BB%D1%8E%D1%87?"\ + "param1=%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80¶m2=param_value", + @instance.avatar.send(:presigned_url, :original) + ) + end + end end # rubocop:enable Naming/VariableNumber