為簡單起見,在實踐單檔案直傳過程中,將盡量使用程式語言的自帶函式,避免過度依賴第三方元件;同時為講解原理,也不會直接使用七牛官方Ruby-SDK,有需要的讀者可以自行研究。
■ 簽發上傳授權憑證
#!/usr/bin/env ruby
# encoding : utf-8
# upload_token.rb
require `json`
require `base64`
require `openssl`
# 根據傳入引數,構造一個上傳策略
def put_policy(bucket, expires)
# 生成一個Hash物件
put_policy = Hash.new()
# 僅指定目標儲存空間,即“新增資源”語意:
# 資源不存在則建立
# 資源已存在,且與上傳內容不一致則失敗
put_policy[`scope`] = "#{bucket}"
# 計算授權有效期截止時間,UNIX時間戳格式
put_policy[`deadline`] = (Time.now() + expires).tv_sec()
# 序列化為JSON字串
return JSON.generate(put_policy)
end # put_policy
# 根據傳入的上傳策略,生成對應的上傳授權憑證
def upload_token(access_key, secret_key, put_policy)
# 對上傳策略做UrlSafe-Base64編碼
encoded_put_policy = Base64.urlsafe_encode64(put_policy)
# 使用SHA1作為HASH函式,生成簽名
sign = OpenSSL::HMAC.digest(
`sha1`,
secret_key,
encoded_put_policy
)
# 對簽名做UrlSafe-Base64編碼
encoded_sign = Base64.urlsafe_encode64(sign)
# 拼出上傳授權憑證,以“:”作為分隔符
return "#{access_key}:#{encoded_sign}:#{encoded_put_policy}"
end # upload_token
#### 以下部分為測試程式碼 ####
BUCKET = `qiniu-ts-demo` # 使用時請更換成真實的儲存空間名
EXPIRES = 3600
pp = put_policy(BUCKET, EXPIRES)
ACCESS_KEY = `MY_ACCESS_KEY` # 使用時請更換成真實的AccessKey
SECRET_KEY = `MY_SECRET_KEY` # 使用時請更換成真實的SecretKey
token = upload_token(ACCESS_KEY, SECRET_KEY, pp)
puts pp
# 輸出示例:{"scope":"qiniu-ts-demo","deadline":1389772115}
puts token
# 輸出示例:MY_ACCESS_KEY:rgAZqUhj2ojVsXhgol27ck9XmO8=:eyJzY29wZSI6InFpbml1LXRzLWRlbW8iLCJkZWFkbGluZSI6MTM4OTc3MjExNX0=
■ 上傳檔案
#!/usr/bin/env ruby
# encoding : utf-8
# put_file.rb
require `json`
require `net/http`
require `./upload_token.rb`
BUCKET = `qiniu-ts-demo` # 使用時請更換成真實的儲存空間名
EXPIRES = 3600
ACCESS_KEY = `MY_ACCESS_KEY` # 使用時請更換成真實的AccessKey
SECRET_KEY = `MY_SECRET_KEY` # 使用時請更換成真實的SecretKey
# 生成上傳授權憑證
upload_token = upload_token(
ACCESS_KEY,
SECRET_KEY,
put_policy(BUCKET, EXPIRES)
)
# 指定請求報文中的各個引數
file_name = `test.txt`
file_content = <<TEXT
This is a test file for qiniu-ts-demo.
TEXT
boundary = `a-string-never-exists-in-the-uploading-file`
# 生成請求報文體
req_body = <<HTTP_BODY
--#{boundary}
Content-Disposition: form-data; name="token"
#{upload_token}
--#{boundary}
Content-Disposition: form-data; name="file"; filename="#{file_name}"
#{file_content}
--#{boundary}--
HTTP_BODY
# 轉換換行符
req_body.gsub!(/
/, "
")
# 生成Headers
req_headers = Hash.new()
req_headers[`Host`] = "up.qiniu.com"
req_headers[`Content-Type`] = "multipart/form-data; boundary=#{boundary}"
req_headers[`Content-Length`] = "#{req_body.length}"
# 傳送請求
http_client = Net::HTTP.new(`up.qiniu.com`, 80)
resp = http_client.post(
`/`,
req_body,
req_headers
)
# 解析響應
puts "HTTP Code=#{resp.code}"
puts "HTTP Msg=#{resp.msg}"
puts "HTTP Body=#{resp.body()}"
# 輸出示例:
# HTTP Code=200
# HTTP Msg=OK
# HTTP Body={"hash":"Ft4i6pVW8irlfIK_8KBHjSXA-4qM","key":"Ft4i6pVW8irlfIK_8KBHjSXA-4qM"}
200響應碼錶示上傳成功,伺服器返回資源內容的Hash值。因為上傳時沒有指定資源名,預設使用該Hash值作為資源名(Key)。
注意:在單檔案直傳介面中指定的FileName引數不會被當作資源名使用。
■ 驗證上傳結果
如何驗證檔案已經正確上傳了呢?可以構造下載URL,通過瀏覽器驗證。以上述Demo為例,根據下載URL構造規則:
http://<Bucket>.qiniudn.com/<Key>
可以得到對應的下載URL:
http://qiniu-ts-demo.qiniudn.com/Ft4i6pVW8irlfIK_8KBHjSXA-4qM
因為沒有為資源指定MIME型別,瀏覽器會將資源作為二進位制檔案下載,可以使用文字編輯器來驗證其內容。
■ 我們們行進到哪兒了?
通過簡單的Ruby程式設計,正確地上傳了一個文字檔案,且可以通過瀏覽器下載該檔案。
有了資源之後,可以進一步使用七牛雲端儲存提供的豐富的檔案雲處理功能。這部分內容將在後續文章中介紹。
七牛雲端儲存 © 2014 署名-非商業性使用-禁止演繹
允許自由轉載,請註明作者及出處。