七牛雲試用指南-單檔案直傳(實踐)

無鋒之刃發表於2019-02-16

為簡單起見,在實踐單檔案直傳過程中,將盡量使用程式語言的自帶函式,避免過度依賴第三方元件;同時為講解原理,也不會直接使用七牛官方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 署名-非商業性使用-禁止演繹

允許自由轉載,請註明作者及出處。

相關文章