baidubce-sdk 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fcf25bb36811b26a3d31ee13e740ddab94214d91
4
+ data.tar.gz: 56d9ab32198c87d3121ef9aec564047a24e157d6
5
+ SHA512:
6
+ metadata.gz: 6b4caffe3a7384402d7ea0fcf203c638aaee588d5ab4e5a2b21f168babcf792c9e7ccaaef9c055612df048261662296a8a4739da016594e2a61da216589e45fb
7
+ data.tar.gz: 79e634982aab61ba9f75b8bda7af86d5b2d5a4cde6c28b8edfd502a887726b2bb7ea1e30a0b1e2156be9b3b71e030b1ef65756c7c86ff0f1bda60b70f7a7e3b9
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.0.0
5
+ before_install: gem install bundler -v 1.15.4
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at xiaoyong@baidu.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in baidubce-sdk.gemspec
6
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,177 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
@@ -0,0 +1,1266 @@
1
+ # BOS Ruby SDK文档
2
+
3
+ # 概述
4
+
5
+ 本文档主要介绍BOS Ruby SDK的安装和使用。在使用本文档前,您需要先了解BOS的一些基本知识,并已开通了BOS服务。若您还不了解BOS,可以参考[产品描述](ProductDescription.html)和[入门指南](GettingStarted-new.html)。
6
+
7
+ # 安装SDK工具包
8
+
9
+ ## 运行环境
10
+
11
+ Ruby SDK包要求运行环境至少为Ruby 2.0 版本。
12
+
13
+ ## 安装SDK
14
+
15
+ ### 方式一:通过gem安装
16
+
17
+ ```gem install baidubce-sdk```
18
+
19
+ ### 方式二:通过bundler安装
20
+
21
+ 1. 首先得确认安装了bundler,安装命令:```gem install bundler```
22
+ 2. 在你的应用程序的Gemfile中添加:```gem 'baidubce-sdk', '~> 0.9.0'```,再运行```bundle install```
23
+
24
+ > **说明:** 用户在安装好gem之后,可以输入irb进入Ruby交互式命令行,输入```require 'baidubce/services/bos/bos_client'```,如果显示"true"则SDK已经顺利安装。[github源码链接](https://github.com/baidubce/bce-sdk-ruby)
25
+
26
+ **SDK目录结构**
27
+
28
+ ```
29
+ │──baidubce-sdk.gemspec //依赖的第三方gem
30
+ ├──lib
31
+ │   └── baidubce
32
+ │   ├── auth //BCE签名相关
33
+ │   ├── http //BCE的http通信相关
34
+ │   ├── services
35
+ │   │   └── bos //BOS主目录
36
+ │   │      ├── bos_client.rb //BOS操作类,所有操作可以通过BosClient类可以完成
37
+ │   │      ├── bos_constants.rb //BOS常量
38
+ │   │   └── sts //STS主目录
39
+ │   │ ├── sts_client.rb //STS操作类
40
+ │ ├── exception.rb //BCE客户端的异常
41
+ │ ├── retry_policy.rb //BCE客户端重试机制
42
+ │ ├── bce_base_client.rb //BCE公用客户端
43
+ │   └── utils //BCE公用工具
44
+ └──samples //使用示例
45
+ ```
46
+
47
+ ## 卸载SDK
48
+
49
+ 卸载SDK时,执行```gem uninstall baidubce-sdk```,删除脚本中require和include语句即可。
50
+
51
+ # 初始化
52
+
53
+ ## 确认Endpoint
54
+
55
+ - 在确认您使用SDK时配置的Endpoint时,可先阅读开发人员指南中关于[BOS访问域名](https://cloud.baidu.com/doc/BOS/DevRef.html#BOS.E8.AE.BF.E9.97.AE.E5.9F.9F.E5.90.8D)的部分,理解Endpoint相关的概念。
56
+
57
+ - 百度云目前开放了多区域支持,请参考[区域选择说明](../Reference/Regions.html)。
58
+
59
+ - 目前支持“华北-北京”、“华南-广州”和“华东-苏州”三个区域。北京区域:`http://bj.bcebos.com`,广州区域:`http://gz.bcebos.com`,苏州区域:`http://su.bcebos.com`。
60
+
61
+ 对应信息为:
62
+
63
+ | 访问区域 | 对应Endpoint |
64
+ | -------- | ------------- |
65
+ | BJ | bj.bcebos.com |
66
+ | GZ | gz.bcebos.com |
67
+ | SU | su.bcebos.com |
68
+
69
+ ## 获取密钥
70
+
71
+ 要使用百度云BOS,您需要拥有一个有效的 AK(Access Key ID)和SK(Secret Access Key)用来进行签名认证。AK/SK是由系统分配给用户的,均为字符串,用于标识用户,为访问BOS做签名验证。
72
+
73
+ 可以通过如下步骤获得并了解您的AK/SK信息:
74
+
75
+ 1. [注册百度云账号](https://login.bce.baidu.com/reg.html?tpl=bceplat&from=portal)
76
+ 2. [创建AK/SK](https://console.bce.baidu.com/iam/?_=1513940574695#/iam/accesslist)
77
+
78
+ ## 新建BosClient
79
+
80
+ BosClient是BOS服务的客户端,为开发者与BOS服务进行交互提供了一系列的方法。
81
+
82
+ ### 使用AK/SK新建BosClient
83
+
84
+ 通过AK/SK方式访问BOS,用户可以参考如下代码新建一个BosClient:
85
+
86
+ ```
87
+ #使用Ruby SDK,引入bos_client和Baidubce模块
88
+ require 'baidubce/services/bos/bos_client'
89
+ include Baidubce
90
+
91
+ #配置client参数
92
+ credentials = Auth::BceCredentials.new(
93
+ "accessKeyId",
94
+ "secretAccessKey"
95
+ )
96
+
97
+ conf = BceClientConfiguration.new(
98
+ credentials,
99
+ "ENDPOINT"
100
+ )
101
+ #新建BosClient
102
+ client = Services::BosClient.new(conf)
103
+ ```
104
+
105
+ > **注意:**
106
+ >
107
+ > 1. 在上面代码中,`accessKeyId`对应控制台中的“Access Key ID”,`secretAccessKey`对应控制台中的“Access Key Secret”,获取方式请参考《操作指南 [管理ACCESSKEY](GettingStarted.html#管理ACCESSKEY)》。
108
+ > 2. 如果用户需要自己指定域名,可以通过传入ENDPOINT参数来指定,`ENDPOINT`参数需要用指定区域的域名来进行定义,如服务所在区域为北京,则为`http://bj.bcebos.com`。
109
+
110
+ ### 使用STS创建BosClient
111
+
112
+ #### 申请STS token
113
+
114
+ BOS可以通过STS机制实现第三方的临时授权访问。STS(Security Token Service)是百度云提供的临时授权服务。通过STS,您可以为第三方用户颁发一个自定义时效和权限的访问凭证。第三方用户可以使用该访问凭证直接调用百度云的API或SDK访问百度云资源。
115
+
116
+ 通过STS方式访问BOS,用户需要先通过STS的client申请一个认证字符串,申请方式可参见[百度云STS使用介绍](https://cloud.baidu.com/doc/BOS/API.html#STS.E7.AE.80.E4.BB.8B)。
117
+
118
+ #### 用STS token新建BOSClient
119
+
120
+ 申请好STS后,可将STStoken配置到BosClient中,用户可以参考如下代码新建一个BosClient:
121
+
122
+ 1. 首先进行STS的endpoint配置。STS的配置示例如下:
123
+
124
+ ```
125
+ require 'baidubce/services/sts/sts_client'
126
+ require 'baidubce/services/bos/bos_client'
127
+
128
+ credentials = Baidubce::Auth::BceCredentials.new(
129
+ "your ak",
130
+ "your sk"
131
+ )
132
+
133
+ sts_conf = Baidubce::BceClientConfiguration.new(
134
+ credentials,
135
+ "http://sts.bj.baidubce.com"
136
+ )
137
+ ```
138
+
139
+ 2. StsClient的示例代码如下:
140
+
141
+ ```
142
+ # 新建StsClient
143
+ sts_client = Baidubce::Services::StsClient.new(sts_conf)
144
+ acl = {
145
+ id: '8c47a952db4444c5a097b41be3f24c94',
146
+ accessControlList: [
147
+ {
148
+ eid: 'shj',
149
+ service: 'bce:bos',
150
+ region: 'bj',
151
+ effect: 'Allow',
152
+ resource: ["bos-demo"],
153
+ permission: ["READ"]
154
+ }
155
+ ]
156
+ }
157
+
158
+ # durationSeconds为失效时间,如果为非int值或者不设置该参数,会使用默认的12小时作为失效时间
159
+ # sts_client.get_session_token(acl, "test")
160
+ # sts_client.get_session_token(acl, 1024)
161
+ sts_response = sts_client.get_session_token(acl)
162
+
163
+ sts_ak = sts_response["accessKeyId"]
164
+ sts_sk = sts_response['secretAccessKey']
165
+ token = sts_response['sessionToken']
166
+ ```
167
+
168
+ **注意:**其中acl指用户定义的acl,语法请参照[访问控制](API.html#访问控制)。
169
+
170
+ 3. 将获取到的accessKeyID/secretAccessKey/sessionToken用于新建BosClient。
171
+
172
+ ```
173
+ # 使用获取到的ak, sk, token新建BosClient访问BOS
174
+ sts_credentials = Baidubce::Auth::BceCredentials.new(
175
+ sts_ak,
176
+ sts_sk,
177
+ token
178
+ )
179
+
180
+ conf = Baidubce::BceClientConfiguration.new(
181
+ sts_credentials,
182
+ "http://bj.bcebos.com",
183
+ )
184
+
185
+ client = Baidubce::Services::BosClient.new(conf)
186
+ ```
187
+
188
+ **注意:**目前使用STS配置client时,无论对应BOS服务的endpoint在哪里,endpoint都需配置为`http://sts.bj.baidubce.com`。
189
+
190
+ ## 配置HTTPS协议访问BOS
191
+
192
+ BOS支持HTTPS传输协议,您可以通过如下两种方式在BOS Ruby SDK中使用HTTPS访问BOS服务:
193
+
194
+ - 在`endpoint`中指定HTTPS:
195
+
196
+ ```
197
+ # 配置client参数
198
+ credentials = Auth::BceCredentials.new(
199
+ "accessKeyId",
200
+ "secretAccessKey"
201
+ )
202
+
203
+ conf = BceClientConfiguration.new(
204
+ credentials,
205
+ "https://bj.bcebos.com"
206
+ )
207
+ # 新建BosClient
208
+ client = Services::BosClient.new(conf)
209
+ ```
210
+
211
+ - 通过在`protocol`中指定`https`来设置HTTPS协议:
212
+
213
+ ```
214
+ # 配置client参数
215
+ credentials = Auth::BceCredentials.new(
216
+ "accessKeyId",
217
+ "secretAccessKey"
218
+ )
219
+
220
+ options = {
221
+ 'protocol' => 'https'
222
+ }
223
+
224
+ conf = BceClientConfiguration.new(
225
+ credentials,
226
+ "bj.bcebos.com",
227
+ options
228
+ )
229
+
230
+ # 新建BosClient
231
+ client = Services::BosClient.new(conf)
232
+ ```
233
+
234
+ > **注意:**如果您在指定了endpoint的scheme的同时指定了protocol参数,则以endpoint为准。
235
+
236
+ ## 配置BosClient
237
+
238
+ ### 设置自定义参数
239
+
240
+ Ruby SDK默认设置了一些基本参数,若用户想要对参数的值进行修改,可以创建自身的参数配置,并在构造BosClient的时候传入,传入代码参考如下:
241
+
242
+ ```
243
+ #配置自定义参数
244
+ options = {
245
+ 'protocol' => 'https',
246
+ 'read_timeout_in_millis' => 1000 * 60,
247
+ 'region' => 'bj'
248
+ }
249
+
250
+ conf = BceClientConfiguration.new(
251
+ credentials,
252
+ "http://bj.bcebos.com",
253
+ options
254
+ )
255
+
256
+ #新建BosClient
257
+ client = Services::BosClient.new(conf)
258
+ ```
259
+
260
+ 参数说明如下:
261
+
262
+ | 参数 | 说明 | 默认值 |
263
+ | ---------------------- | ---------------------------------------------- | ------------------------------------------------------------ |
264
+ | protocol | 协议 | http |
265
+ | region | 区域 | bj |
266
+ | open_timeout_in_millis | 请求超时时间(单位:毫秒) | 50 * 1000 |
267
+ | read_timeout_in_millis | 通过打开的连接传输数据的超时时间(单位:毫秒) | 10 * 60 * 1000(设置时需要对文件大小和网速进行评估,否则上传大文件时会产生超时) |
268
+ | send_buf_size | 发送缓冲区大小 | 1024 * 1024 |
269
+ | recv_buf_size | 接收缓冲区大小 | 10 \* 1024 \* 1024 |
270
+
271
+ ### 设置可选参数
272
+
273
+ BosClient将可选的参数封装到`options`中,每一个方法具有的可选参数详见具体的接口使用方法介绍,现以`put_object_from_string`方法为例,参考如下代码实现设置可选参数:
274
+
275
+ ```
276
+ # 利用options在上传Object的时候传入指定参数
277
+ user_metadata = { "key1" => "value1" }
278
+ options = { Http::CONTENT_TYPE => 'string',
279
+ "key2" => "value2",
280
+ 'Content-Disposition' => 'inline',
281
+ 'user-metadata' => user_metadata
282
+ }
283
+
284
+ client.put_object_from_string(bucket_name, object_name, "obj_str", options)
285
+ ```
286
+
287
+ ## Bucket管理
288
+
289
+ Bucket既是BOS上的命名空间,也是计费、权限控制、日志记录等高级功能的管理实体。
290
+
291
+ - Bucket名称在所有区域中具有全局唯一性,且不能修改。
292
+
293
+ > **说明:**
294
+ >
295
+ > - 百度云目前开放了多区域支持,请参考[区域选择说明](../Reference/Regions.html)。
296
+ > - 目前支持“华北-北京”、“华南-广州”和“华东-苏州”三个区域。北京区域:`http://bj.bcebos.com`,广州区域:`http://gz.bcebos.com`,苏州区域:`http://su.bcebos.com`。
297
+
298
+ - 存储在BOS上的每个Object都必须包含在一个Bucket中。
299
+
300
+ - 一个用户最多可创建100个Bucket,但每个Bucket中存放的Object的数量和大小总和没有限制,用户不需要考虑数据的可扩展性。
301
+
302
+ ## Bucket权限管理
303
+
304
+ ### 设置Bucket的访问权限
305
+
306
+ 如下代码将Bucket的权限设置为了private:
307
+
308
+ ```
309
+ client.set_bucket_canned_acl(bucket_name, "private")
310
+ ```
311
+
312
+ canned acl支持三种权限,分别为:`private`、`public-read`、`public-read-write`。关于权限的具体内容可以参考《BOS API文档 [使用CannedAcl方式的权限控制](API.html#使用CannedAcl方式的权限控制)》。
313
+
314
+ ### 设置指定用户对Bucket的访问权限
315
+
316
+ BOS提供set_bucket_acl方法来实现指定用户对Bucket的访问权限设置,可以参考如下代码实现:
317
+
318
+ ```
319
+ acl = [{'grantee' => [{'id' => 'b124deeaf6f641c9ac27700b41a350a8'},
320
+ {'id' => 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'}],
321
+ 'permission' => ['FULL_CONTROL']
322
+ }]
323
+
324
+ client.set_bucket_acl(bucket_name, acl)
325
+ ```
326
+
327
+ > **注意:**
328
+ >
329
+ > 1. permission中的权限设置包含三个值:`READ`、`WRITE`、`FULL_CONTROL`,它们分别对应相关权限。具体内容可以参考《BOS API文档 [上传ACL文件方式的权限控制](API.html# 上传ACL文件方式的权限控制)》。
330
+ > 2. 设置两个以上(含两个)被授权人时,请参考以上示例的格式,若将数组合并会返回报错。
331
+
332
+ ### 设置更多Bucket访问权限
333
+
334
+ 1. 通过设置referer白名单方式设置防盗链
335
+
336
+ ```
337
+ acl = [{'grantee' => [{'id' => 'b124deeaf6f641c9ac27700b41a350a8'},
338
+ {'id' => 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'}],
339
+ 'permission' => ['FULL_CONTROL'],
340
+ 'condition' => {
341
+ 'referer' => {
342
+ 'stringLike' => ['http://www.abc.com/*'],
343
+ 'stringEquals' => ['http://www.abc.com']
344
+ }
345
+ }
346
+ }]
347
+
348
+ client.set_bucket_acl(bucket_name, acl)
349
+ ```
350
+
351
+ 2. 限制客户端IP访问,只允许部分客户端IP访问
352
+
353
+ ```
354
+ acl = [{'grantee' => [{'id' => 'b124deeaf6f641c9ac27700b41a350a8'},
355
+ {'id' => 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'}],
356
+ 'permission' => ['FULL_CONTROL'],
357
+ 'condition' => {
358
+ "ipAddress" => [
359
+ '192.168.0.0/16',
360
+ '192.169.0.*',
361
+ '192.170.0.5'
362
+ ]
363
+ }
364
+ }]
365
+
366
+ client.set_bucket_acl(bucket_name, acl)
367
+ ```
368
+
369
+ ### 设置STS临时token权限
370
+
371
+ 对于通过STS方式创建的临时访问身份,管理员也可进行专门的权限设定。
372
+ STS的简介及设置临时权限的方式可参见[临时授权访问](https://cloud.baidu.com/doc/BOS/API.html#.E4.B8.B4.E6.97.B6.E6.8E.88.E6.9D.83.E8.AE.BF.E9.97.AE)。
373
+
374
+ 使用BOS Ruby SDK设置STS临时token权限可参考[使用STS创建BosClient](#使用STS创建BosClient)
375
+
376
+ ### 查看Bucket的权限
377
+
378
+ 如下代码可以查看Bucket的权限:
379
+
380
+ ```
381
+ client.get_bucket_acl(bucket_name)
382
+ ```
383
+
384
+ `get_bucket_acl`方法返回的解析类中可供调用的参数有:
385
+
386
+ | 参数 | 说明 |
387
+ | ---------- | -------------------- |
388
+ | owner | Bucket owner信息 |
389
+ | id | Bucket owner的用户ID |
390
+ | acl | 标识Bucket的权限列表 |
391
+ | grantee | 标识被授权人 |
392
+ | -id | 被授权人ID |
393
+ | permission | 标识被授权人的权限 |
394
+
395
+ ## 查看Bucket所属的区域
396
+
397
+ Bucket Location即Bucket Region,百度云支持的各region详细信息可参见[区域选择说明](https://cloud.baidu.com/doc/Reference/Regions.html)。
398
+
399
+ 如下代码可以获取该Bucket的Location信息:
400
+
401
+ ```
402
+ client.get_bucket_location(bucket_name)
403
+ ```
404
+
405
+ ## 新建Bucket
406
+
407
+ 如下代码可以新建一个Bucket:
408
+
409
+ ```
410
+ bucketName = "your_bucket";
411
+
412
+ # Bucket是否存在,若不存在创建Bucket
413
+ client.create_bucket(bucket_name) unless client.does_bucket_exist(bucket_name)
414
+ ```
415
+
416
+ > **注意:**
417
+ > 由于Bucket的名称在所有区域中是唯一的,所以需要保证bucketName不与其他所有区域上的Bucket名称相同。
418
+ >
419
+ > Bucket的命名有以下规范:
420
+ >
421
+ > - 只能包括小写字母,数字,短横线(-)。
422
+ > - 必须以小写字母或者数字开头。
423
+ > - 长度必须在3-63字节之间。
424
+
425
+ 通过上述代码创建的bucket,权限是私有读写,存储类型是标准类型(Standard)。用户在控制台创建Bucket时可以指定Bucket权限和存储类型。
426
+
427
+ ## 列举Bucket
428
+
429
+ 如下代码可以列出用户所有的Bucket:
430
+
431
+ ```
432
+ buckets = client.list_buckets()
433
+ ```
434
+
435
+ ## 删除Bucket
436
+
437
+ ### 删除指定Bucket
438
+
439
+ 如下代码可以删除一个Bucket:
440
+
441
+ ```
442
+ bucketName = "your_bucket";
443
+ client.delete_bucket(bucketName)
444
+ ```
445
+
446
+ > **注意:**
447
+ >
448
+ > - 在删除前需要保证此Bucket下的所有Object和未完成的三步上传Part已经被删除,否则会删除失败。
449
+ > - 在删除前确认该Bucket没有开通跨区域复制,不是跨区域复制规则中的源Bucket或目标Bucket,否则不能删除。
450
+
451
+ ### 删除所有Bucket
452
+
453
+ 将`delete_bucket`和`list_buckets`函数结合,可以删除全部Bucket,参考代码如下:
454
+
455
+ ```
456
+ # 列出全部Bucket
457
+ buckets = client.list_buckets()['buckets']
458
+
459
+ # 遍历删除全部Bucket
460
+ buckets.each do |bucket|
461
+ while true
462
+ options = {}
463
+ res = client.list_objects(bucket['name'], options)
464
+ res['contents'].each do |object|
465
+ client.delete_object(bucket['name'], object['key'])
466
+ end
467
+ if res['isTruncated']
468
+ options[:marker] = res['nextMarker']
469
+ else
470
+ break
471
+ end
472
+ end
473
+ client.delete_bucket(bucket['name'])
474
+ end
475
+ ```
476
+
477
+ ## 判断Bucket是否存在
478
+
479
+ 若用户需要判断某个Bucket是否存在,则如下代码可以做到:
480
+
481
+ ```
482
+ client.does_bucket_exist(bucketName)
483
+ ```
484
+
485
+ # 文件管理
486
+
487
+ ## 上传文件
488
+
489
+ 在BOS中,用户操作的基本数据单元是Object。Object包含Key、Meta和Data。其中,Key是Object的名字;Meta是用户对该Object的描述,由一系列Name-Value对组成;Data是Object的数据。
490
+
491
+ BOS Ruby SDK提供了丰富的文件上传接口,可以通过以下方式上传文件:
492
+
493
+ - 简单上传
494
+ - 追加上传
495
+ - 分片上传
496
+ - 断点续传上传
497
+
498
+ ### 简单上传
499
+
500
+ BOS在简单上传的场景中,支持以指定文件形式、以数据流方式、以二进制串方式、以字符串方式执行Object上传,请参考如下代码:
501
+
502
+ ```
503
+ # 以数据流形式上传Object
504
+ client.put_object(bucket_name, object_name, data)
505
+
506
+ # 从字符串中上传Object
507
+ client.put_object_from_string(bucket_name, object_name, "string")
508
+
509
+ # 从文件中直接上传Object
510
+ client.put_object_from_file(bucket_name, object_name, file_path)
511
+ ```
512
+
513
+ Object以文件的形式上传到BOS中,putObject相关接口支持不超过5GB的Object上传。在PutObject请求处理成功后,BOS会在Header中返回Object的ETag作为文件标识。
514
+
515
+ **设置文件元信息**
516
+
517
+ 文件元信息(Object Meta),是对用户在向BOS上传文件时,同时对文件进行的属性描述,主要分为分为两种:设置HTTP标准属性(HTTP Headers)和用户自定义的元信息。
518
+
519
+ **设定Object的Http Header**
520
+
521
+ BOS Ruby SDK本质上是调用后台的HTTP接口,因此用户可以在上传文件时自定义Object的Http Header。常用的http header说明如下:
522
+
523
+ | 名称 | 描述 | 默认值 |
524
+ | ------------------- | ------------------------------------------------------------ | ------------------------ |
525
+ | Content-MD5 | 文件数据校验,设置后BOS会启用文件内容MD5校验,把您提供的MD5与文件的MD5比较,不一致会抛出错误 | 无 |
526
+ | Content-Type | 文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如没有指,BOS则根据文件的扩展名自动生成,如文件没有扩展名则填默认值 | application/octet-stream |
527
+ | Content-Disposition | 指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称 | 无 |
528
+ | Content-Length | 上传的文件的长度,超过流/文件的长度会截断,不足为实际值 | 流/文件时间长度 |
529
+ | Expires | 缓存过期时间 | 无 |
530
+ | Cache-Control | 指定该Object被下载时的网页的缓存行为 | 无 |
531
+
532
+ 参考代码如下:
533
+
534
+ ```
535
+ options = { Http::CONTENT_TYPE => 'string',
536
+ Http::CONTENT_MD5 => 'md5',
537
+ Http::CONTENT_DISPOSITION => 'inline',
538
+ 'key1' => 'value1'
539
+ }
540
+
541
+ client.put_object_from_string(bucket_name, object_name, "string", options)
542
+ ```
543
+
544
+ **用户自定义元信息**
545
+
546
+ BOS支持用户自定义元数据来对Object进行描述。如下代码所示:
547
+
548
+ ```
549
+ options = {
550
+ 'user-metadata' => { "key1" => "value1" }
551
+ }
552
+
553
+ client.put_object_from_string(bucket_name, object_name, "string", options)
554
+ ```
555
+
556
+ > **提示:**
557
+ >
558
+ > - 在上面代码中,用户自定义了一个名字为”key1”,值为”value1”的元数据
559
+ > - 当用户下载此Object的时候,此元数据也可以一并得到
560
+ > - 一个Object可以有多个类似的参数,但所有的User Meta总大小不能超过2KB
561
+
562
+ **上传Object时设置存储类型**
563
+
564
+ BOS支持标准存储, 低频存储和冷存储,上传Object并存储为低频存储类型通过指定StorageClass实现,三种存储类型对应的参数如下:
565
+
566
+ | 存储类型 | 参数 |
567
+ | -------- | ----------- |
568
+ | 标准存储 | STANDRAD |
569
+ | 低频存储 | STANDARD_IA |
570
+ | 冷存储 | COLD |
571
+
572
+ 以低频存储为例,代码如下:
573
+
574
+ ```
575
+ # 上传一个低频object(默认为标准object)
576
+ client.put_object_from_file(bucket_name, object_name, file_path, Http::BOS_STORAGE_CLASS => 'STANDARD_IA')
577
+ ```
578
+
579
+ putObject请求处理成功后,BOS会在Header中返回Object的Content-MD5,用户可以根据这个参数来对文件进行校验。
580
+
581
+ ### 追加上传
582
+
583
+ 上文介绍的简单上传方式,创建的Object都是Normal类型,用户不可再进行追加写,这在日志、视频监控、视频直播等数据复写较频繁的场景中使用不方便。
584
+
585
+ 正因如此,百度云BOS特别支持了AppendObject,即以追加写的方式上传文件。通过AppendObject操作创建的Object类型为Appendable Object,可以对该Object追加数据。AppendObject大小限制为0~5G。
586
+
587
+ 通过AppendObject方式上传示例代码如下:
588
+
589
+ ```
590
+ # 从字符串上传一个appendable object
591
+ client.append_object_from_string(bucket_name, object_name, "string")
592
+
593
+ # 从offset处开始追加写
594
+ client.append_object_from_string(bucket_name, object_name, "append_str", 'offset' => 6)
595
+ ```
596
+
597
+ ### 分块上传
598
+
599
+ 除了通过简单上传几追加上传方式将文上传件到BOS以外,BOS还提供了另外一种上传模式 —— Multipart Upload。用户可以在如下的应用场景内(但不仅限于此),使用Multipart Upload上传模式,如:
600
+
601
+ - 需要支持断点上传。
602
+ - 上传超过5GB大小的文件。
603
+ - 网络条件较差,和BOS的服务器之间的连接经常断开。
604
+ - 需要流式地上传文件。
605
+ - 上传文件之前,无法确定上传文件的大小。
606
+
607
+ 下面将一步步介绍Multipart Upload的实现。假设有一个文件,本地路径为 `/path/to/file.zip` ,由于文件比较大,将其分块传输到BOS中。
608
+
609
+ #### 初始化Multipart Upload
610
+
611
+ 使用`initiate_multipart_upload` 方法来初始化一个分块上传事件:
612
+
613
+ ```
614
+ upload_id = client.initiate_multipart_upload(bucket_name, object_name)["uploadId"]
615
+ ```
616
+
617
+ `initiate_multipart_upload`的返回结果中含有 `uploadId` ,它是区分分块上传事件的唯一标识,在后面的操作中,我们将用到它。
618
+
619
+ #### 上传低频存储类型Object的初始化
620
+
621
+ 初始化低频存储的一个分块上传事件:
622
+
623
+ ```
624
+ options = {
625
+ Http::BOS_STORAGE_CLASS => 'STANDARD_IA'
626
+ }
627
+ client.initiate_multipart_upload(bucket_name, object_name, options)
628
+ ```
629
+
630
+ #### 上传冷存储类型Object的初始化
631
+
632
+ 初始化冷存储的一个分块上传事件:
633
+
634
+ ```
635
+ options = {
636
+ Http::BOS_STORAGE_CLASS => 'COLD'
637
+ }
638
+ client.initiate_multipart_upload(bucket_name, object_name, options)
639
+ ```
640
+
641
+ #### 上传分块
642
+
643
+ 接着,把文件分块上传。
644
+
645
+ ```
646
+ # 设置分块的开始偏移位置
647
+ left_size = File.open(multi_file, "r").size()
648
+ offset = 0
649
+ part_number = 1
650
+ part_list = []
651
+
652
+ while left_size > 0 do
653
+ part_size = 5 * 1024 * 1024
654
+ if left_size < part_size
655
+ part_size = left_size
656
+ end
657
+
658
+ response = client.upload_part_from_file(
659
+ bucket_name, object_name, upload_id, part_number, part_size, multi_file, offset)
660
+ left_size -= part_size
661
+ offset += part_size
662
+ # your should store every part number and etag to invoke complete multi-upload
663
+ part_list << {
664
+ "partNumber" => part_number,
665
+ "eTag" => response['etag']
666
+ }
667
+ part_number += 1
668
+ end
669
+ ```
670
+
671
+ 上面代码的核心是调用 `UploadPart` 方法来上传每一个分块,但是要注意以下几点:
672
+
673
+ - UploadPart 方法要求除最后一个Part以外,其他的Part大小都要大于等于5MB。但是Upload Part接口并不会立即校验上传Part的大小;只有当Complete Multipart Upload的时候才会校验。
674
+ - 为了保证数据在网络传输过程中不出现错误,建议您在`UploadPart`后,使用每个分块BOS返回的Content-MD5值分别验证已上传分块数据的正确性。当所有分块数据合成一个Object后,不再含MD5值。
675
+ - Part号码的范围是1~10000。如果超出这个范围,BOS将返回InvalidArgument的错误码。
676
+ - 每次上传Part时都要把流定位到此次上传块开头所对应的位置。
677
+ - 每次上传Part之后,BOS的返回结果会包含`eTag`和`partNumber`,需要保存到`part_list`中。`part_list`类型是array,里面每个元素是个hash,每个hash包含两个关键字,一个是partNumber, 一个是eTag;在后续完成分块上传的步骤中会用到它。
678
+
679
+ #### 完成分块上传
680
+
681
+ 如下代码所示,完成分块上传:
682
+
683
+ ```
684
+ client.complete_multipart_upload(bucket_name, object_name, upload_id, part_list)
685
+ ```
686
+
687
+ 上面代码中的 `part_list` 是第二步中保存的part列表,BOS收到用户提交的Part列表后,会逐一验证每个数据Part的有效性。当所有的数据Part验证通过后,BOS将把这些数据part组合成一个完整的Object。
688
+
689
+ #### 取消分块上传
690
+
691
+ 用户可以使用`abort_multipart_upload`方法取消分块上传。
692
+
693
+ ```
694
+ client.abort_multipart_upload(bucket_name, object_name, upload_id)
695
+ ```
696
+
697
+ #### 获取未完成的分块上传事件
698
+
699
+ 用户可以使用`list_multipart_uploads`方法获取Bucket中未完成的分块上传事件。
700
+
701
+ ```
702
+ response = client.list_multipart_uploads(bucket_name)
703
+ puts response['bucket']
704
+ puts response['uploads'][0]['key']
705
+ ```
706
+
707
+ > **注意:**
708
+ >
709
+ > 1. 默认情况下,如果Bucket中的分块上传事件的数目大于1000,则只会返回1000个Object,并且返回结果中IsTruncated的值为True,同时返回NextKeyMarker作为下次读取的起点。
710
+ > 2. 若想返回更多分块上传事件的数目,可以使用KeyMarker参数分次读取。
711
+
712
+ **获取所有已上传的块信息**
713
+
714
+ 用户可以使用`list_parts`方法获取某个上传事件中所有已上传的块:
715
+
716
+ ```
717
+ response = client.list_parts(bucket_name, object_name, upload_id)
718
+ puts response['bucket']
719
+ puts response['uploads'][0]['key']
720
+ ```
721
+
722
+ > **注意:**
723
+ >
724
+ > 1. 默认情况下,如果Bucket中的分块上传事件的数目大于1000,则只会返回1000个Object,并且返回结果中IsTruncated的值为True,同时返回NextPartNumberMarker作为下次读取的起点。
725
+ > 2. 若想返回更多分块上传事件的数目,可以使用PartNumberMarker参数分次读取。
726
+
727
+ ### 断点续传上传
728
+
729
+ 当用户向BOS上传大文件时,如果网络不稳定或者遇到程序崩等情况,则整个上传就失败了,失败前已经上传的部分也作废,用户不得不重头再来。这样做不仅浪费资源,在网络不稳定的情况下,往往重试多次还是无法完成上传。
730
+ 基于上述场景,BOS提供了断点续传上传的能力:
731
+
732
+ - 当网络情况一般的情况下,建议使用三步上传方式,将object分为1Mb的块,参考[分块上传](#分块上传)。
733
+ - 当您的网络情况非常差,推荐使用appendObject的方式进行断点续传,每次append 较小数据256kb,参考[追加上传](# 追加上传)。
734
+
735
+ > **提示**
736
+ >
737
+ > - 断点续传是分片上传的封装和加强,是用分片上传实现的;
738
+ > - 文件较大或网络环境较差时,推荐使用分片上传;
739
+
740
+ ## 下载文件
741
+
742
+ BOS Ruby SDK提供了丰富的文件下载接口,用户可以通过以下方式从BOS中下载文件:
743
+
744
+ - 简单流式下载
745
+ - 下载到本地文件
746
+ - 断点续传下载
747
+ - 范围下载
748
+
749
+ ### 简单流式下载
750
+
751
+ 用户可以通过如下代码将Object读取到一个流中:
752
+
753
+ ```
754
+ client.get_object_as_string(bucket_name, object_name)
755
+ ```
756
+
757
+ ### 直接下载Object到文件
758
+
759
+ 用户可以参考如下代码将Object下载到指定文件:
760
+
761
+ ```
762
+ client.get_object_to_file(bucket_name, object_name, file_name)
763
+ ```
764
+
765
+ ### 范围下载
766
+
767
+ 为了实现更多的功能,可以通过配置`RANGE`参数来指定下载范围,实现更精细化地获取Object。如果指定的下载范围是0 - 100,则返回第0到第100个字节的数据,包括第100个,共101字节的数据,即[0, 100]。`RANGE`参数的格式为`array(offset, endset)`其中两个变量为长整型,单位为字节。用户也可以用此功能实现文件的分段下载和断点续传。
768
+
769
+ ```
770
+ range = [0,100]
771
+ client.get_object_as_string(bucket_name, object_name, range)
772
+ ```
773
+
774
+ ### 其他使用方法
775
+
776
+ #### 获取Object的存储类型
777
+
778
+ Object的storage class属性分为`STANDARD`(标准存储), `STANDARD_IA`(低频存储)和`COLD`(冷存储),通过如下代码可以实现:
779
+
780
+ ```
781
+ response = client.get_object_meta_data(bucket_name, object_name)
782
+ puts response[Http::BOS_STORAGE_CLASS];
783
+ ```
784
+
785
+ #### 只获取ObjectMetadata
786
+
787
+ 用户也可通过`get_object_meta_data`方法可以只获取ObjectMetadata而不获取Object的实体。如下代码所示:
788
+
789
+ ```
790
+ response = client.get_object_meta_data(bucket_name, object_name)
791
+ puts response['etag'];
792
+ ```
793
+
794
+ `get_object_meta_data`方法返回的解析类中可供调用的参数有:
795
+
796
+ | 参数 | 说明 |
797
+ | ------------------- | ------------------------------------------------------- |
798
+ | content-type | Object的类型 |
799
+ | content-length | Object的大小 |
800
+ | content-md5 | Object的MD5 |
801
+ | etag | Object的HTTP协议实体标签 |
802
+ | x-bce-storage-class | Object的存储类型 |
803
+ | user-metadata | 如果在PutObject指定了userMetadata自定义meta,则返回此项 |
804
+
805
+ ## 变更文件存储等级
806
+
807
+ 上文中已提到,BOS支持为文件赋予STANDARD(标准存储), STANDARD_IA(低频存储)和COLD(冷存储)三种存储类型。同时,BOS Ruby SDK也支持用户对特定文件执行存储类型变更的操作。
808
+
809
+ 涉及到的参数如下:
810
+
811
+ | 参数 | 说明 |
812
+ | ------------------- | ------------------------------------------------------------ |
813
+ | x-bce-storage-class | 指定Object的存储类型,STANDARD_IA代表低频存储,COLD代表冷存储,不指定时默认是标准存储类型。 |
814
+
815
+ 示例如下:
816
+
817
+ ```
818
+ options = {
819
+ Http::BOS_STORAGE_CLASS => 'STANDARD_IA'
820
+ }
821
+
822
+ # 标准存储转低频存储
823
+ client.copy_object(bucket_name, object_name, bucket_name, object_name, options)
824
+ puts client.get_object_meta_data(bucket_name, object_name)[Http::BOS_STORAGE_CLASS]
825
+
826
+ options = {
827
+ Http::BOS_STORAGE_CLASS => 'COLD'
828
+ }
829
+
830
+ # 低频存储转冷存储
831
+ client.copy_object(bucket_name, object_name, bucket_name, object_name, options)
832
+ puts client.get_object_meta_data(bucket_name, object_name)[Http::BOS_STORAGE_CLASS]
833
+ ```
834
+
835
+ ## 获取文件下载URL
836
+
837
+ 用户可以参考如下代码获取Object的URL:
838
+
839
+ ```
840
+ options = { 'expiration_in_seconds' => 360,
841
+ 'timestamp' => Time.now.to_i
842
+ }
843
+
844
+ puts client.generate_pre_signed_url(bucket_name, object_name, options)
845
+ ```
846
+
847
+ > **说明:**
848
+ >
849
+ > - 用户在调用该函数前,需要手动设置endpoint为所属区域域名。百度云目前开放了多区域支持,请参考[区域选择说明](../Reference/Regions.html)。目前支持“华北-北京”、“华南-广州”和“华东-苏州”三个区域。北京区域:`http://bj.bcebos.com`,广州区域:`http://gz.bcebos.com`,苏州区域:`http://su.bcebos.com`。
850
+ > - `EXPIRATION_IN_SECONDS`为指定的URL有效时长,时间从当前时间算起,为可选参数,不配置时系统默认值为1800秒。如果要设置为永久不失效的时间,可以将`expiration_in_seconds`参数设置为 -1,不可设置为其他负数。
851
+ > - `TIMESTAMP`为可选参数,不配置时,系统默认TIMESTAMP为当前时间。
852
+ > - 如果预期获取的文件时公共可读的,则对应URL链接可通过简单规则快速拼接获取: http://bucketName.$region.bcebos.com/$bucket/$object
853
+
854
+ ## 列举存储空间中的文件
855
+
856
+ BOS SDK支持用户通过以下两种方式列举出object:
857
+
858
+ - 简单列举
859
+ - 通过参数复杂列举
860
+
861
+ 除此之外,用户还可在列出文件的同时模拟文件夹
862
+
863
+ ### 简单列举
864
+
865
+ 当用户希望简单快速列举出所需的文件时,可通过listObjects方法获取Bucket中的Object列表。
866
+
867
+ ```
868
+ client.list_objects(bucket_name)
869
+ ```
870
+
871
+ > **注意:**
872
+ >
873
+ > 1. 默认情况下,如果Bucket中的Object数量大于1000,则只会返回1000个Object。
874
+ > 2. 若想增大返回Object的数目,可以使用Marker参数分次读取。
875
+
876
+ ### 通过参数复杂列举
877
+
878
+ 除上述简单列举外,用户还可通过`options`配置可选参数来实现各种灵活的查询功能。可设置的参数如下:
879
+
880
+ | 参数 | 功能 |
881
+ | --------- | ------------------------------------------------------------ |
882
+ | PREFIX | 限定返回的object key必须以prefix作为前缀 |
883
+ | DELIMITER | 是一个用于对Object名字进行分组的字符所有名字包含指定的前缀且第一次出现。Delimiter字符之间的Object作为一组元素: CommonPrefixes |
884
+ | MARKER | 设定结果从marker之后按字母排序的第一个开始返回 |
885
+ | MAX_KEYS | 限定此次返回object的最大数,如果不设定,默认为100,max-keys取值不能大于1000 |
886
+
887
+ > **注意:**
888
+ >
889
+ > 1. 如果有Object以Prefix命名,当仅使用Prefix查询时,返回的所有Key中仍会包含以Prefix命名的Object,详见[递归列出目录下所有文件](#递归列出目录下所有文件)。
890
+ > 2. 如果有Object以Prefix命名,当使用Prefix和Delimiter组合查询时,返回的所有Key中会有Null,Key的名字不包含Prefix前缀,详见[查看目录下的文件和子目录](# 查看目录下的文件和子目录)。
891
+
892
+ 下面我们分别以几个案例说明通过参数列举的方法:
893
+
894
+ **指定最大返回条数**
895
+
896
+ ```
897
+ # 指定最大返回条数为500
898
+ options = {
899
+ maxKeys: 500
900
+ }
901
+ puts client.list_objects(bucket_name, options)
902
+ ```
903
+
904
+ **返回指定前缀的object**
905
+
906
+ ```
907
+ # 指定返回前缀为usr的object
908
+ options = {
909
+ prefix: 'usr'
910
+ }
911
+ puts client.list_objects(bucket_name, options)
912
+ ```
913
+
914
+ **从指定Object后返回**
915
+
916
+ ```
917
+ # 用户可以定义不包括某object,从其之后开始返回
918
+ options = {
919
+ marker: 'object'
920
+ }
921
+ puts client.list_objects(bucket_name, options)
922
+ ```
923
+
924
+ **分页获取所有Object**
925
+
926
+ 用户可设置每页最多500条记录
927
+
928
+ ```
929
+ options = {
930
+ maxKeys: 500
931
+ }
932
+
933
+ is_truncated = true
934
+ while is_truncated
935
+ res = client.list_objects(bucket_name, options)
936
+ is_truncated = res['isTruncated']
937
+ options[:marker] = res['nextMarker'] unless res['nextMarker'].nil?
938
+ end
939
+ ```
940
+
941
+ **分页获取所有特定Object后的结果**
942
+
943
+ 用户可设置每页最多500条记录,并从某特定object之后开始获取
944
+
945
+ ```
946
+ options = {
947
+ maxKeys: 5,
948
+ marker: 'object'
949
+ }
950
+
951
+ is_truncated = true
952
+ while is_truncated
953
+ res = client.list_objects(bucket_name, options)
954
+ is_truncated = res['isTruncated']
955
+ options[:marker] = res['nextMarker'] unless res['nextMarker'].nil?
956
+ end
957
+ ```
958
+
959
+ `listObjects`方法返回的解析类中可供调用的参数有:
960
+
961
+ | 参数 | 说明 |
962
+ | ------------- | ------------------------------------------------------------ |
963
+ | name | Bucket名称 |
964
+ | prefix | 匹配以prefix开始到第一次出现Delimiter字符之间的object作为一组元素返回 |
965
+ | marker | 本次查询的起点 |
966
+ | maxKeys | 请求返回的最大数目 |
967
+ | isTruncated | 指明是否所有查询都返回了;false-本次已经返回所有结果,true-本次还没有返回所有结果 |
968
+ | contents | 返回的一个Object的容器 |
969
+ | +key | Object名称 |
970
+ | +lastModified | 此Object最后一次被修改的时间 |
971
+ | +eTag | Object的HTTP协议实体标签 |
972
+ | +storageClass | Object的存储形态 |
973
+ | +size | Object的内容的大小(字节数) |
974
+ | +owner | Object对应Bucket所属用户信息 |
975
+ | ++id | Bucket Owner的用户ID |
976
+ | ++displayName | Bucket Owner的名称 |
977
+
978
+ ### 模拟文件夹功能
979
+
980
+ 在BOS的存储结果中是没有文件夹这个概念的,所有元素都是以Object来存储,但BOS的用户在使用数据时往往需要以文件夹来管理文件。
981
+
982
+ 因此,BOS提供了创建模拟文件夹的能力,其本质上来说是创建了一个size为0的Object。对于这个Object可以上传下载,只是控制台会对以”/“结尾的Object以文件夹的方式展示。
983
+
984
+ 用户可以通过 Delimiter 和 Prefix 参数的配合模拟出文件夹功能。Delimiter 和 Prefix 的组合效果是这样的:
985
+
986
+ 如果把 Prefix 设为某个文件夹名,就可以罗列以此 Prefix 开头的文件,即该文件夹下递归的所有的文件和子文件夹(目录)。文件名在Contents中显示。
987
+
988
+ 如果再把 Delimiter 设置为 “/” 时,返回值就只罗列该文件夹下的文件和子文件夹(目录),该文件夹下的子文件名(目录)返回在 CommonPrefixes 部分,子文件夹下递归的文件和文件夹不被显示。
989
+
990
+ 如下是几个应用方式:
991
+
992
+ #### 列出Bucket内所有文件
993
+
994
+ 当用户需要获取Bucket下的所有文件时,可以参考[分页获取所有Object](#分页获取所有Object)
995
+
996
+ #### 递归列出目录下所有文件
997
+
998
+ 可以通过设置 `Prefix` 参数来获取dir目录下所有的文件:
999
+
1000
+ ```
1001
+ options = {
1002
+ prefix: 'dir/'
1003
+ }
1004
+
1005
+ is_truncated = true
1006
+ while is_truncated
1007
+ res = client.list_objects(bucket_name, options)
1008
+ is_truncated = res['isTruncated']
1009
+ options[:marker] = res['nextMarker'] unless res['nextMarker'].nil?
1010
+ end
1011
+ ```
1012
+
1013
+ #### 查看目录下的文件和子目录
1014
+
1015
+ 在 `Prefix` 和 `Delimiter` 结合的情况下,可以列出dir目录下的文件和子目录:
1016
+
1017
+ ```
1018
+ options = {
1019
+ prefix: 'dir/',
1020
+ delimiter: '/'
1021
+ }
1022
+
1023
+ is_truncated = true
1024
+ while is_truncated
1025
+ res = client.list_objects(bucket_name, options)
1026
+ is_truncated = res['isTruncated']
1027
+ options[:marker] = res['nextMarker'] unless res['nextMarker'].nil?
1028
+ end
1029
+ ```
1030
+
1031
+ ### 列举Bucket中object的存储属性
1032
+
1033
+ 当用户完成上传后,如果需要查看指定Bucket中的全部Object的storage class属性,可以通过如下代码实现:
1034
+
1035
+ ```
1036
+ res = client.list_objects(bucket_name)
1037
+
1038
+ res['contents'].each { |obj| puts obj['storageClass'] }
1039
+ ```
1040
+
1041
+ ## Object权限控制
1042
+
1043
+ ### 设置Object的访问权限
1044
+
1045
+ 如下代码将Object的权限设置为了private:
1046
+
1047
+ ```
1048
+ client.set_object_canned_acl(bucket_name, object_name, Http::BCE_ACL => 'private')
1049
+ ```
1050
+
1051
+ 关于权限的具体内容可以参考《BOS API文档 [Object权限控制](API.html#Object权限控制)》。
1052
+
1053
+ ### 设置指定用户对Object的访问权限
1054
+
1055
+ BOS提供`set_object_acl`方法和`set_object_canned_acl`方法来实现指定用户Object的访问权限设置,可以参考如下代码实现:
1056
+
1057
+ 1. 通过`set_object_canned_acl`的`x-bce-grant-read`和`x-bce-grant-full-control`设置指定用户的访问权限
1058
+
1059
+ ```
1060
+ id_permission = "id=\"8c47a952db4444c5a097b41be3f24c94\",id=\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\""
1061
+ client.set_object_canned_acl(bucket_name, object_name, 'x-bce-grant-read' => id_permission)
1062
+ ```
1063
+
1064
+ ```
1065
+ id_permission = "id=\"8c47a952db4444c5a097b41be3f24c94\",id=\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\""
1066
+ client.set_object_canned_acl(bucket_name, object_name, 'x-bce-grant-full-control' => id_permission)
1067
+ ```
1068
+
1069
+ 2. 通过`set_object_acl`设置object访问权限
1070
+
1071
+ ```
1072
+ acl = [{'grantee' => [{'id' => 'b124deeaf6f641c9ac27700b41a350a8'},
1073
+ {'id' => 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'}],
1074
+ 'permission' => ['FULL_CONTROL']
1075
+ }]
1076
+ client.set_object_acl(bucket_name, object_name, acl)
1077
+ ```
1078
+
1079
+ > **注意:**
1080
+ >
1081
+ > 1. permission中的权限设置包含两个值:`READ`、`FULL_CONTROL`,它们分别对应相关权限。
1082
+ > 2. 设置两个以上(含两个)被授权人时,请参考以上示例的格式,若将数组合并会返回报错。
1083
+
1084
+ ### 查看Object的权限
1085
+
1086
+ 如下代码可以查Object的权限:
1087
+
1088
+ ```
1089
+ client.get_object_acl(bucket_name, object_name)
1090
+ ```
1091
+
1092
+ `get_object_acl`方法返回的解析类中可供调用的参数有:
1093
+
1094
+ | 参数 | 说明 |
1095
+ | ----------------- | -------------------- |
1096
+ | accessControlList | 标识Object的权限列表 |
1097
+ | grantee | 标识被授权人 |
1098
+ | -id | 被授权人ID |
1099
+ | permission | 标识被授权人的权限 |
1100
+
1101
+ ### 删除Object的权限
1102
+
1103
+ 如下代码可以删除Object的权限:
1104
+
1105
+ ```
1106
+ client.delete_object_acl(bucket_name, object_name)
1107
+ ```
1108
+
1109
+ ## 删除文件
1110
+
1111
+ **删除单个文件**
1112
+
1113
+ 可参考如下代码删除了一个Object:
1114
+
1115
+ ```
1116
+ client.delete_object(bucket_name, object_name)
1117
+ ```
1118
+
1119
+ ## 查看文件是否存在
1120
+
1121
+ 用户可通过如下操作查看某文件是否存在:
1122
+
1123
+ ```
1124
+ begin
1125
+ client.get_object_meta_data(bucket_name, object_name)
1126
+ rescue BceServerException => e
1127
+ puts "#{object_name} not exist!" if e.status_code == 404
1128
+ end
1129
+ ```
1130
+
1131
+ ## 获取及更新文件元信息
1132
+
1133
+ 文件元信息(Object Metadata),是对用户上传BOS的文件的属性描述,分为两种:HTTP标准属性(HTTP Headers)和User Meta(用户自定义元信息)。
1134
+
1135
+ ### 获取文件元信息
1136
+
1137
+ 参考[只获取ObjectMetadata](#只获取ObjectMetadata)。
1138
+
1139
+ ### 修改文件元信息
1140
+
1141
+ BOS修改Object的Metadata通过拷贝Object实现。即拷贝Object的时候,把目的Bucket设置为源Bucket,目的Object设置为源Object,并设置新的Metadata,通过拷贝自身实现修改Metadata的目的。如果不设置新的Metadata,则报错。
1142
+
1143
+ ```
1144
+ user_metadata = { "key1" => "value1" }
1145
+ options = {
1146
+ 'user-metadata' => user_metadata
1147
+ }
1148
+
1149
+ client.copy_object(bucket_name, object_name, bucket_name, object_name, options)
1150
+ puts client.get_object_meta_data(bucket_name, object_name)['user-metadata']['key1']
1151
+ ```
1152
+
1153
+ ## 拷贝Object
1154
+
1155
+ ### 拷贝一个文件
1156
+
1157
+ 用户可以通过copyObject方法拷贝一个Object,如下代码所示:
1158
+
1159
+ ```
1160
+ client.copy_object(source_bucket_name, source_object_key, target_bucket_name, target_object_key)
1161
+ ```
1162
+
1163
+ `copy_object`方法可以通过`options`配置可选参数,参数列表参考如下:
1164
+
1165
+ | 参数 | 说明 |
1166
+ | ------------- | ------------------------------------------------------------ |
1167
+ | user-metadata | 用户自定义Meta,包含Key-Value对 |
1168
+ | eTag | Source Object的eTag,若选择上传,则会对Target Object和Source Object的eTag进行比对,若不相同,则返回错误。 |
1169
+
1170
+ #### 同步Copy
1171
+
1172
+ 当前BOS的CopyObject接口是通过同步方式实现的。同步方式下,BOS端会等待Copy实际完成才返回成功。同步Copy能帮助用户更准确的判断Copy状态,但用户感知的复制时间会变长,且复制时间和文件大小成正比。
1173
+
1174
+ 同步Copy方式更符合业界常规,提升了与其它平台的兼容性。同步Copy方式还简化了BOS服务端的业务逻辑,提高了服务效率。
1175
+
1176
+ ### 分块拷贝
1177
+
1178
+ 除了通过CopyObject接⼝拷贝文件以外,BOS还提供了另外一种拷贝模式——Multipart Upload Copy。用户可以在如下的应用场景内(但不仅限于此),使用Multipart Upload Copy,如:
1179
+
1180
+ - 需要支持断点拷贝。
1181
+ - 拷贝超过5GB大小的文件。
1182
+ - 网络条件较差,和BOS的服务器之间的连接经常断开。
1183
+
1184
+ 下面将介绍分步实现三步拷贝。
1185
+
1186
+ 三步拷贝包含init、“拷贝分块”和complete三步,其中init和complete的操作同分块上传一致,可直接参考[初始化Multipart Upload](#初始化Multipart Upload)和[完成分块上传](#完成分块上传)。
1187
+
1188
+ ```
1189
+ left_size = client.get_object_meta_data(source_bucket_name, source_object_key)['content-length']
1190
+ offset = 0
1191
+ part_number = 1
1192
+ part_list = []
1193
+
1194
+ while left_size > 0 do
1195
+ part_size = 5 * 1024 * 1024
1196
+ if left_size < part_size
1197
+ part_size = left_size
1198
+ end
1199
+
1200
+ response = client.upload_part_copy(
1201
+ source_bucket_name, source_object_key, target_bucket_name, target_object_key, upload_id, part_number, part_size, offset)
1202
+ left_size -= part_size
1203
+ offset += part_size
1204
+ # your should store every part number and etag to invoke complete multi-upload
1205
+ part_list << {
1206
+ "partNumber" => part_number,
1207
+ "eTag" => response["eTag"]
1208
+ }
1209
+ part_number += 1
1210
+ end
1211
+ ```
1212
+
1213
+ > **注意:**
1214
+ > size参数以字节为单位,定义每个分块的大小,除最后一个Part以外,其他的Part大小都要大于5MB。
1215
+
1216
+ # 异常处理
1217
+
1218
+ BOS异常提示有如下四种方式:
1219
+
1220
+ | 异常方法 | 说明 |
1221
+ | ------------------ | ----------------- |
1222
+ | BceHttpException | 客户端异常 |
1223
+ | BceServerException | 服务器异常 |
1224
+ | BceHttpException | net::http相关异常 |
1225
+
1226
+ 用户可以使用rescue获取某个事件所产生的异常:
1227
+
1228
+ ```
1229
+ begin
1230
+ client.get_object_meta_data(bucket_name, object_name)
1231
+ rescue Exception => e
1232
+ puts "Catch a http exception" if e.is_a?(BceHttpException)
1233
+ puts "Catch a client exception" if e.is_a?(BceClientException)
1234
+ puts "Catch a server exception" if e.is_a?(BceServerException)
1235
+ end
1236
+ ```
1237
+
1238
+ ## 客户端异常
1239
+
1240
+ 客户端异常表示客户端尝试向BOS发送请求以及数据传输时遇到的异常。
1241
+
1242
+ ## 服务端异常
1243
+
1244
+ 当BOS服务端出现异常时,BOS服务端会返回给用户相应的错误信息,以便定位问题。常见服务端异常可参见[BOS错误信息格式](https://cloud.baidu.com/doc/BOS/API.html#.E9.94.99.E8.AF.AF.E4.BF.A1.E6.81.AF.E6.A0.BC.E5.BC.8F)
1245
+
1246
+ ## SDK日志
1247
+
1248
+ BOS Ruby SDK支持四个级别的日志(默认为`Logger::INFO`级别),支持设置输出日志文件的目录,详细可以参考`Log`模块。示例代码:
1249
+
1250
+ ```
1251
+ # 默认日志路径:DEFAULT_LOG_FILE = "./baidubce-sdk.log"
1252
+ Log.set_log_file(file_path)
1253
+
1254
+ # 四个日志级别:Logger::DEBUG | Logger::INFO | Logger::ERROR | Logger::FATAL
1255
+ Log.set_log_level(Logger::DEBUG)
1256
+ ```
1257
+
1258
+
1259
+
1260
+ # 版本变更记录
1261
+
1262
+ - Ruby SDK开发包[2018-05-21] 版本号 0.1.0
1263
+ - 创建、查看、罗列、删除Bucket,获取位置和判断是否存在
1264
+ - 支持管理Bucket的生命周期、日志、ACL、存储类型
1265
+ - 上传、下载、删除、罗列Object,支持追加上传、分块上传、分块拷贝
1266
+