2013-03-06 3 views
2

이 말은 나를 괴롭힌다. Im Amazon S3에서 CarrierWave를 사용하면 버킷에 파일을 안전하게 업로드 할 수 있습니다. Im은 (다른 요청으로) 파일을 검색하고 브라우저에 다운로드하여 전달하려고합니다.CarrierWave S3 File 검색 문제 - 정의되지 않은 메소드 'body'

파일은 아무거나, .zip 파일 등이 될 수 있습니다. 이미지 저장에는 사용하지 않습니다.

버킷은 공개되지 않은 비공개이므로 S3 URL을 사용할 수 없습니다. cache_stored_file에

au = @note.attachment 
au.retrieve_from_store!(File.basename(@note.attachment.to_s)) 
au.cache_stored_file! 

코드 오류 :

여기 내 검색 코드입니다! 선. 내가 객체를 검사하고 나에게 잘 보이고, I 출력 @의 note.attachment 경우, 나는 모든되었습니다 등 키

IV와 아마존 S3의 URL을 명확하게 볼 수 있습니다

undefined method `body' for nil:NilClass 

: 오류를 던지는 웹을 통해 알아낼 수 있습니다. Iv는 같은 문제가있는 소수의 사람들이 내 사건과 관련이없는 일 (예 : 일부 imagemagick 메서드 사용)으로 문제를 해결할 수 있음을 발견했습니다.

처리 또는 이미지 작업이 없으므로 파일을 브라우저로 다운로드하여 보내려합니다.

아무도 도와 줄 수 있습니까?

carrierwave (0.8.0) lib/carrierwave/storage/fog.rb:225:in `read' 
carrierwave (0.8.0) lib/carrierwave/uploader/cache.rb:77:in `sanitized_file' 
carrierwave (0.8.0) lib/carrierwave/uploader/cache.rb:116:in `cache!' 
carrierwave (0.8.0) lib/carrierwave/uploader/cache.rb:73:in `cache_stored_file!' 

답변

3

나는이 선을 의미하지 않습니다 생각

class AttachmentUploader < CarrierWave::Uploader::Base 

    storage :fog 

    def store_dir 
    "#{Rails.env}/#{model.id}" 
    end 

    def cache_dir 
    "#{Rails.root}/tmp/attachments" 
    end 
end 

및 추적 :

au = @note.attachment 
au.retrieve_from_store!(File.basename(@note.attachment.to_s)) 
au.cache_stored_file! 

retrieve_from_store 당신이 일반적으로 부르는 것이 뭔가 여기

내 업 로더입니다 첨부 된 객체가 아니라 업 로더에서 첨부 파일의 기본 이름을 전달하는 복잡한 단계는 경고음이 울리게해야합니다.

올바르게 이해했다면 S3에 저장된 파일을 다운로드 할 수있는 권한을 부여하기 만하면됩니다.

이렇게하는 방법은 몇 가지가 있습니다.

가장 쉬운 방법은 @note.attachment.url을 호출하고 사용자가 클릭 할 수있는 링크로 URL을 인쇄하는 것입니다.

또 다른 방법은 사용자를 컨트롤러 동작의 URL로 리디렉션하는 것입니다.

# notes/1/download_attachment 
def download_attachment 
    @note = Note.find(params[:id) 
    redirect_to @note.attachment.url 
end 

마지막으로 프록시 서버/캐시로 작동하고 S3에서 파일을 가져 와서 반환하는 것입니다.

당신은 당신의 컨트롤러에이 같은 일을 할 수있는 :

file = open(@note.attachment.url) 
send_data file 

나는이 마지막 코드를 테스트 할 수있는 기회가 없었 있습니다.

send_data here에 대한 자세한 내용을 볼 수 있습니다.

+0

답변 해 주셔서 감사합니다. 하지만이 파일들이 보안/개인 파일 인 경우에는 어떨까요? 정말로 S3 URL을 공개하고 싶습니까? 이 첨부 파일은 재무 문서 일 수 있으므로 먼저 파일을 로컬 캐시로 가져온 다음 클라이언트에 제공해야한다고 들었습니다. 그 맞습니까? – Cheyne

+0

사실 내 프로젝트 중 하나에서 비슷한 상황이 있습니다. 내가 한 것은 서버와의 모든 통신에 https를 사용한다는 것입니다. 나는 사용자에게 링크를 제공하지만, 나는 매우 빠르게 만료되는 임시 링크를 만든다. 그렇게하면 공격자는 링크가 만료되기 때문에 http 암호화를 중단하고 매우 빠르게 수행해야합니다. 만료되는 링크는 Carrierwave/Fog를 사용하여 쉽게 구성 할 수 있습니다. – Jesper

+0

하지만 내 대답에서 언급 한 마지막 방법의 변형을 사용하여 파일을 캐싱 할 수도 있습니다. – Jesper

관련 문제