2011-12-05 4 views
5

Używam oficjalnego klejnotu ruby ​​AWS dla S3 i mam problem z użyciem metody "url_for" w plikach, które mają w sobie znaki specjalne (np. Przecinki, apostrofy). Używam najnowszy klejnot AWS-SDK dla Ruby i mój kod wygląda następująco:Znaki specjalne w pliku wpływającym na aws-sdk ruby ​​gem url_for method

s3 = AWS::S3::new 
bucket = s3.buckets[bucket] 
object = bucket.objects[object_address] 
object_url = object.url_for(:read, :expires => 60*60, :secure => true) 

Obiekt jest uzyskiwanie znaleźć poprawnie, ale URL dostaję od url_for daje mi httpError: 404 Not Found błąd. Działa dobrze, jeśli nazwa pliku nie zawiera przecinków ani apostrofów.

Czy istnieje sposób radzenia sobie z tym bez konieczności ograniczania nazw plików w pierwszej kolejności?

+0

Jak wygląda twój adres URL? – sarnold

+0

Wymieniłem kilka części dla prywatności, ale to jest sedno tego. Zaczyna się od https również ... //mybucket.s3.amazonaws.com/mypathstuff/test%2Ctest.png?AWSAccessKeyId=MYACCESSKEY&Expires=1323005992&Signature=lettersandnumbers%2Bt2RtdCnBAA%3D –

+0

Powyżej części, które zamieniłem, były "mybucket", "mypathstuff" "i" litery i numery ". Próbowałem kodowania/dekodowania adresu URL bez żadnych korzyści. –

Odpowiedz

2

Czy domyślnie usuwasz ciąg URL? Na przykład:

object_url = CGI.escape(object.url_for(:read, :expires => 60*60, :secure => true)) 

Spowoduje to prawidłową ucieczkę ciągu znaków do formatu czytelnego dla przeglądarki. Robię to dla wszystkich moich bezpiecznych adresów URL S3, ponieważ czasami są podpisy w postaci / lub +, które spowodują również, że połączenie się nie powiedzie, jeśli nie zostanie poprawnie zmienione. Uchroni to również poprawnie przecinki i apostrofy.

+0

Próbowałem z i bez ucieczki, to nie wydaje się ważne. –

+0

Czy metoda 'url_for' generuje wyjątek (HTTPError), czy jest to po prostu próba kliknięcia łącza wyświetlającego stronę 404? – iwasrobbed

+0

To jest po kliknięciu łącza, które dostaję stronę 404. –

2

Wpadłem ostatnio na ten sam problem. Nie udało mi się poprawić nazw plików przed przesłaniem, więc zamiast używać #url_for, skończyłem pisać swój własny koder. Nie było to zbyt trudne, choć denerwujące, że nie działa w gemie.

Oto moje rozwiązanie

def url_for_read(path, opts) 
    expire_date = (Time.zone.now + opts[:expires]).to_i 
    request_string = "GET\n\n\n#{expire_date}\n/#{config[:bucket]}/#{path}" 
    hmac = OpenSSL::HMAC.digest(digest, config[:secret_access_key], request_string) 
    signature = URI.escape(Base64.encode64(hmac).strip) 
    s3_url_domain + "#{path}?AWSAccessKeyId=#{config[:access_key_id]}&Expires=#{expire_date}&Signature=#{CGI::escape(signature)}" 
end 

Zakłada masz informacje AWS w config hash, digest tutaj jest „sha1” i domena wygląda https://<my_bucket>.s3-<region>.amazonaws.com. Aby uzyskać pełną klasę, możesz zapoznać się z tym zagadnieniem https://gist.github.com/bunnymatic/9274108.

+0

W moim przypadku '' oczekiwał 2 nowych linii (nie 3), zgodnie z typem zawartości. Odpowiedź z serwerów AWS jest bardzo pomocna w tym przypadku, musiałem też zakodować nazwę pliku URL. –