Предварительно подписанные URL-адреса Amazon S3 с использованием Amazon Java SDK и дополнительных символов / - PullRequest
3 голосов
/ 12 февраля 2012

Я создавал предварительно назначенные URL-адреса HTTP PUT, и все работало замечательно, пока я не захотел начать использовать «папки» в S3;Я хотел, чтобы ключ имел символ '/'.

. Теперь я получаю, что подпись не соответствует, когда я отправляю запросы HTTP PUT, потому что' / ', вероятно, меняется на% 2F ...Я экранирую символ перед созданием предварительно назначенного URL-адреса, он прекрасно работает, но затем консольное управление Amazon не понимает его и показывает его как один файл вместо подпапок.HTTP PUT-запросы отправляются с использованием C ++ с библиотекой POCO NET.

EDITЯ использую Poco HttpRequest из C ++ на мой веб-сервер Java для генерации подписанного URL (возвращается в ответе).Затем C ++ использует этот URL, чтобы снова поместить файл в s3, используя Poco.Проблема заключалась в том, что URL-адреса, возвращаемые с веб-сервера, анализировались через объекты URI Poco, которые автоматически декодировали ключ объекта s3, изменяя его.Имея это в виду, я смог решить мою проблему.

1 Ответ

2 голосов
/ 14 февраля 2012

Хитрый - я постараюсь приблизиться к этому дну.

Отказ от ответственности : я увлекся визуальной проверкой библиотек Poco вместо фактической отладки примера кода, который должен давать более надежные результаты гораздо быстрее, см. Ниже;)

Анализ

Если я экранирую символ перед созданием предварительно заданного URL, он будет работать отлично, но тогда консольное управление Amazon не понимает этого и показывает его как один файл вместо подпапок.

Последнее связано с тем, что S3 фактически не имеет представления о папках на уровне хранилища, например, см. section Индекс документов и папок в пределах Индекс поддержки документов :

Объекты, хранящиеся в Amazon S3, хранятся в плоском контейнере, т.е. ведро Amazon S3, и оно не обеспечивает никакой иерархической организация, похожая на файловую систему. Тем не менее, вы можете создать логическая иерархия с использованием имен ключей объектов и использовать эти имена для вывода логические папки, содержащие эти объекты.

Это именно то, что Консоль управления AWS делает и здесь:

Консоль управления AWS также поддерживает концепцию папок: используя то же соглашение о присвоении имен ключей, которое использовалось в предыдущем примере.

Однако , ваш тест на допущение кодирования / как %2F доказывает, что именно так Poco :: Net кодирует URL при выполнении HTTP PUT запрос.

Потенциальное решение

Чтобы ваш сценарий работал должным образом, вам нужно выяснить, где URL-адрес закодирован таким образом - я мог бы подумать о двух компонентах в принципе:

Poco :: Net

Выяснение того, почему Poco :: Net кодирует URL, отличный от S3 (если вообще, см. Ниже), лучше всего сделать путем отладки вашего кода, вот где я бы начал:

Class HTTPRequest по очереди использует класс URI , который автоматически выполняет несколько нормализаций для всех передаваемых ему URI и частей URI , в частности Кодированные в процентах символы декодируются . Обратный поток обрабатывается методом encode () , то есть , когда все становится интересным и требуется точка останова , см. URI.cpp :

  • строк 575 и след. - здесь encode () делает свое волшебство, которое, кажется, действительно имеет место, поскольку ни код внутри функции, ни различные символы, передаваемые через параметр reserved , не содержат ошибочных / (см. Строки 47 и далее относительно соответствующих используемых констант)
  • следовательно, вы можете установить точку останова в этой функции и отследить стек вызовов, чтобы выяснить, какой код на самом деле выполняет кодирование заранее, что может вообще не привести к нарушителю, см. Ниже.

Java => C ++ переход

Вы еще не указали, какой канал фактически используется для передачи предварительно подписанного URL, сгенерированного AWS Java SDK, в свою очередь, на C ++. Учитывая проверку кода (обратите внимание, только визуальный контроль, я сам еще не отлаживал это) функциональности Poco :: Net позволяет сделать вывод, что в самой библиотеке не может быть выявлено явного нарушителя, таким образом, представляется более вероятным, что он уже может войти в ваш слой C ++ в кодировке (это легко проверить, конечно, с помощью отладки) - случайно ли вы используете какой-либо веб-сервис между этими компонентами, например?

Удачи!

...