From d1e60697c3079977f6ead3d56d3fc963c11bac7b Mon Sep 17 00:00:00 2001 From: 404 Date: Tue, 18 Dec 2012 10:57:16 +0800 Subject: [PATCH 1/6] disabled wm --- spec/qiniu/rs/eu_spec.rb | 2 ++ spec/qiniu/rs_spec.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/spec/qiniu/rs/eu_spec.rb b/spec/qiniu/rs/eu_spec.rb index ff7558e..979a276 100755 --- a/spec/qiniu/rs/eu_spec.rb +++ b/spec/qiniu/rs/eu_spec.rb @@ -41,6 +41,7 @@ module Qiniu result.should_not be_false end +=begin context ".set_watermark" do it "should works" do options = { @@ -59,6 +60,7 @@ module Qiniu puts data.inspect end end +=end end end diff --git a/spec/qiniu/rs_spec.rb b/spec/qiniu/rs_spec.rb index 1710fc4..17f169b 100755 --- a/spec/qiniu/rs_spec.rb +++ b/spec/qiniu/rs_spec.rb @@ -80,6 +80,7 @@ module Qiniu end end +=begin context ".set_watermark" do it "should works" do options = { @@ -98,6 +99,7 @@ module Qiniu puts result.inspect end end +=end context ".put_auth" do it "should works" do From 5b0a561cc1c49576816c90882a364407b773bc50 Mon Sep 17 00:00:00 2001 From: 404 Date: Wed, 19 Dec 2012 17:53:26 +0800 Subject: [PATCH 2/6] add Qiniu::RS.generate_download_token() --- CHANGELOG.md | 4 ++++ Gemfile.lock | 8 ++++---- README.md | 2 +- lib/qiniu/rs.rb | 12 ++++++++++- lib/qiniu/rs/up.rb | 7 ++++--- lib/qiniu/rs/version.rb | 4 ++-- lib/qiniu/tokens/download_token.rb | 33 ++++++++++++++++++++++++++++++ lib/qiniu/tokens/qbox_token.rb | 8 +++++--- lib/qiniu/tokens/upload_token.rb | 2 +- spec/qiniu/rs/io_spec.rb | 2 +- spec/qiniu/rs/rs_spec.rb | 2 +- spec/qiniu/rs/up_spec.rb | 2 +- spec/qiniu/rs_spec.rb | 21 ++++++++++++++++--- 13 files changed, 86 insertions(+), 21 deletions(-) create mode 100755 lib/qiniu/tokens/download_token.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 46a69b5..6bec2fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## CHANGE LOG +### v3.3.0 + +- 私有资源下载新版实现,添加 Qiniu::RS.generate_download_token() 方法。参考 [downloadToken](http://docs.qiniutek.com/v3/api/io/#get) + ### v3.2.2 fixed E701 error diff --git a/Gemfile.lock b/Gemfile.lock index 9c5d6a1..e93c190 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - qiniu-rs (3.2.2) + qiniu-rs (3.3.0) json (~> 1.7) mime-types (~> 1.19) rest-client (~> 1.6) @@ -14,15 +14,15 @@ GEM fakeweb (1.3.0) json (1.7.5) mime-types (1.19) - rake (10.0.2) + rake (10.0.3) rest-client (1.6.7) mime-types (>= 1.16) rspec (2.12.0) rspec-core (~> 2.12.0) rspec-expectations (~> 2.12.0) rspec-mocks (~> 2.12.0) - rspec-core (2.12.1) - rspec-expectations (2.12.0) + rspec-core (2.12.2) + rspec-expectations (2.12.1) diff-lcs (~> 1.1.3) rspec-mocks (2.12.0) ruby-hmac (0.4.0) diff --git a/README.md b/README.md index 1100b7c..17ec399 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Qiniu Resource (Cloud) Storage SDK for Ruby - [![Build Status](https://secure.travis-ci.org/why404/qiniu-rs-for-ruby.png?branch=master)](http://travis-ci.org/why404/qiniu-rs-for-ruby) [![Dependency Status](https://gemnasium.com/why404/qiniu-rs-for-ruby.png)](https://gemnasium.com/why404/qiniu-rs-for-ruby) +# Qiniu Resource (Cloud) Storage SDK for Ruby - [![Build Status](https://api.travis-ci.org/qiniu/ruby-sdk.png?branch=master)](https://travis-ci.org/qiniu/ruby-sdk) [![Dependency Status](https://gemnasium.com/why404/qiniu-rs-for-ruby.png)](https://gemnasium.com/why404/qiniu-rs-for-ruby) # 关于 diff --git a/lib/qiniu/rs.rb b/lib/qiniu/rs.rb index 4e18d09..fd58d19 100755 --- a/lib/qiniu/rs.rb +++ b/lib/qiniu/rs.rb @@ -17,6 +17,7 @@ module Qiniu autoload :AccessToken, 'qiniu/tokens/access_token' autoload :QboxToken, 'qiniu/tokens/qbox_token' autoload :UploadToken, 'qiniu/tokens/upload_token' + autoload :DownloadToken, 'qiniu/tokens/download_token' autoload :Abstract, 'qiniu/rs/abstract' class << self @@ -100,7 +101,7 @@ module Qiniu end def upload_file opts = {} - uncontained_opts = [:uptoken, :file, :bucket, :key] - opts.keys + uncontained_opts = [:uptoken, :file, :bucket, :key] - opts.keys raise MissingArgsError, uncontained_opts unless uncontained_opts.empty? source_file = opts[:file] @@ -232,6 +233,15 @@ module Qiniu token_obj.generate_token end + def generate_download_token(opts = {}) + token_obj = DownloadToken.new(opts) + token_obj.access_key = Config.settings[:access_key] + token_obj.secret_key = Config.settings[:secret_key] + #token_obj.expires_in = opts[:expires_in] + #token_obj.pattern = opts[:pattern] + token_obj.generate_token + end + end end diff --git a/lib/qiniu/rs/up.rb b/lib/qiniu/rs/up.rb index 98f8650..ec1663b 100755 --- a/lib/qiniu/rs/up.rb +++ b/lib/qiniu/rs/up.rb @@ -58,7 +58,7 @@ module Qiniu class TmpData def initialize(dir, filename) @tmpdir = Config.settings[:tmpdir] + File::SEPARATOR + dir - FileUtils.mkdir_p(@tmpdir) unless Dir.exists?(@tmpdir) + FileUtils.mkdir_p(@tmpdir) unless File.directory?(@tmpdir) @tmpfile = @tmpdir + File::SEPARATOR + filename end @@ -83,7 +83,7 @@ module Qiniu end def sweep! - FileUtils.rm_r(@tmpdir) if Dir.exists?(@tmpdir) + FileUtils.rm_r(@tmpdir) if File.directory?(@tmpdir) end end @@ -170,7 +170,7 @@ module Qiniu _call_binary_with_token(uptoken, url, body) end - def _resumable_put_block(uptoken, fh, block_index, block_size, chunk_size, progress, retry_times = 1, notifier) + def _resumable_put_block(uptoken, fh, block_index, block_size, chunk_size, progress, retry_times, notifier) code, data = 0, {} fpath = fh.path # this block has never been uploaded. @@ -318,6 +318,7 @@ module Qiniu end end + end end end diff --git a/lib/qiniu/rs/version.rb b/lib/qiniu/rs/version.rb index dc7e222..0e5cf34 100755 --- a/lib/qiniu/rs/version.rb +++ b/lib/qiniu/rs/version.rb @@ -4,8 +4,8 @@ module Qiniu module RS module Version MAJOR = 3 - MINOR = 2 - PATCH = 2 + MINOR = 3 + PATCH = 0 # Returns a version string by joining MAJOR, MINOR, and PATCH with '.' # # Example diff --git a/lib/qiniu/tokens/download_token.rb b/lib/qiniu/tokens/download_token.rb new file mode 100755 index 0000000..4bc5906 --- /dev/null +++ b/lib/qiniu/tokens/download_token.rb @@ -0,0 +1,33 @@ +# -*- encoding: utf-8 -*- + +require 'json' +require 'qiniu/tokens/access_token' +require 'qiniu/rs/utils' + +module Qiniu + module RS + class DownloadToken < AccessToken + + include Utils + + attr_accessor :pattern, :expires_in + + def initialize(opts = {}) + @pattern = opts[:pattern] || "*" + @expires_in = opts[:expires_in] || 3600 + end + + def generate_signature + params = {"S" => @pattern, "E" => Time.now.to_i + @expires_in} + Utils.urlsafe_base64_encode(params.to_json) + end + + def generate_token + signature = generate_signature + encoded_digest = generate_encoded_digest(signature) + %Q(#{@access_key}:#{encoded_digest}:#{signature}) + end + + end + end +end diff --git a/lib/qiniu/tokens/qbox_token.rb b/lib/qiniu/tokens/qbox_token.rb index 2073f7d..8ccdb0c 100755 --- a/lib/qiniu/tokens/qbox_token.rb +++ b/lib/qiniu/tokens/qbox_token.rb @@ -8,6 +8,8 @@ module Qiniu module RS class QboxToken < AccessToken + include Utils + attr_accessor :url, :params def initialize(opts = {}) @@ -20,10 +22,10 @@ module Qiniu signature = uri.path query_string = uri.query signature += '?' + query_string if !query_string.nil? && !query_string.empty? - signature += "\n"; + signature += "\n" if @params.is_a?(Hash) - total_param = @params.map { |key, value| %Q(#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s).gsub('+', '%20')}) } - signature += total_param.join("&") + params_string = Utils.generate_query_string(@params) + signature += params_string end signature end diff --git a/lib/qiniu/tokens/upload_token.rb b/lib/qiniu/tokens/upload_token.rb index bb13af4..24ea913 100755 --- a/lib/qiniu/tokens/upload_token.rb +++ b/lib/qiniu/tokens/upload_token.rb @@ -27,7 +27,7 @@ module Qiniu params[:callbackBodyType] = @callback_body_type if !@callback_body_type.nil? && !@callback_body_type.empty? params[:customer] = @customer if !@customer.nil? && !@customer.empty? params[:escape] = 1 if @escape == 1 || @escape == true - urlsafe_base64_encode(params.to_json) + Utils.urlsafe_base64_encode(params.to_json) end def generate_token diff --git a/spec/qiniu/rs/io_spec.rb b/spec/qiniu/rs/io_spec.rb index 70abd7f..9be4526 100755 --- a/spec/qiniu/rs/io_spec.rb +++ b/spec/qiniu/rs/io_spec.rb @@ -11,7 +11,7 @@ module Qiniu before :all do @bucket = "io_test_bucket" - @key = Digest::SHA1.hexdigest (Time.now.to_i+rand(100)).to_s + @key = Digest::SHA1.hexdigest((Time.now.to_i+rand(100)).to_s) result = Qiniu::RS.mkbucket(@bucket) puts result.inspect diff --git a/spec/qiniu/rs/rs_spec.rb b/spec/qiniu/rs/rs_spec.rb index 101916d..ca7ea91 100755 --- a/spec/qiniu/rs/rs_spec.rb +++ b/spec/qiniu/rs/rs_spec.rb @@ -12,7 +12,7 @@ module Qiniu before :all do @bucket = "rs_test_bucket" - @key = Digest::SHA1.hexdigest (Time.now.to_i+rand(100)).to_s + @key = Digest::SHA1.hexdigest((Time.now.to_i+rand(100)).to_s) @domain = 'rs-test-bucket.dn.qbox.me' code, data = Qiniu::RS::RS.mkbucket(@bucket) diff --git a/spec/qiniu/rs/up_spec.rb b/spec/qiniu/rs/up_spec.rb index 024d17b..259f1d8 100755 --- a/spec/qiniu/rs/up_spec.rb +++ b/spec/qiniu/rs/up_spec.rb @@ -11,7 +11,7 @@ module Qiniu before :all do @localfile = "bigfile.txt" - File.open(@localfile, "w"){|f| 5242888.times{f.write(Random.rand(9).to_s)}} + File.open(@localfile, "w"){|f| 5242888.times{f.write(rand(9).to_s)}} @bucket = "up_test_bucket" @key = Digest::SHA1.hexdigest(@localfile+Time.now.to_s) diff --git a/spec/qiniu/rs_spec.rb b/spec/qiniu/rs_spec.rb index 17f169b..1e7f87e 100755 --- a/spec/qiniu/rs_spec.rb +++ b/spec/qiniu/rs_spec.rb @@ -31,10 +31,13 @@ module Qiniu end after :all do - result = Qiniu::RS.drop(@bucket) - puts result.inspect + result = Qiniu::RS.unpublish(@domain) result.should_not be_false + result1 = Qiniu::RS.drop(@bucket) + puts result1.inspect + result1.should_not be_false + result2 = Qiniu::RS.drop(@test_image_bucket) puts result2.inspect result2.should_not be_false @@ -180,7 +183,7 @@ module Qiniu it "should works" do # generate bigfile for testing localfile = "test_bigfile" - File.open(localfile, "w"){|f| 5242888.times{f.write(Random.rand(9).to_s)}} + File.open(localfile, "w"){|f| 5242888.times{f.write(rand(9).to_s)}} key = Digest::SHA1.hexdigest(localfile+Time.now.to_s) # generate the upload token uptoken_opts = {:scope => @bucket, :expires_in => 3600, :customer => "awhy.xu@gmail.com", :escape => 0} @@ -281,12 +284,14 @@ module Qiniu end end +=begin context ".unpublish" do it "should works" do result = Qiniu::RS.unpublish(@domain) result.should_not be_false end end +=end context ".delete" do it "should works" do @@ -360,6 +365,16 @@ module Qiniu data = Qiniu::RS.generate_upload_token({:scope => 'test_bucket', :expires_in => 3600, :escape => 0}) data.should_not be_empty puts data.inspect + data.split(":").length.should == 3 + end + end + + context ".generate_download_token" do + it "should works" do + data = Qiniu::RS.generate_download_token({:expires_in => 1, :pattern => 'http://qiniu-rs-test.dn.qbox.me/*'}) + data.should_not be_empty + puts data.inspect + data.split(":").length.should == 3 end end From 957b5d14998534ff7729149f2fd5e305ad1e9dad Mon Sep 17 00:00:00 2001 From: 404 Date: Thu, 20 Dec 2012 17:16:17 +0800 Subject: [PATCH 3/6] docs updated --- docs/README.md | 177 +++++++++++++------------------------------------ 1 file changed, 45 insertions(+), 132 deletions(-) diff --git a/docs/README.md b/docs/README.md index 5421375..ff3b042 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,7 +6,7 @@ title: Ruby SDK 使用指南 | 七牛云存储 此 Ruby SDK 适用于 Ruby 1.8.x, 1.9.x, jruby, rbx, ree 版本,基于 [七牛云存储官方API](/v3/api/) 构建。使用此 SDK 构建您的网络应用程序,能让您以非常便捷地方式将数据安全地存储到七牛云存储上。无论您的网络应用是一个网站程序,还是包括从云端(服务端程序)到终端(手持设备应用)的架构的服务或应用,通过七牛云存储及其 SDK,都能让您应用程序的终端用户高速上传和下载,同时也让您的服务端更加轻盈。 -七牛云存储 Ruby SDK 源码地址:[https://github.com/qiniu/ruby-sdk](https://github.com/qiniu/ruby-sdk) +七牛云存储 Ruby SDK 源码地址: **文档大纲** @@ -18,20 +18,18 @@ title: Ruby SDK 使用指南 | 七牛云存储 - [获取用于上传文件的临时授权凭证](#generate-upload-token) - [服务端上传文件](#upload-server-side) - [断点续上传](#resumable-upload) - - [针对 NotFound 场景处理](#upload-file-for-not-found) - - [客户端直传文件](#upload-client-side) + - [自定义 404 NotFound 资源](#upload-file-for-not-found) + - [移动端/web端直传文件](#upload-client-side) + - [下载文件](#download) + - [公有资源下载](#download-public-files) + - [私有资源下载](#download-private-files) - [查看文件属性信息](#stat) - - [获取文件下载链接(含文件属性信息)](#get) - - [只获取文件下载链接](#download) - [删除指定文件](#delete) - [删除所有文件(单个 bucket)](#drop) - [批量操作](#batch) - - [批量获取文件属性信息(含下载链接)](#batch_get) - - [批量获取文件下载链接](#batch_download) + - [批量获取文件属性信息](#batch_get) - [批量删除文件](#batch_delete) - - [创建公开外链](#publish) - - [取消公开外链](#unpublish) - - [Bucket(资源表)管理](#buckets) + - [Bucket(空间)管理](#buckets) - [创建 Bucket](#mkbucket) - [列出所有 Bucket](#list-all-buckets) - [访问控制](#set-protected) @@ -250,7 +248,7 @@ title: Ruby SDK 使用指南 | 七牛云存储 -##### 针对 NotFound 场景处理 +##### 自定义 404 NotFound 资源 您可以上传一个应对 HTTP 404 出错处理的文件,当您 [创建公开外链](#publish) 后,若公开的外链找不到该文件,即可使用您上传的“自定义404文件”代替之。要这么做,您只须使用 `Qiniu::RS.upload_file` 函数上传一个 `key` 为固定字符串类型的值 `errno-404` 即可。 @@ -264,7 +262,7 @@ title: Ruby SDK 使用指南 | 七牛云存储 -#### 客户端直传文件 +#### 移动端/web端直传文件 客户端上传流程和服务端上传类似,差别在于:客户端直传文件所需的 `upload_token` 可以选择在客户方的业务服务器端生成,也可以选择在客户方的客户端程序里边生成。选择前者,可以和客户方的业务揉合得更紧密和安全些,比如防伪造请求。 @@ -275,6 +273,39 @@ title: Ruby SDK 使用指南 | 七牛云存储 如果您的网络程序是从云端(服务端程序)到终端(手持设备应用)的架构模型,且终端用户有使用您移动端App上传文件(比如照片或视频)的需求,可以把您服务器得到的此 `upload_token` 返回给手持设备端的App,然后您的移动 App 可以使用 [七牛云存储 Objective-SDK (iOS)](http://docs.qiniutek.com/v3/sdk/objc/) 或 [七牛云存储 Android-SDK](http://docs.qiniutek.com/v3/sdk/android/) 的相关上传函数或参照 [七牛云存储API之文件上传](http://docs.qiniutek.com/v3/api/io/#upload) 直传文件。这样,您的终端用户即可把数据(比如图片或视频)直接上传到七牛云存储服务器上无须经由您的服务端中转,而且在上传之前,七牛云存储做了智能加速,终端用户上传数据始终是离他物理距离最近的存储节点。当终端用户上传成功后,七牛云存储服务端会向您指定的 `callback_url` 发送回调数据。如果 `callback_url` 所在的服务处理完毕后输出 `JSON` 格式的数据,七牛云存储服务端会将该回调请求所得的响应信息原封不动地返回给终端应用程序。 + +### 下载文件 + +私有(private)是 bucket(空间) 的一个属性,一个私有 bucket 中的资源为私有资源,私有资源不可匿名下载。 + +新创建的bucket缺省为私有,也可以将某个bucket设为公有,公有bucket中的资源为公有资源,公有资源可以匿名下载。 + + +#### 公有资源下载 + + http://.qiniudn.com/ + +注意,尖括号不是必需,代表替换项。 + + +#### 私有资源下载 + +私有资源只能通过临时下载授权凭证(downloadToken)下载,下载链接格式如下: + + http://.qiniudn.com/?token= + +downloadToken 可以使用 SDK 提供的如下方法生成: + + Qiniu::RS.generate_download_token :expires_in => expires_in_seconds, + :pattern => download_url_patterns + +**参数** + +expires_in +: 可选,数字类型,用于设置上传 URL 的有效期,单位:秒,缺省为 3600 秒,即 1 小时后该上传链接不再有效。 + +pattern +: 可选,字符串类型,用于设置可匹配的下载链接。参考:[downloadToken pattern 详解](/v3/api/io/#download-token-pattern) @@ -315,66 +346,6 @@ mimeType putTime : 上传时间,单位是 百纳秒 - - -### 获取文件下载链接(含文件属性信息) - - Qiniu::RS.get(bucket, key, save_as = nil, expires_in = nil, version = nil) - -`Qiniu::RS.get` 函数除了能像 `Qiniu::RS.stat` 一样返回文件的属性信息外,还能返回具体的下载链接及其有效时间。 - -**参数** - -bucket -: 必须,字符串类型(String),类似传统数据库里边的表名称,我们暂且将其叫做“资源表”,每份数据是属性信息都存储到具体的 bucket(资源表)中 。 - -key -: 必须,字符串类型(String),类似传统数据库里边某个表的主键ID,每一个文件最终都用一个唯一 `key` 进行标示。 - -save_as -: 可选,字符串类型(String),文件下载时保存的具体名称 - -expires_in -: 可选,整型,用于设置下载 URL 的有效期,单位:秒,缺省为 3600 秒 - -version -: 可选,字符串类型(String),值为 `Qiniu::RS.stat` 或 `Qiniu::RS.get` 函数返回的 `hash` 字段的值,可用于断点续下载。 - -**返回值** - -如果请求失败,返回 `false`;否则返回如下一个 `Hash` 类型的结构: - - { - "fsize" => 3053, - "hash" => "Fu9lBSwQKbWNlBLActdx8-toAajv", - "mimeType" => "application/x-ruby", - "url" => "http://iovip.qbox.me/file/", - "expires" => 3600 - } - -fsize -: 表示文件总大小,单位是 Byte - -hash -: 文件的特征值,可以看做是基版本号 - -mimeType -: 文件的 mime-type - -url -: 文件的临时有效下载链接 - -expires -: 文件下载链接的有效期,单位为 秒,过了 `expires` 秒之后,下载 `url` 将不再有效 - - - -### 只获取文件下载链接 - - Qiniu::RS.download(bucket, key, save_as = nil, expires_in = nil, version = nil) - -`Qiniu::RS.download` 函数参数与 `Qiniu::RS.get` 一样,差别在于,`Qiniu::RS.download` 只返回文件的下载链接。 - ### 删除指定文件 @@ -451,7 +422,7 @@ keys -#### 批量获取文件属性信息(含下载链接) +#### 批量获取文件属性信息 Qiniu::RS.batch_get(bucket, keys) @@ -483,22 +454,6 @@ keys ... ] - - -#### 批量获取文件下载链接 - - Qiniu::RS.batch_download(bucket, keys) - -`Qiniu::RS.batch_download` 函数也是在 `Qiniu::RS.batch` 之上的封装,提供批量获取文件下载链接的功能。 - -参数同 `Qiniu::RS.batch_get` 的参数一样。 - -**返回值** - -如果请求失败,返回 `false`,否则返回一个 `Array` 类型的结构,其中每个元素是一个字符串类型的下载链接: - - ["", "", …, ""] - #### 批量删除文件 @@ -513,50 +468,9 @@ keys 如果批量删除成功,返回 `true` ,否则为 `false` 。 - - -### 创建公开外链 - - Qiniu::RS.publish(domain, bucket) - -调用 `Qiniu::RS.publish` 函数可以将您在七牛云存储中的资源表 `bucket` 发布到某个 `domain` 下,`domain` 需要在 DNS 管理里边 CNAME 到 `iovip.qbox.me` 。 - -这样,用户就可以通过 `http:///` 来访问资源表 `bucket` 中的文件。键值为 `foo/bar/file` 的文件对应访问 URL 为 `http:///foo/bar/file`。 另外,`domain` 可以是一个真实的域名,比如 `www.example.com`,也可以是七牛云存储的二级路径,比如 `iovip.qbox.me/example` 。 - -例如:执行 `Qiniu::RS.publish("cdn.example.com", "EXAMPLE_BUCKET")` 后,那么键名为 `foo/bar/file` 的文件可以通过 `http://cdn.example.com/foo/bar/file` 访问。 - -**参数** - -domain -: 必须,字符串类型(String),资源表发布的目标域名,例如:`cdn.example.com` - -bucket -: 必须,字符串类型(String),要公开发布的资源表名称。 - -**返回值** - -如果发布成功,返回 `true`,否则返回 `false` 。 - - - -### 取消公开外链 - - Qiniu::RS.unpublish(domain) - -可以通过 SDK 提供的 `Qiniu::RS.unpublish` 函数来取消指定 `bucket` 的在某个 `domain` 域下的所有公开外链访问。 - -**参数** - -domain -: 必须,字符串类型(String),资源表已发布的目标域名名称,例如:`cdn.example.com` - -**返回值** - -如果撤销成功,返回 `true`,否则返回 `false` 。 - -### Bucket(资源表)管理 +### Bucket(空间)管理 @@ -691,7 +605,6 @@ spec 返回一个字符串类型的缩略图 URL - #### 高级图像处理(缩略、裁剪、旋转、转化) From 06b019008a73eee215df77c24f2c1bd390b29376 Mon Sep 17 00:00:00 2001 From: 404 Date: Sun, 6 Jan 2013 11:07:12 +0800 Subject: [PATCH 4/6] fix encoding comments --- spec/qiniu/rs/io_spec.rb | 2 +- spec/qiniu/rs/up_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/qiniu/rs/io_spec.rb b/spec/qiniu/rs/io_spec.rb index 9be4526..05ce823 100755 --- a/spec/qiniu/rs/io_spec.rb +++ b/spec/qiniu/rs/io_spec.rb @@ -1,4 +1,4 @@ -# Utils.-*- encoding: utf-8 -*- +# -*- encoding: utf-8 -*- require 'spec_helper' require 'qiniu/rs/auth' diff --git a/spec/qiniu/rs/up_spec.rb b/spec/qiniu/rs/up_spec.rb index 259f1d8..28e6736 100755 --- a/spec/qiniu/rs/up_spec.rb +++ b/spec/qiniu/rs/up_spec.rb @@ -1,4 +1,4 @@ -# Utils.-*- encoding: utf-8 -*- +# -*- encoding: utf-8 -*- require 'digest/sha1' require 'spec_helper' From c3e2a3d44bd083d5093f165c23e8b03fdcfb2540 Mon Sep 17 00:00:00 2001 From: 404 Date: Sun, 6 Jan 2013 14:48:35 +0800 Subject: [PATCH 5/6] rewrite docs --- docs/README.md | 531 ++++++++++++------------------------------------- 1 file changed, 131 insertions(+), 400 deletions(-) diff --git a/docs/README.md b/docs/README.md index ff3b042..8862c2b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,54 +8,51 @@ title: Ruby SDK 使用指南 | 七牛云存储 七牛云存储 Ruby SDK 源码地址: -**文档大纲** +**目录** - [安装](#Installation) +- [接入](#turn-on) + - [配置密钥(AccessKey / SecretKey)](#establish_connection!) + - [针对 Ruby On Rails 网站应用初始化设置](#ror-init) - [使用](#Usage) - - [应用接入](#establish_connection!) - - [Ruby On Rails 应用初始化设置](#ror-init) - - [上传文件](#upload) - - [获取用于上传文件的临时授权凭证](#generate-upload-token) - - [服务端上传文件](#upload-server-side) - - [断点续上传](#resumable-upload) - - [自定义 404 NotFound 资源](#upload-file-for-not-found) - - [移动端/web端直传文件](#upload-client-side) - - [下载文件](#download) + - [文件上传](#upload) + - [生成上传授权凭证(uploadToken)](#generate-upload-token) + - [Ruby 服务端上传文件](#upload-server-side) + - [开启断点续上传](#resumable-upload) + - [iOS / Android / Web 端直传文件说明](#upload-client-side) + - [文件下载](#download) - [公有资源下载](#download-public-files) - [私有资源下载](#download-private-files) - - [查看文件属性信息](#stat) - - [删除指定文件](#delete) - - [删除所有文件(单个 bucket)](#drop) - - [批量操作](#batch) - - [批量获取文件属性信息](#batch_get) - - [批量删除文件](#batch_delete) - - [Bucket(空间)管理](#buckets) - - [创建 Bucket](#mkbucket) - - [列出所有 Bucket](#list-all-buckets) - - [访问控制](#set-protected) - - [图像处理](#op-image) - - [查看图片属性信息](#image_info) - - [查看图片EXIF信息](#image_exif) - - [获取指定规格的缩略图预览地址](#image_preview_url) - - [高级图像处理(缩略、裁剪、旋转、转化)](#image_mogrify_preview_url) - - [高级图像处理(缩略、裁剪、旋转、转化)并持久化](#image_mogrify_save_as) - - [高级图像处理(水印)](#image-watermarking) - - [水印准备工作](#watermarking-pre-work) - - [设置原图保护](#watermarking-set-protected) - - [设置水印预览图URL分隔符](#watermarking-set-sep) - - [设置水印预览图规格别名](#watermarking-set-style) - - [设置水印模板](#watermarking-set-template) - - [获取水印模板](#watermarking-get-template) - + - [生成下载授权凭证(downloadToken)](#download-token) + - [高级特性](#other-download-features) + - [断点续下载](#resumable-download) + - [自定义 404 NotFound](#upload-file-for-not-found) + - [文件管理](#file-management) + - [查看单个文件属性信息](#stat) + - [复制单个文件](#copy) + - [移动单个文件](#move) + - [删除单个文件](#delete) + - [批量操作](#batch) + - [批量获取文件属性信息](#batch-get) + - [批量复制文件](#batch-copy) + - [批量移动文件](#batch-move) + - [批量删除文件](#batch-delete) + - [云处理](#cloud-processing) + - [图像](#image-processing) + - [查看图片属性信息](#image-info) + - [查看图片EXIF信息](#image-exif) + - [图像在线处理(缩略、裁剪、旋转、转化)](#image-mogrify-for-preview) + - [图像在线处理(缩略、裁剪、旋转、转化)后并持久化存储](#image-mogrify-for-save-as) + - 音频(TODO) + - 视频(TODO) - [贡献代码](#Contributing) - [许可证](#License) + ## 安装 - - 在您 Ruby 应用程序的 `Gemfile` 文件中,添加如下一行代码: gem 'qiniu-rs' @@ -69,11 +66,13 @@ title: Ruby SDK 使用指南 | 七牛云存储 $ gem install qiniu-rs -## 使用 + + +## 接入 -### 应用接入 +### 配置密钥(AccessKey / SecretKey) 要接入七牛云存储,您需要拥有一对有效的 Access Key 和 Secret Key 用来进行签名认证。可以通过如下步骤获得: @@ -87,7 +86,7 @@ title: Ruby SDK 使用指南 | 七牛云存储 -### Ruby On Rails 应用初始化设置 +### 针对 Ruby On Rails 网站应用初始化设置 如果您使用的是 [Ruby on Rails](http://rubyonrails.org/) 框架,我们建议您在应用初始化启动的过程中,依次调用上述两个函数即可,操作如下: @@ -102,13 +101,20 @@ title: Ruby SDK 使用指南 | 七牛云存储 接下来,我们会逐一介绍此 SDK 提供的其他方法。 + + + +## 使用 + -### 上传文件 +### 文件上传 + +**注意**:如果您只是想要上传已存在您电脑本地或者是服务器上的文件到七牛云存储,可以直接使用七牛提供的 [qrsync](/v3/tools/qrsync/) 上传工具。如果是需要通过您的网站或是移动应用(App)上传文件,则可以接入使用此 SDK,详情参考如下文档说明。 -#### 获取用于上传文件的临时授权凭证 +#### 生成上传授权凭证(uploadToken) 要上传一个文件,首先需要调用 SDK 提供的 `Qiniu::RS.generate_upload_token` 函数来获取一个经过授权用于临时匿名上传的 `upload_token`——经过数字签名的一组数据信息,该 `upload_token` 作为文件上传流中 `multipart/form-data` 的一部分进行传输。 @@ -157,7 +163,7 @@ title: Ruby SDK 使用指南 | 七牛云存储 -#### 服务端上传文件 +#### Ruby 服务端上传文件 通过 `Qiniu::RS.upload_file()` 方法可在客户方的业务服务器上直接往七牛云存储上传文件。该函数规格如下: @@ -210,7 +216,7 @@ title: Ruby SDK 使用指南 | 七牛云存储 -##### 断点续上传 +##### 开启断点续上传 无需任何额外改动,SDK 提供的 `Qiniu::RS.upload_file()` 方法缺省支持断点续上传。默认情况下,SDK 会自动启用断点续上传的方式来上传超过 4MB 大小的文件。您也可以在 [应用接入](/v3/sdk/ruby/#establish_connection!) 时通过修改缺省配置来设置该阀值: @@ -246,55 +252,63 @@ title: Ruby SDK 使用指南 | 七牛云存储 : 整型,指定每次 http 若请求失败最多可以重试的次数,缺省为3次。该参数 SDK 全局有效。 - - -##### 自定义 404 NotFound 资源 - -您可以上传一个应对 HTTP 404 出错处理的文件,当您 [创建公开外链](#publish) 后,若公开的外链找不到该文件,即可使用您上传的“自定义404文件”代替之。要这么做,您只须使用 `Qiniu::RS.upload_file` 函数上传一个 `key` 为固定字符串类型的值 `errno-404` 即可。 - -除了使用 SDK 提供的方法,同样也可以借助七牛云存储提供的命令行辅助工具 [qboxrsctl](https://github.com/qiniu/devtools/tags) 达到同样的目的: - - qboxrsctl put - -将其中的 `` 换作 `errno-404` 即可。 - -注意,每个 `` 里边有且只有一个 `errno-404` 文件,上传多个,最后的那一个会覆盖前面所有的。 - -#### 移动端/web端直传文件 +#### iOS / Android / Web 端直传文件说明 -客户端上传流程和服务端上传类似,差别在于:客户端直传文件所需的 `upload_token` 可以选择在客户方的业务服务器端生成,也可以选择在客户方的客户端程序里边生成。选择前者,可以和客户方的业务揉合得更紧密和安全些,比如防伪造请求。 +客户端 iOS / Android / Web 上传流程和服务端上传类似,差别在于:客户端直传文件所需的 `uploadToken` 选择在客户方的业务服务器端生成,然后将其生成的 `uploadToken` 颁发给客户端。 -简单来讲,客户端上传流程也分为两步: +简单来讲,客户端上传流程分为两步: -1. 获取 `upload_token`([用于上传文件的临时授权凭证](#generate-upload-token)) -2. 将该 `upload_token` 作为文件上传流 `multipart/form-data` 中的一部分实现上传操作 +1. [服务端生成上传授权凭证(uploadToken)](#generate-upload-token) +2. 客户端程序调用 [iOS](/v3/sdk/objc/) / [Android](/v3/sdk/android/) SDK 的文件上传方法进行上传 + +如果是网页直传文件到七牛云存储,网页可以使用 JavaScript 动态实现 [七牛云存储上传API](/v3/api/io/#upload-file-by-html-form)。 + +通过客户端直传文件,您的终端用户即可把数据(比如图片或视频)直接上传到七牛云存储服务器上,而无须经由您的服务端中转,终端用户上传数据始终是离他物理距离最近的七牛存储节点。当终端用户上传成功后,七牛云存储服务端会向您指定的 `callback_url` (一般在 [uploadToken](#generate-upload-token) 里边指定)发送回调数据(回调数据在客户端程序里边指定)。如果 `callback_url` 所指向的服务端处理完毕后输出 `JSON` 格式的数据,七牛云存储服务端会将该回调请求所得的 JSON 响应信息原封不动地返回给客户端应用程序。 -如果您的网络程序是从云端(服务端程序)到终端(手持设备应用)的架构模型,且终端用户有使用您移动端App上传文件(比如照片或视频)的需求,可以把您服务器得到的此 `upload_token` 返回给手持设备端的App,然后您的移动 App 可以使用 [七牛云存储 Objective-SDK (iOS)](http://docs.qiniutek.com/v3/sdk/objc/) 或 [七牛云存储 Android-SDK](http://docs.qiniutek.com/v3/sdk/android/) 的相关上传函数或参照 [七牛云存储API之文件上传](http://docs.qiniutek.com/v3/api/io/#upload) 直传文件。这样,您的终端用户即可把数据(比如图片或视频)直接上传到七牛云存储服务器上无须经由您的服务端中转,而且在上传之前,七牛云存储做了智能加速,终端用户上传数据始终是离他物理距离最近的存储节点。当终端用户上传成功后,七牛云存储服务端会向您指定的 `callback_url` 发送回调数据。如果 `callback_url` 所在的服务处理完毕后输出 `JSON` 格式的数据,七牛云存储服务端会将该回调请求所得的响应信息原封不动地返回给终端应用程序。 -### 下载文件 -私有(private)是 bucket(空间) 的一个属性,一个私有 bucket 中的资源为私有资源,私有资源不可匿名下载。 +### 文件下载 -新创建的bucket缺省为私有,也可以将某个bucket设为公有,公有bucket中的资源为公有资源,公有资源可以匿名下载。 +七牛云存储上的资源下载分为 [公有资源下载](#download-public-files) 和 [私有资源下载](#download-private-files) 。 + +私有(private)是 Bucket(空间)的一个属性,一个私有 Bucket 中的资源为私有资源,私有资源不可匿名下载。 + +新创建的空间(Bucket)缺省为私有,也可以将某个 Bucket 设为公有,公有 Bucket 中的资源为公有资源,公有资源可以匿名下载。 + #### 公有资源下载 - http://.qiniudn.com/ + [GET] http://.qiniudn.com/ + +或者, + + [GET] http://<绑定域名>/ + +绑定域名可以是自定义域名,可以在 [七牛云存储开发者自助网站](https://dev.qiniutek.com/buckets) 进行域名绑定操作。 注意,尖括号不是必需,代表替换项。 + #### 私有资源下载 私有资源只能通过临时下载授权凭证(downloadToken)下载,下载链接格式如下: - http://.qiniudn.com/?token= + [GET] http://.qiniudn.com/?token= -downloadToken 可以使用 SDK 提供的如下方法生成: +或者, + + [GET] http://<绑定域名>/?token= + + + +##### 生成下载授权凭证(downloadToken) + +`` 可以使用 SDK 提供的如下方法生成: Qiniu::RS.generate_download_token :expires_in => expires_in_seconds, :pattern => download_url_patterns @@ -307,9 +321,41 @@ expires_in pattern : 可选,字符串类型,用于设置可匹配的下载链接。参考:[downloadToken pattern 详解](/v3/api/io/#download-token-pattern) + + + +#### 高级特性 + + + +##### 断点续下载 + +七牛云存储支持标准的断点续下载,参考:[云存储API之断点续下载](/v3/api/io/#download-by-range-bytes) + + + +##### 自定义 404 NotFound + +您可以上传一个应对 HTTP 404 出错处理的文件,当用户访问一个不存在的文件时,即可使用您上传的“自定义404文件”代替之。要这么做,您只须使用 `Qiniu::RS.upload_file` 函数上传一个 `key` 为固定字符串类型的值 `errno-404` 即可。 + +除了使用 SDK 提供的方法,同样也可以借助七牛云存储提供的命令行辅助工具 [qboxrsctl](/v3/tools/qboxrsctl/) 达到同样的目的: + + qboxrsctl put + +将其中的 `` 换作 `errno-404` 即可。 + +注意,每个 `` 里边有且只有一个 `errno-404` 文件,上传多个,最后的那一个会覆盖前面所有的。 + + + + +### 文件管理 + +文件管理包括对存储在七牛云存储上的文件进行查看、复制、移动和删除处理。 + -### 查看文件属性信息 +#### 查看单个文件属性信息 Qiniu::RS.stat(bucket, key) @@ -348,7 +394,7 @@ putTime -### 删除指定文件 +### 删除单个文件 Qiniu::RS.delete(bucket, key) @@ -366,22 +412,6 @@ key 如果删除成功,返回 `true`,否则返回 `false` 。 - - -### 删除所有文件(单个 bucket) - - Qiniu::RS.drop(bucket) - -`Qiniu::RS.drop` 提供了删除整个 `bucket` 及其里边的所有 `key`,以及这些 `key` 关联的所有文件都将被删除。 - -**参数** - -bucket -: 必须,字符串类型(String),类似传统数据库里边的表名称,我们暂且将其叫做“资源表”,每份数据是属性信息都存储到具体的 bucket(资源表)中 。 - -**返回值** - -如果删除成功,返回 `true`,否则返回 `false` 。 @@ -420,7 +450,7 @@ keys ... ] - + #### 批量获取文件属性信息 @@ -454,7 +484,7 @@ keys ... ] - + #### 批量删除文件 @@ -468,71 +498,18 @@ keys 如果批量删除成功,返回 `true` ,否则为 `false` 。 - -### Bucket(空间)管理 + - +### 云处理 -#### 创建 Bucket + - Qiniu::RS.mkbucket(bucket_name) +#### 图像 -可以通过 SDK 提供的 `Qiniu::RS.mkbucket` 函数创建一个 bucket(资源表)。 + -**参数** - -bucket_name -: 必须,字符串类型(String),资源表 bucket 的名称。 - -**返回值** - -如果指定 bucket 创建成功,返回 `true`,否则返回 `false` 。 - - - -#### 列出所有 Bucket - - Qiniu::RS.buckets - -可以通过 SDK 提供的 `Qiniu::RS.buckets` 函数列出当前登录客户的所有 buckets(资源表)。 - -**返回值** - -如果请求成功,返回一个 buckets 的列表(Array),否则返回 `false` 。 - - ["Bucket1", "Bucket2", …, "BucketN"] - - - -#### 访问控制 - - Qiniu::RS.set_protected(bucket_name, protected_mode) - -可以通过 SDK 提供的 `Qiniu::RS.set_protected` 函数来设置指定 bucket 的访问属性,一般在水印处理时作原图保护用。 - -**参数** - -bucket_name -: 必须,字符串类型(String),指定资源表 bucket 的名称。 - -protected_mode -: 必须,整型,值为 1 或者 0,值为 1 表示启用保护模式,反之亦然。 - -该函数不常用,一般在特殊场景下会用到。比如给图片打水印时,首先要设置原图保护,禁用公开的图像处理操作,采用水印的特殊图像处理,而保护原图就可以通过该函数操作实现。 - -**返回值** - -如果设置成功,返回 `true`,否则返回 `false` 。 - - - - -### 图像处理 - - - -#### 查看图片属性信息 +##### 查看图片属性信息 Qiniu::RS.image_info(url) @@ -566,9 +543,9 @@ height colorModel : 原始图片着色模式 - + -#### 查看图片EXIF信息 +##### 查看图片EXIF信息 Qiniu::RS.image_exif(url) @@ -583,31 +560,9 @@ url 如果参数 `url` 所代表的图片没有 EXIF 信息,返回 `false`。否则,返回一个包含 EXIF 信息的 Hash 结构。 + - - -#### 获取指定规格的缩略图预览地址 - - Qiniu::RS.image_preview_url(url, spec) - -使用 SDK 提供的 `Qiniu::RS.image_preview_url` 方法,可以基于一张存储于七牛云存储服务器上的图片,针对其下载链接,以及指定的缩略图规格类型,来获取该张图片的缩略图地址。 - -**参数** - -url -: 必须,字符串类型(String),图片的下载链接,需是 `Qiniu::RS.get`(或`Qiniu::RS.batch_get`)函数返回值中 `url` 字段的值,或者是 `Qiniu::RS.download`(或`Qiniu::RS.batch_download`)函数返回的下载链接。且文件本身必须是图片。 - -spec -: 可选,字符串或整型的枚举值,指定缩略图的具体规格,参考 [七牛云存储API之缩略图预览](/v3/api/foimg/#fo-imagePreview) 和 [自定义缩略图规格](/v3/api/foimg/#fo-imagePreviewEx) 。该值缺省为 0 (即输出宽800px高600px图片质量为85的缩略图) - -**返回值** - -返回一个字符串类型的缩略图 URL - - - - -#### 高级图像处理(缩略、裁剪、旋转、转化) +##### 图像在线处理(缩略、裁剪、旋转、转化) `Qiniu::RS.image_mogrify_preview_url()` 方法支持将一个存储在七牛云存储的图片进行缩略、裁剪、旋转和格式转化处理,该方法返回一个可以直接预览缩略图的URL。 @@ -639,10 +594,9 @@ mogrify_options 返回一个可以预览最终缩略图的URL,String 类型。 + - - -#### 高级图像处理(缩略、裁剪、旋转、转化)并持久化存储处理结果 +#### 图像在线处理(缩略、裁剪、旋转、转化)后并持久化存储 `Qiniu::RS.image_mogrify_save_as()` 方法支持将一个存储在七牛云存储的图片进行缩略、裁剪、旋转和格式转化处理,并且将处理后的缩略图作为一个新文件持久化存储到七牛云存储服务器上,这样就可以供后续直接使用而不用每次都传入参数进行图像处理。 @@ -713,229 +667,6 @@ mogrify_options end - - -## 高级图像处理(水印) - - - -### 水印准备工作 - -为了保护用户原图和方便用户访问打过水印之后的图片,在经水印作用之前,需进行以下一些设置: - -1. [设置原图保护](#watermarking-set-protected) -2. [设置水印预览图URL分隔符](#watermarking-set-sep) -3. [设置水印预览图规格别名](#watermarking-set-style) - - - -#### 1. 设置原图保护 - -用户的图片打上水印后,其原图不可见。通过给原图所在的 Bucket(资源表)设置访问控制,可以达到保护原图的目的,详情请参考 [Bucket(资源表)管理之访问控制](set-protected)。 - -设置原图保护也可以借助七牛云存储提供的命令行辅助工具 [qboxrsctl](https://github.com/qiniu/devtools/tags) 来实现: - - // 为下面的所有图片设置原图保护 - qboxrsctl protected - - - -#### 2. 设置水印预览图URL分隔符 - -没有设置水印前,用户可以通过如下公开链接的形式访问原图([创建公开外链后的情况下](/v3/api/io/#rs-Publish)): - - http:/// - -设置水印后,其原图属性为私有,不能再通过这种形式访问。但是用户可以在原图的 `` 后面加上“分隔符”,以及相应的水印风格样式来访问打水印后的图片。例如,假设您为用户设定的访问水印图的分隔符为中划线 “-”,那么用户可以通过这种形式来访问打水印后的图片: - - http:///-/imageView//w//h//q//format//sharpen//watermark/ - -其中,`HasWatermark` 参数为 `0` (或者没有)表示不打水印,为 `1` 表示给图片打水印。 - -通过 SDK 提供的 `Qiniu::RS.set_separator` 函数可以设置水印预览图URL分隔符: - - Qiniu::RS.set_separator(bucket_name, separator) - -**参数** - -bucket_name -: 必须,字符串类型(String),图片所在的 Bucket(资源表) 名称 - -separator -: 必须,字符串类型(String),源图片与预览图规格之间的分割符 - -**返回值** - -操作成功返回 `true`,否则返回 `false`。 - -除了使用 SDK 提供的方法,同样可以借助七牛云存储提供的命令行辅助工具 [qboxrsctl](https://github.com/qiniu/devtools/tags) 达到同样的目的: - - // 设置预览图分隔符 - qboxrsctl separator - - - -#### 3. 设置水印预览图规格别名 - -通过步骤2中所描述的水印预览图 URL 来访问打水印后的图片毕竟较为繁琐,因此可以通过为该水印预览图规格设置“别名”的形式来访问。如: - -别名(Name) | 规格(Style) | 说明 ------------ | ------------ | ------- -small.jpg | imageView/0/w/120/h/90 | 大小为 120x90,不打水印 -middle.jpg | imageView/0/w/440/h/330/watermark/1 | 大小为 440x330,打水印 -large.jpg | imageView/0/w/1280/h/760/watermark/1 | 大小为 1280x760,打水印 - - -SDK 提供了 `Qiniu::RS.set_style` 函数可以定义预览图规格别名,该函数原型如下: - - Qiniu::RS.set_style(bucket, name, style) - -**参数** - -bucket -: 必须,字符串类型(String),图片所在的 Bucket(资源表) 名称 - -name -: 必须,字符串类型(String),预览图规格名称(别名) - -style -: 必须,字符串类型(String),具体的规格样式 - -**返回值** - -操作成功返回 `true`,否则返回 `false` 。 - -除了使用 SDK 提供的方法,同样也可以借助七牛云存储提供的命令行辅助工具 [qboxrsctl](https://github.com/qiniu/devtools/tags) 达到同样的目的: - - // 为 下面的所有图片设置名为