爲簡單起見,在實踐單文件直傳過程當中,將盡可能使用編程語言的自帶函數,避免過分依賴第三方組件;同時爲講解原理,也不會直接使用七牛官方Ruby-SDK,有須要的讀者能夠自行研究。html
#!/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!(/\n/, "\r\n") # 生成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)。git
注意:在單文件直傳接口中指定的FileName參數不會被看成資源名使用。github
如何驗證文件已經正確上傳了呢?能夠構造下載URL,經過瀏覽器驗證。以上述Demo爲例,根據下載URL構造規則:編程
http://<Bucket>.qiniudn.com/<Key>
能夠獲得對應的下載URL:json
http://qiniu-ts-demo.qiniudn.com/Ft4i6pVW8irlfIK_8KBHjSXA-4qMsegmentfault
由於沒有爲資源指定MIME類型,瀏覽器會將資源做爲二進制文件下載,可使用文本編輯器來驗證其內容。瀏覽器
經過簡單的Ruby編程,正確地上傳了一個文本文件,且能夠經過瀏覽器下載該文件。七牛雲存儲
有了資源以後,能夠進一步使用七牛雲存儲提供的豐富的文件雲處理功能。這部份內容將在後續文章中介紹。ruby
七牛雲存儲 © 2014 署名-非商業性使用-禁止演繹
容許自由轉載,請註明做者及出處。