2011-12-05 28 views
5

Tôi đang sử dụng đá quý ruby ​​AWS chính thức cho S3 và tôi gặp sự cố khi sử dụng phương thức "url_for" trên các tệp có ký tự đặc biệt trong đó (ví dụ: dấu phẩy, dấu nháy đơn). Tôi đang sử dụng đá quý AWS-sdk mới nhất cho ruby ​​và mã của tôi trông như thế này:Các ký tự đặc biệt trong tên tập tin ảnh hưởng đến phương pháp đá quý aws-sdk ruby ​​url_for

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

Đối tượng là nhận thấy một cách chính xác, nhưng URL tôi nhận được từ url_for mang lại cho tôi một HTTPError: 404 Not Found lỗi. Nó hoạt động tốt nếu tên tệp không có dấu phẩy hoặc dấu nháy đơn trong đó.

Có cách nào để xử lý việc này mà không cần phải hạn chế tên tệp ở địa điểm đầu tiên không?

+0

URL của bạn trông như thế nào? – sarnold

+0

Tôi đã thay thế một vài phần để bảo mật, nhưng đây là ý chính của nó. Nó bắt đầu bằng https cũng ... //mybucket.s3.amazonaws.com/mypathstuff/test%2Ctest.png?AWSAccessKeyId=MYACCESSKEY&Expires=1323005992&Signature=lettersandnumbers%2Bt2RtdCnBAA%3D –

+0

Phía trên các phần tôi đã thay thế là "mybucket", "mypathstuff "và" lettersandnumbers ". Tôi đã thử mã hóa/giải mã URL thành không có lợi ích. –

Trả lời

2

Bạn có thoát chuỗi URL theo mặc định không? Ví dụ:

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

Điều này sẽ thoát đúng chuỗi thành định dạng có thể duyệt được. Tôi làm điều này cho tất cả các URL S3 an toàn của tôi vì đôi khi có một ký tự / hoặc + trong chữ ký sẽ khiến liên kết thất bại nếu nó không được thoát đúng cách. Điều này cũng sẽ thoát khỏi dấu phẩy và dấu nháy đơn đúng cách.

+0

Tôi đã thử với và không có thoát, nó không có vẻ quan trọng. –

+0

Phương thức 'url_for' có ném ngoại lệ (HTTPError) hay chỉ khi bạn cố bấm vào liên kết mà nó hiển thị cho bạn trang 404? – iwasrobbed

+0

Đó là khi tôi nhấp vào liên kết mà tôi nhận được trang 404. –

2

Gần đây tôi đã gặp sự cố tương tự. Tôi không thể sửa tên tệp trước khi gửi thay vì sử dụng #url_for, tôi đã kết thúc bằng cách viết bộ mã hóa riêng của mình. Đó không phải là quá khó khăn, mặc dù gây phiền nhiễu rằng nó không hoàn toàn làm việc trong đá quý aws-sdk.

Đây là giải pháp của tôi

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 

này giả định bạn có thông tin AWS của bạn trong một hash config, digest đây là một 'sha1' và tên miền trông giống như https://<my_bucket>.s3-<region>.amazonaws.com. Đối với lớp học đầy đủ, bạn có thể kiểm tra gist này https://gist.github.com/bunnymatic/9274108.

+0

Trong trường hợp của tôi, '' đang mong đợi 2 dòng mới (không phải 3), theo loại nội dung. Phản hồi từ các máy chủ AWS khá hữu ích trong trường hợp này, ngoài ra, tôi cũng phải mã hóa URL tên tệp. –

Các vấn đề liên quan