2013-05-20 129 views
4

我想允許使用ruby的Grape API下載二進制文件(.p12文件)。這是我正在嘗試的。如何允許使用GRAPE API下載二進制文件

get '/download_file' do 
    pkcs12 = generate_pkcsfile 
    content_type('application/octet-stream') 
    body(pkcs12.der) 
end 

使用ActionController的等效代碼是

begin 
    pkcs12 = generate_pkcsfile 
    send_data(pkcs12.der, 
      :filename => 'filename.p12') 
end 

的問題是文件中使用API​​似乎與嵌入每一個字符「\ ufffd」字頭的文本文件,而該文件下載使用瀏覽器下載似乎是二進制文件。我如何使用GRAPE API框架允許下載通過ActionController的send_data下載的相同文件

+0

相較於輸出使用ActionController的請求,你看到的'內容Type' HTTP標頭中的差異返回?他們有不同的字符集? –

+0

當你比較問題中的API和瀏覽器時,實際上是「API客戶端加API路由」還是「瀏覽器加上ActionController路由」?你有四種可能的組合,並且不清楚你有什麼問題 - 從你的描述中可以看出,問題實際上是在你的測試API客戶端中嗎? –

+0

沒錯。爲了澄清,爲了測試葡萄API,我使用curl/wget作爲客戶端和/ download_file作爲端點。爲了測試ActionController,我使用了firefox瀏覽器和/ keys作爲端點。換句話說,端點是不同的,但我想要在兩個端點上獲得相同的行爲。我檢查了兩個標題。瀏覽器/鍵響應標題有'text/html; charset = utf-8'作爲內容類型,而葡萄響應頭具有'application/octet-stream'作爲內容類型。但是切換葡萄碼返回'text/html; charset = utf-8'沒有改變響應主體。 – boboverflow

回答

1

我認爲您的葡萄代碼是可以的,我已經使用瀏覽器和Mac HTTP工具測試了它的一個變體(名爲GraphicalHTTPClient ),我用它來測試API。我從磁盤成功加載的二進制文件,並使用幾乎相同的代碼到您的MIME類型'application/octet-stream'傳送它:

get :download do 
    data = File.open('binary_data').read 
    content_type 'application/octet-stream' 
    body data 
    end 

我建議您的問題是與API客戶機和/或字符編碼(由Stuart中號的建議)。儘管迄今爲止我發生的另一種可能性形成了我們的討論,但一些Rack中間件被錯誤地觸發,並且修改了Grape的輸出。

+0

感謝所有的回覆。我嘗試切換葡萄端點以返回與send_data相同的字符編碼;但我沒有看到任何響應機構的變化。我正在考慮切換ActionController和Grape端點代碼以返回Base64編碼的字符串,以保證兩種用例都具有相同的行爲。 – boboverflow

+0

我懷疑這裏的數據需要'force_encoding'。如果你可以在一個簡單的Grape應用程序中重現這一點,請將它放在Grape郵件列表中。 –

11

有問題#412#418已經報告給葡萄github頁面。 哪些與返回二進制文件並覆蓋內容類型有關。

要返回二進制格式,像這樣:

get '/download_file' do 
    content_type "application/octet-stream" 
    header['Content-Disposition'] = "attachment; filename=yourfilename" 
    env['api.format'] = :binary 
    File.open(your_file_path).read 
end 
+4

'env ['api.format'] =:binary'爲我做了這個 – adantj

+0

您也可能想使用'File.binread(your_file_path)'來保證安全。 –