3

我在我的Rails應用程序中使用google-api-ruby-client與Google Drive進行交互。所有的基本功能,如列出文件夾中的文件,獲取,移動,複製和刪除文件,創建新文件夾等工作正常。Ruby:使用google-api-ruby-client SDK將文件上傳到Google驅動器Timeout :: Error

但是上傳新文件始終與超時失敗::錯誤

我收到要上傳的文件從我的網站(的multipart/form-data的)一個普通的文件上傳,這是我怎麼上傳到谷歌驅動器

result = nil 
new_file_obj = google_drive.files.insert.request_schema.new({ 
    'title' => file_name, 
    'mimeType' => file_mime_type, 
    'parents' => [{'id' => current_folder_id}] 
}) 

file_content = Google::APIClient::UploadIO.new(new_file.tempfile, file_mime_type, file_name) 

result = google_client.execute(
    api_method: google_drive.files.insert, 
    body_object: new_file_obj, 
    media: file_content, 
    parameters: { 
     'uploadType' => 'multipart', 
     'alt' => 'json' 
    } 
) 

這裏new_file是由客戶端上傳的文件。 new_file.tempfile給出Tempfile類型的對象。

execute方法永遠不會返回並最終得到一個Timeout :: Error異常。這是相關的堆棧跟蹤:

/lib/ruby/1.9.1/net/protocol.rb:140:in `rescue in rbuf_fill' 
/lib/ruby/1.9.1/net/protocol.rb:134:in `rbuf_fill' 
/lib/ruby/1.9.1/net/protocol.rb:116:in `readuntil' 
/lib/ruby/1.9.1/net/protocol.rb:126:in `readline' 
/lib/ruby/1.9.1/net/http.rb:2211:in `read_status_line' 
/lib/ruby/1.9.1/net/http.rb:2200:in `read_new' 
/lib/ruby/1.9.1/net/http.rb:1183:in `transport_request' 
/lib/ruby/1.9.1/net/http.rb:1169:in `request' 
/lib/ruby/1.9.1/net/http.rb:1162:in `block in request' 
/lib/ruby/1.9.1/net/http.rb:627:in `start' 
/lib/ruby/1.9.1/net/http.rb:1160:in `request' 
/lib/ruby/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/adapter/net_http.rb:74:in `perform_request' 
/lib/ruby/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/adapter/net_http.rb:37:in `call' 
/lib/ruby/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/request/url_encoded.rb:14:in `call' 
/lib/ruby/gems/1.9.1/gems/google-api-client-0.5.0/lib/google/api_client/request.rb:154:in `send' 
/lib/ruby/gems/1.9.1/gems/google-api-client-0.5.0/lib/google/api_client.rb:546:in `execute' 

我寫了這個代碼以下這裏的例子:https://developers.google.com/drive/examples/ruby#saving_new_files缺少什麼我在這裏?

我想上傳的文件是一個小的PNG圖像。該文件正常地傳到我的Web應用程序,因爲如果我將它寫入磁盤,我可以查看該文件。 Google服務器絕對不會停機,因爲我可以從drive.google.com上傳文件。這也意味着我的網絡足夠好。

那究竟是什麼造成超時?

解決這個相同的異常被提到增加read_timeout(http://stackoverflow.com/questions/10011387/rescue-in-rbuf-fill-timeouterror-timeouterror)。那是我應該做的嗎?如果是的話,我該如何使用google-api-ruby-client sdk在這裏做到這一點?

回答

-1

這個答案是錯誤的。 drive.install權限是不是需要上傳文件。

今天我嘗試上傳沒有drive.install建議@Steve Bazyl和它剛剛工作(即使沒有tmp_file.rewind調用)。

看起來問題是短暫的,因爲環境中沒有其他東西發生了變化。

原來問題在於權限不足。以前這些對於我是問用戶的權限作用域:

https://www.googleapis.com/auth/userinfo.email 
https://www.googleapis.com/auth/userinfo.profile 
https://www.googleapis.com/auth/drive 

凡爲谷歌驅動器需要的應用程序是installed它上傳代表用戶的文件。而對於應用程序是installed許可以下範圍也應當要求:https://www.googleapis.com/auth/drive.install

來源:

  1. How do I add/create/insert files to Google Drive through the API?(您不必列出Chrome商店的應用程序,因爲剛纔提到要求。對於drive.install權限就足夠了。一定要重新認證/重新授權所有用戶獲得新令牌)

  2. https://developers.google.com/drive/scopes#google_drive_scopes

然而 Timeout::Error還是有點異常的。可能Google服務器沒有在提供的令牌中看到沒有足夠的權限,並且沒有迴應錯誤消息。

P.S:如果有人解釋Timeout::Error,它將被接受爲正確的答案。

+1

它沒有必要具有使用該API的drive.install範圍。例如,如果您嘗試使用簡單命令行應用程序的快速入門示例,您會發現它沒有這個範圍就可以正常工作。 –

1

從一些快速的實驗中,可能只是tempfile文件沒有回捲閱讀。我修改了快速入門示例以從tempfile中讀取並能夠重現錯誤。例如:

tmp = Tempfile.new('foo') 
tmp.write("hello world") 

media = Google::APIClient::UploadIO.new(tmp, 'text/plain', 'foo.txt') 
file = drive.files.insert.request_schema.new({ 
    'title' => 'My document', 
    'description' => 'A test document', 
    'mimeType' => 'text/plain' 
}) 
result = client.execute(
    :api_method => drive.files.insert, 
    :body_object => file, 
    :media => media, 
    :parameters => { 
    'uploadType' => 'multipart', 
    'alt' => 'json'}) 

這將產生相同的堆棧跟蹤掛起約30秒左右後。但是,添加回調以重置臨時文件的調用使其工作正常

tmp = Tempfile.new('foo') 
tmp.write("hello world") 
tmp.rewind # Reset for reading... 

試試看看它是否修復了您的問題。

+0

你是部分正確的,即不需要drive.install。不過,我也不需要tmp_file.rewind。我刪除了舊的令牌,從Google驅動器中刪除了應用程序(基本上重置了所有內容),然後嘗試上傳,並且它工作正常! – brahmana

相關問題