七牛云试用指南-单文件直传(实践)

1607 查看

为简单起见,在实践单文件直传过程中,将尽量使用编程语言的自带函数,避免过度依赖第三方组件;同时为讲解原理,也不会直接使用七牛官方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!(/\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)。

注意:在单文件直传接口中指定的FileName参数不会被当作资源名使用。

■ 验证上传结果

如何验证文件已经正确上传了呢?可以构造下载URL,通过浏览器验证。以上述Demo为例,根据下载URL构造规则:

http://<Bucket>.qiniudn.com/<Key>

可以得到对应的下载URL:

http://qiniu-ts-demo.qiniudn.com/Ft4i6pVW8irlfIK_8KBHjSXA-4qM

因为没有为资源指定MIME类型,浏览器会将资源作为二进制文件下载,可以使用文本编辑器来验证其内容。

■ 咱们行进到哪儿了?

通过简单的Ruby编程,正确地上传了一个文本文件,且可以通过浏览器下载该文件。

有了资源之后,可以进一步使用七牛云存储提供的丰富的文件云处理功能。这部分内容将在后续文章中介绍。

上一篇 单文件直传(原理)

下一篇 文件下载

回目录


七牛云存储 © 2014 署名-非商业性使用-禁止演绎

允许自由转载,请注明作者及出处。