2011-12-05 11 views
5

Estoy usando la gema oficial de rubíes de AWS para S3 y tengo problemas para usar el método "url_for" en archivos que tienen caracteres especiales en ellos (es decir, comas, apóstrofes) Estoy utilizando la última joya AWS-SDK para Ruby y mi código tiene este aspecto:Caracteres especiales en el nombre de archivo que afectan 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) 

El objetivo es conseguir constató correctamente, pero la URL que recibo de url_for me da un HTTPError: 404 Not Found error. Funciona bien si el nombre del archivo no tiene comas o apóstrofos en él.

¿Hay alguna manera de manejar esto sin tener que restringir los nombres de los archivos en primer lugar?

+0

¿Cómo se ve tu URL? – sarnold

+0

He reemplazado algunas partes por privacidad, pero esta es la esencia de esto. Comienza con https también ... //mybucket.s3.amazonaws.com/mypathstuff/test%2Ctest.png?AWSAccessKeyId=MYACCESSKEY&Expires=1323005992&Signature=lettersandnumbers%2Bt2RtdCnBAA%3D –

+0

Por encima de las partes que sustituí fueron "mybucket", "mypathstuff" "y" letras y números ". Intenté codificar/decodificar la URL sin ningún beneficio. –

Respuesta

2

¿Está escapando de la cadena de URL de forma predeterminada? Por ejemplo:

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

Esto escaparía correctamente de la cadena en un formato legible por el navegador. Hago esto para todas mis URL S3 seguras, ya que a veces hay un carácter / o + en la firma que hará que el enlace también falle si no se ha escapado correctamente. Esto también escapará de las comas y los apóstrofos correctamente.

+0

Lo he intentado con y sin escapar, no parece importar. –

+0

¿El método 'url_for' arroja una excepción (HTTPError) o es solo cuando intenta hacer clic en el enlace que le muestra una página 404? – iwasrobbed

+0

Es cuando hago clic en el enlace que obtengo la página 404. –

2

Me encontré con el mismo problema recientemente. No pude corregir los nombres de archivo antes del envío de, así que, en lugar de usar #url_for, terminé escribiendo mi propio codificador. No fue demasiado difícil, aunque es molesto que no funcione en la gema aws-sdk.

aquí está mi solución

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 

Esto supone que tiene su información de AWS en un hash config, digest aquí es un 'sha1' y el dominio se parece a https://<my_bucket>.s3-<region>.amazonaws.com. Para la clase completa, puedes consultar esta esencia https://gist.github.com/bunnymatic/9274108.

+0

En mi caso, '' StringToSign> 'esperaba 2 nuevas líneas (no 3), siguiendo el tipo de contenido. La respuesta de los servidores de AWS es bastante útil en este caso, también, tuve que codificar URL del nombre del archivo también. –

Cuestiones relacionadas