overdue
This commit is contained in:
30
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/.gitignore
generated
vendored
Executable file
30
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/.gitignore
generated
vendored
Executable file
@@ -0,0 +1,30 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
||||
out
|
||||
gen
|
||||
vendor
|
||||
coverage
|
||||
release
|
||||
6
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/.gitmodules
generated
vendored
Executable file
6
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/.gitmodules
generated
vendored
Executable file
@@ -0,0 +1,6 @@
|
||||
[submodule "specs/qingstor"]
|
||||
path = specs/qingstor
|
||||
url = https://github.com/yunify/qingstor-api-specs.git
|
||||
[submodule "test/features"]
|
||||
path = test/features
|
||||
url = https://github.com/yunify/qingstor-sdk-test-scenarios.git
|
||||
55
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/.travis.yml
generated
vendored
Executable file
55
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/.travis.yml
generated
vendored
Executable file
@@ -0,0 +1,55 @@
|
||||
sudo: required
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
language: go
|
||||
go:
|
||||
- master
|
||||
- 1.9
|
||||
- 1.8
|
||||
- 1.7
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- ${HOME}/source
|
||||
|
||||
before_install:
|
||||
- pushd ${HOME}/source
|
||||
- if [[ ! -d "./make-4.0" ]]; then
|
||||
wget http://ftp.gnu.org/gnu/make/make-4.0.tar.gz &&
|
||||
tar -vxzf make-4.0.tar.gz &&
|
||||
pushd make-4.0 && ./configure && make && popd;
|
||||
fi
|
||||
- pushd make-4.0 && sudo make install && popd
|
||||
- if [[ ! -d "./glide-v0.12.3" ]]; then
|
||||
wget https://github.com/Masterminds/glide/releases/download/v0.12.3/glide-v0.12.3-linux-amd64.tar.gz &&
|
||||
tar -vxzf glide-v0.12.3-linux-amd64.tar.gz &&
|
||||
mv linux-amd64 glide-v0.12.3;
|
||||
fi
|
||||
- pushd glide-v0.12.3 && sudo cp glide /usr/local/bin && popd
|
||||
- if [[ ! -d "./snips-v0.2.8" ]]; then
|
||||
wget https://github.com/yunify/snips/releases/download/v0.2.8/snips-v0.2.8-linux_amd64.tar.gz &&
|
||||
mkdir snips-v0.2.8 &&
|
||||
pushd snips-v0.2.8 &&
|
||||
tar -vxzf ../snips-v0.2.8-linux_amd64.tar.gz &&
|
||||
popd;
|
||||
fi
|
||||
- pushd snips-v0.2.8 && sudo cp snips /usr/local/bin && popd
|
||||
- popd
|
||||
- /usr/local/bin/make --version
|
||||
- /usr/local/bin/glide --version
|
||||
|
||||
install:
|
||||
- go get -u github.com/golang/lint/golint;
|
||||
- glide install
|
||||
- git submodule init
|
||||
|
||||
before_script:
|
||||
- /usr/local/bin/make update
|
||||
- /usr/local/bin/make generate
|
||||
|
||||
script:
|
||||
- /usr/local/bin/make check
|
||||
- /usr/local/bin/make release
|
||||
- /usr/local/bin/make build test test-coverage
|
||||
4
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/AUTHORS
generated
vendored
Executable file
4
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/AUTHORS
generated
vendored
Executable file
@@ -0,0 +1,4 @@
|
||||
Patches have been contributed by (ordered by the time of the first merged patch):
|
||||
|
||||
Jingwen Peng <pengsrc@yunify.com>
|
||||
Osier Yang <osier@yunify.com>
|
||||
184
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/CHANGELOG.md
generated
vendored
Executable file
184
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/CHANGELOG.md
generated
vendored
Executable file
@@ -0,0 +1,184 @@
|
||||
# Change Log
|
||||
All notable changes to QingStor SDK for Go will be documented in this file.
|
||||
|
||||
## [v2.2.14] - 2018-6-9
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix head application/json file failed
|
||||
|
||||
## [v2.2.13] - 2018-5-31
|
||||
|
||||
### Added
|
||||
|
||||
- Add storage class support
|
||||
|
||||
## [v2.2.12] - 2018-4-8
|
||||
|
||||
### Changed
|
||||
|
||||
- Skip empty header while unpacking
|
||||
|
||||
## [v2.2.11] - 2018-3-28
|
||||
|
||||
### Changed
|
||||
|
||||
- Inject request id for HEAD request
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix a read timeout bug introduced in v2.2.10
|
||||
|
||||
## [v2.2.10] - 2018-3-14
|
||||
|
||||
### Changed
|
||||
|
||||
- Close body for every API except GetObject and ImageProcess
|
||||
- Add correct i/o timeout behavior for http client
|
||||
|
||||
## [v2.2.9] - 2017-11-25
|
||||
|
||||
### Changed
|
||||
|
||||
- Refactor logger.
|
||||
|
||||
## [v2.2.8] - 2017-09-25
|
||||
|
||||
### Added
|
||||
|
||||
- Support setting custom SDK logger.
|
||||
|
||||
## [v2.2.7] - 2017-09-01
|
||||
|
||||
### Added
|
||||
|
||||
- Support image process APIs.
|
||||
- Add advanced client for image process.
|
||||
|
||||
### Changed
|
||||
|
||||
- Force the zone ID to be lowercase.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Add support for the X-QS-Date header.
|
||||
|
||||
## [v2.2.6] - 2017-07-21
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix concurrency issue in object related operations.
|
||||
|
||||
## [v2.2.5] - 2017-05-22
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix error in request URL query.
|
||||
- Fix error in request header value.
|
||||
|
||||
## [v2.2.4] - 2017-03-28
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix type of Content-Type header.
|
||||
- Add Content-Length to GetObjectOutput.
|
||||
- Fix status code of DELETE CORS API.
|
||||
- Fix type of object size for GET Bucket API.
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
- The type of content length and object size has been changed from `*int` to `*int64`.
|
||||
|
||||
## [v2.2.3] - 2017-03-10
|
||||
|
||||
### Added
|
||||
|
||||
- Allow user to append additional info to User-Agent.
|
||||
|
||||
## [v2.2.2] - 2017-03-08
|
||||
|
||||
### Fixed
|
||||
|
||||
- Resource is not mandatory in bucket policy statement.
|
||||
|
||||
## [v2.2.1] - 2017-03-05
|
||||
|
||||
### Changed
|
||||
|
||||
- Add "Encrypted" field to "KeyType" struct.
|
||||
|
||||
## [v2.2.0] - 2017-02-28
|
||||
|
||||
### Added
|
||||
|
||||
- Add ListMultipartUploads API.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix request builder & signer.
|
||||
|
||||
## [v2.1.2] - 2017-01-16
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix request signer.
|
||||
|
||||
## [v2.1.1] - 2017-01-05
|
||||
|
||||
### Changed
|
||||
|
||||
- Fix logger output format, don't parse special characters.
|
||||
- Rename package "errs" to "errors".
|
||||
|
||||
### Added
|
||||
|
||||
- Add type converters.
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
- Change value type in input and output to pointer.
|
||||
|
||||
## [v2.1.0] - 2016-12-23
|
||||
|
||||
### Changed
|
||||
|
||||
- Fix signer bug.
|
||||
- Add more parameters to sign.
|
||||
|
||||
### Added
|
||||
|
||||
- Add request parameters for GET Object.
|
||||
- Add IP address conditions for bucket policy.
|
||||
|
||||
## [v2.0.1] - 2016-12-15
|
||||
|
||||
### Changed
|
||||
|
||||
- Improve the implementation of deleting multiple objects.
|
||||
|
||||
## [v2.0.0] - 2016-12-14
|
||||
|
||||
### Added
|
||||
|
||||
- QingStor SDK for the Go programming language.
|
||||
|
||||
[v2.2.14]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.13...v2.2.14
|
||||
[v2.2.13]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.12...v2.2.13
|
||||
[v2.2.12]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.11...v2.2.12
|
||||
[v2.2.11]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.10...v2.2.11
|
||||
[v2.2.10]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.9...v2.2.10
|
||||
[v2.2.9]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.8...v2.2.9
|
||||
[v2.2.8]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.7...v2.2.8
|
||||
[v2.2.7]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.6...v2.2.7
|
||||
[v2.2.6]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.5...v2.2.6
|
||||
[v2.2.5]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.4...v2.2.5
|
||||
[v2.2.4]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.3...v2.2.4
|
||||
[v2.2.3]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.2...v2.2.3
|
||||
[v2.2.2]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.1...v2.2.2
|
||||
[v2.2.1]: https://github.com/yunify/qingstor-sdk-go/compare/v2.2.0...v2.2.1
|
||||
[v2.2.0]: https://github.com/yunify/qingstor-sdk-go/compare/v2.1.2...v2.2.0
|
||||
[v2.1.2]: https://github.com/yunify/qingstor-sdk-go/compare/v2.1.1...v2.1.2
|
||||
[v2.1.1]: https://github.com/yunify/qingstor-sdk-go/compare/v2.1.0...v2.1.1
|
||||
[v2.1.0]: https://github.com/yunify/qingstor-sdk-go/compare/v2.0.1...v2.1.0
|
||||
[v2.0.1]: https://github.com/yunify/qingstor-sdk-go/compare/v2.0.0...v2.0.1
|
||||
[v2.0.0]: https://github.com/yunify/qingstor-sdk-go/compare/v2.0.0...v2.0.0
|
||||
201
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/LICENSE
generated
vendored
Executable file
201
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/LICENSE
generated
vendored
Executable file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2012 Yunify Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
1
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/MAINTAINERS
generated
vendored
Executable file
1
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/MAINTAINERS
generated
vendored
Executable file
@@ -0,0 +1 @@
|
||||
Jingwen Peng <pengsrc@yunify.com>
|
||||
124
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/Makefile
generated
vendored
Executable file
124
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/Makefile
generated
vendored
Executable file
@@ -0,0 +1,124 @@
|
||||
SHELL := /bin/bash
|
||||
|
||||
PREFIX=qingstor-sdk-go
|
||||
VERSION=$(shell cat version.go | grep "Version\ =" | sed -e s/^.*\ //g | sed -e s/\"//g)
|
||||
DIRS_TO_CHECK=$(shell ls -d */ | grep -vE "vendor|test")
|
||||
PKGS_TO_CHECK=$(shell go list ./... | grep -v "/vendor/")
|
||||
PKGS_TO_RELEASE=$(shell go list ./... | grep -vE "/vendor/|/test")
|
||||
FILES_TO_RELEASE=$(shell find . -name "*.go" | grep -vE "/vendor/|/test|.*_test.go")
|
||||
FILES_TO_RELEASE_WITH_VENDOR=$(shell find . -name "*.go" | grep -vE "/test|.*_test.go")
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo "Please use \`make <target>\` where <target> is one of"
|
||||
@echo " all to check, build, test and release this SDK"
|
||||
@echo " check to vet and lint the SDK"
|
||||
@echo " update to update git submodules"
|
||||
@echo " generate to generate service code"
|
||||
@echo " build to build the SDK"
|
||||
@echo " test to run test"
|
||||
@echo " test-coverage to run test with coverage"
|
||||
@echo " test-race to run test with race"
|
||||
@echo " integration-test to run integration test"
|
||||
@echo " release to build and release current version"
|
||||
@echo " release-source to pack the source code"
|
||||
@echo " clean to clean the coverage files"
|
||||
|
||||
.PHONY: all
|
||||
all: check build unit release
|
||||
|
||||
.PHONY: check
|
||||
check: vet lint format
|
||||
|
||||
.PHONY: format
|
||||
format:
|
||||
@echo "go fmt, skipping vendor packages"
|
||||
@for pkg in ${PKGS_TO_CHECK}; do go fmt $${pkg}; done;
|
||||
@echo "ok"
|
||||
|
||||
.PHONY: vet
|
||||
vet:
|
||||
@echo "Go tool vet, skipping vendor packages"
|
||||
@go tool vet -all ${DIRS_TO_CHECK}
|
||||
@echo "Done"
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
@echo "Golint, skipping vendor packages"
|
||||
@lint=$$(for pkg in ${PKGS_TO_CHECK}; do golint $${pkg}; done); \
|
||||
lint=$$(echo "$${lint}"); \
|
||||
if [[ -n $${lint} ]]; then echo "$${lint}"; exit 1; fi
|
||||
@echo "Done"
|
||||
|
||||
.PHONY: update
|
||||
update:
|
||||
git submodule update --remote
|
||||
@echo "Done"
|
||||
|
||||
.PHONY: generate
|
||||
generate:
|
||||
@if [[ ! -f "$$(which snips)" ]]; then \
|
||||
echo "ERROR: Command \"snips\" not found."; \
|
||||
fi
|
||||
snips -f="./specs/qingstor/2016-01-06/swagger/api_v2.0.json" -t="./template" -o="./service"
|
||||
gofmt -w .
|
||||
@echo "Done"
|
||||
|
||||
.PHONY: build
|
||||
build: format
|
||||
@echo "Build the SDK"
|
||||
go build ${PKGS_TO_RELEASE}
|
||||
@echo "Done"
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
@echo "Run test"
|
||||
go test -v ${PKGS_TO_RELEASE}
|
||||
@echo "Done"
|
||||
|
||||
.PHONY: test-coverage
|
||||
test-coverage:
|
||||
@echo "Run test with coverage"
|
||||
for pkg in ${PKGS_TO_RELEASE}; do \
|
||||
output="coverage$${pkg#github.com/yunify/qingstor-sdk-go}"; \
|
||||
mkdir -p $${output}; \
|
||||
go test -v -cover -coverprofile="$${output}/profile.out" $${pkg}; \
|
||||
if [[ -e "$${output}/profile.out" ]]; then \
|
||||
go tool cover -html="$${output}/profile.out" -o "$${output}/profile.html"; \
|
||||
fi; \
|
||||
done
|
||||
@echo "Done"
|
||||
|
||||
.PHONY: test-race
|
||||
test-race:
|
||||
@echo "Run test with race"
|
||||
go test -v -race -cpu=1,2,4 ${PKGS_TO_RELEASE}
|
||||
@echo "Done"
|
||||
|
||||
.PHONY: integration-test
|
||||
integration-test:
|
||||
@echo "Run integration test"
|
||||
pushd "./test"; go run *.go; popd
|
||||
@echo "Done"
|
||||
|
||||
.PHONY: release
|
||||
release: release-source release-source-with-vendor
|
||||
|
||||
.PHONY: release-source
|
||||
release-source:
|
||||
@echo "Pack the source code"
|
||||
mkdir -p "release"
|
||||
zip -FS "release/${PREFIX}-source-v${VERSION}.zip" ${FILES_TO_RELEASE}
|
||||
@echo "Done"
|
||||
|
||||
.PHONY: release-source-with-vendor
|
||||
release-source-with-vendor:
|
||||
@echo "Pack the source code with vendor"
|
||||
mkdir -p "release"
|
||||
zip -FS "release/${PREFIX}-source-with-vendor-v${VERSION}.zip" ${FILES_TO_RELEASE_WITH_VENDOR}
|
||||
@echo "Done"
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $${PWD}/coverage
|
||||
@echo "Done"
|
||||
84
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/README.md
generated
vendored
Executable file
84
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/README.md
generated
vendored
Executable file
@@ -0,0 +1,84 @@
|
||||
# QingStor SDK for Go
|
||||
|
||||
[](https://travis-ci.org/yunify/qingstor-sdk-go)
|
||||
[](https://goreportcard.com/report/github.com/yunify/qingstor-sdk-go)
|
||||
[](http://docs.qingcloud.com/qingstor/)
|
||||
[](https://github.com/yunify/qingstor-sdk-go/blob/master/LICENSE)
|
||||
|
||||
The official QingStor SDK for the Go programming language.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Installation
|
||||
|
||||
Refer to the [Installation Guide](docs/installation.md), and have this SDK installed.
|
||||
|
||||
### Preparation
|
||||
|
||||
Before your start, please go to [QingCloud Console](https://console.qingcloud.com/access_keys/) to create a pair of QingCloud API AccessKey.
|
||||
|
||||
___API AccessKey Example:___
|
||||
|
||||
``` yaml
|
||||
access_key_id: 'ACCESS_KEY_ID_EXAMPLE'
|
||||
secret_access_key: 'SECRET_ACCESS_KEY_EXAMPLE'
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
Now you are ready to code. You can read the detailed guides in the list below to have a clear understanding or just take the quick start code example.
|
||||
|
||||
Checkout our [releases](https://github.com/yunify/qingstor-sdk-go/releases) and [change log](https://github.com/yunify/qingstor-sdk-go/blob/master/CHANGELOG.md) for information about the latest features, bug fixes and new ideas.
|
||||
|
||||
- [Configuration Guide](docs/configuration.md)
|
||||
- [QingStor Service Usage Guide](docs/qingstor_service_usage.md)
|
||||
|
||||
___Quick Start Code Example:___
|
||||
|
||||
``` go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yunify/qingstor-sdk-go/config"
|
||||
qs "github.com/yunify/qingstor-sdk-go/service"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conf, _ := config.New("ACCESS_KEY_ID", "SECRET_ACCESS_KEY")
|
||||
|
||||
// Initialize service object for QingStor.
|
||||
qsService, _ := qs.Init(conf)
|
||||
|
||||
// List all buckets.
|
||||
qsOutput, _ := qsService.ListBuckets(&qs.ListBucketsInput{})
|
||||
|
||||
// Print HTTP status code.
|
||||
fmt.Println(qs.IntValue(qsOutput.StatusCode))
|
||||
|
||||
// Print the count of buckets.
|
||||
fmt.Println(qs.IntValue(qsOutput.Count))
|
||||
|
||||
// Print the first bucket name.
|
||||
fmt.Println(qs.StringValue(qsOutput.Buckets[0].Name))
|
||||
}
|
||||
```
|
||||
|
||||
## Reference Documentations
|
||||
|
||||
- [QingStor Documentation](https://docs.qingcloud.com/qingstor/index.html)
|
||||
- [QingStor Guide](https://docs.qingcloud.com/qingstor/guide/index.html)
|
||||
- [QingStor APIs](https://docs.qingcloud.com/qingstor/api/index.html)
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork it ( https://github.com/yunify/qingstor-sdk-go/fork )
|
||||
2. Create your feature branch (`git checkout -b new-feature`)
|
||||
3. Commit your changes (`git commit -asm 'Add some feature'`)
|
||||
4. Push to the branch (`git push origin new-feature`)
|
||||
5. Create a new Pull Request
|
||||
|
||||
## LICENSE
|
||||
|
||||
The Apache License (Version 2.0, January 2004).
|
||||
275
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/config/config.go
generated
vendored
Executable file
275
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/config/config.go
generated
vendored
Executable file
@@ -0,0 +1,275 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/yunify/qingstor-sdk-go/logger"
|
||||
"github.com/yunify/qingstor-sdk-go/utils"
|
||||
)
|
||||
|
||||
// A Config stores a configuration of this sdk.
|
||||
type Config struct {
|
||||
AccessKeyID string `yaml:"access_key_id"`
|
||||
SecretAccessKey string `yaml:"secret_access_key"`
|
||||
|
||||
Host string `yaml:"host"`
|
||||
Port int `yaml:"port"`
|
||||
Protocol string `yaml:"protocol"`
|
||||
ConnectionRetries int `yaml:"connection_retries"`
|
||||
|
||||
AdditionalUserAgent string `yaml:"additional_user_agent"`
|
||||
|
||||
LogLevel string `yaml:"log_level"`
|
||||
|
||||
HTTPSettings HTTPClientSettings
|
||||
|
||||
Connection *http.Client
|
||||
}
|
||||
|
||||
// HTTPClientSettings is the http client settings.
|
||||
type HTTPClientSettings struct {
|
||||
|
||||
// ConnectTimeout affects making new socket connection
|
||||
ConnectTimeout time.Duration `yaml:"connect_timeout"`
|
||||
|
||||
// ReadTimeout affect each call to HTTPResponse.Body.Read()
|
||||
ReadTimeout time.Duration `yaml:"read_timeout"`
|
||||
|
||||
// WriteTimeout affect each write in io.Copy while sending HTTPRequest
|
||||
WriteTimeout time.Duration `yaml:"write_timeout" `
|
||||
|
||||
// TLSHandshakeTimeout affects https hand shake timeout
|
||||
TLSHandshakeTimeout time.Duration `yaml:"tls_timeout"`
|
||||
|
||||
// IdleConnTimeout affects the time limit to re-use http connections
|
||||
IdleConnTimeout time.Duration `yaml:"idle_timeout"`
|
||||
|
||||
TCPKeepAlive time.Duration `yaml:"tcp_keepalive_time"`
|
||||
|
||||
DualStack bool `yaml:"dual_stack"`
|
||||
|
||||
// MaxIdleConns affects the idle connections kept for re-use
|
||||
MaxIdleConns int `yaml:"max_idle_conns"`
|
||||
|
||||
MaxIdleConnsPerHost int `yaml:"max_idle_conns_per_host"`
|
||||
|
||||
ExpectContinueTimeout time.Duration `yaml:"expect_continue_timeout"`
|
||||
}
|
||||
|
||||
// DefaultHTTPClientSettings is the default http client settings.
|
||||
var DefaultHTTPClientSettings = HTTPClientSettings{
|
||||
ConnectTimeout: time.Second * 30,
|
||||
ReadTimeout: time.Second * 30,
|
||||
WriteTimeout: time.Second * 30,
|
||||
TLSHandshakeTimeout: time.Second * 10,
|
||||
IdleConnTimeout: time.Second * 20,
|
||||
TCPKeepAlive: 0,
|
||||
DualStack: false,
|
||||
MaxIdleConns: 100,
|
||||
MaxIdleConnsPerHost: 10,
|
||||
ExpectContinueTimeout: time.Second * 2,
|
||||
}
|
||||
|
||||
// New create a Config with given AccessKeyID and SecretAccessKey.
|
||||
func New(accessKeyID, secretAccessKey string) (c *Config, err error) {
|
||||
c, err = NewDefault()
|
||||
if err != nil {
|
||||
c = nil
|
||||
return
|
||||
}
|
||||
c.AccessKeyID = accessKeyID
|
||||
c.SecretAccessKey = secretAccessKey
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// NewDefault create a Config with default configuration.
|
||||
func NewDefault() (c *Config, err error) {
|
||||
c = &Config{}
|
||||
err = c.LoadDefaultConfig()
|
||||
if err != nil {
|
||||
c = nil
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Check checks the configuration.
|
||||
func (c *Config) Check() (err error) {
|
||||
if c.AccessKeyID == "" {
|
||||
err = errors.New("access key ID not specified")
|
||||
return
|
||||
}
|
||||
if c.SecretAccessKey == "" {
|
||||
err = errors.New("secret access key not specified")
|
||||
return
|
||||
}
|
||||
|
||||
if c.Host == "" {
|
||||
err = errors.New("server host not specified")
|
||||
return
|
||||
}
|
||||
if c.Port <= 0 {
|
||||
err = errors.New("server port not specified")
|
||||
return
|
||||
}
|
||||
if c.Protocol == "" {
|
||||
err = errors.New("server protocol not specified")
|
||||
return
|
||||
}
|
||||
|
||||
if c.AdditionalUserAgent != "" {
|
||||
for _, x := range c.AdditionalUserAgent {
|
||||
// Allow space(32) to ~(126) in ASCII Table, exclude "(34).
|
||||
if int(x) < 32 || int(x) > 126 || int(x) == 32 || int(x) == 34 {
|
||||
err = errors.New("additional User-Agent contains characters that not allowed")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = logger.CheckLevel(c.LogLevel)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// LoadDefaultConfig loads the default configuration for Config.
|
||||
// It returns error if yaml decode failed.
|
||||
func (c *Config) LoadDefaultConfig() (err error) {
|
||||
|
||||
c.HTTPSettings = DefaultHTTPClientSettings
|
||||
|
||||
err = yaml.Unmarshal([]byte(DefaultConfigFileContent), c)
|
||||
if err != nil {
|
||||
logger.Errorf(nil, "Config parse error, %v.", err)
|
||||
return
|
||||
}
|
||||
|
||||
logger.SetLevel(c.LogLevel)
|
||||
|
||||
c.InitHTTPClient()
|
||||
return
|
||||
}
|
||||
|
||||
// LoadUserConfig loads user configuration in ~/.qingstor/config.yaml for Config.
|
||||
// It returns error if file not found.
|
||||
func (c *Config) LoadUserConfig() (err error) {
|
||||
_, err = os.Stat(GetUserConfigFilePath())
|
||||
if err != nil {
|
||||
logger.Warnf(nil, "Installing default config file to %s.", GetUserConfigFilePath())
|
||||
InstallDefaultUserConfig()
|
||||
}
|
||||
|
||||
return c.LoadConfigFromFilePath(GetUserConfigFilePath())
|
||||
}
|
||||
|
||||
// LoadConfigFromFilePath loads configuration from a specified local path.
|
||||
// It returns error if file not found or yaml decode failed.
|
||||
func (c *Config) LoadConfigFromFilePath(filePath string) (err error) {
|
||||
if strings.Index(filePath, "~/") == 0 {
|
||||
filePath = strings.Replace(filePath, "~/", getHome()+"/", 1)
|
||||
}
|
||||
|
||||
yamlString, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
logger.Errorf(nil, "File not found: %s.", filePath)
|
||||
return err
|
||||
}
|
||||
|
||||
return c.LoadConfigFromContent(yamlString)
|
||||
}
|
||||
|
||||
// LoadConfigFromContent loads configuration from a given byte slice.
|
||||
// It returns error if yaml decode failed.
|
||||
func (c *Config) LoadConfigFromContent(content []byte) (err error) {
|
||||
c.LoadDefaultConfig()
|
||||
|
||||
err = yaml.Unmarshal(content, c)
|
||||
if err != nil {
|
||||
logger.Errorf(nil, "Config parse error, %v.", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = c.Check()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
logger.SetLevel(c.LogLevel)
|
||||
|
||||
c.InitHTTPClient()
|
||||
return
|
||||
}
|
||||
|
||||
// InitHTTPClient : After modifying Config.HTTPSettings, you should always call this to initialize the HTTP Client.
|
||||
func (c *Config) InitHTTPClient() {
|
||||
var emptySettings HTTPClientSettings
|
||||
|
||||
if c.HTTPSettings == emptySettings { // User forgot to initialize the settings
|
||||
c.HTTPSettings = DefaultHTTPClientSettings
|
||||
} else {
|
||||
if c.HTTPSettings.ConnectTimeout == 0 {
|
||||
c.HTTPSettings.ConnectTimeout = DefaultHTTPClientSettings.ConnectTimeout
|
||||
}
|
||||
// If ReadTimeout and WriteTimeout is zero, means no read/write timeout
|
||||
if c.HTTPSettings.TLSHandshakeTimeout == 0 {
|
||||
c.HTTPSettings.TLSHandshakeTimeout = DefaultHTTPClientSettings.TLSHandshakeTimeout
|
||||
}
|
||||
if c.HTTPSettings.ExpectContinueTimeout == 0 {
|
||||
c.HTTPSettings.ExpectContinueTimeout = DefaultHTTPClientSettings.ExpectContinueTimeout
|
||||
}
|
||||
}
|
||||
dialer := utils.NewDialer(
|
||||
c.HTTPSettings.ConnectTimeout,
|
||||
c.HTTPSettings.ReadTimeout,
|
||||
c.HTTPSettings.WriteTimeout,
|
||||
)
|
||||
dialer.KeepAlive = c.HTTPSettings.TCPKeepAlive
|
||||
// XXX: DualStack enables RFC 6555-compliant "Happy Eyeballs" dialing
|
||||
// when the network is "tcp" and the destination is a host name
|
||||
// with both IPv4 and IPv6 addresses. This allows a client to
|
||||
// tolerate networks where one address family is silently broken
|
||||
dialer.DualStack = c.HTTPSettings.DualStack
|
||||
c.Connection = &http.Client{
|
||||
// We do not use the timeout in http client,
|
||||
// because this timeout is for the whole http body read/write,
|
||||
// it's unsuitable for various length of files and network condition.
|
||||
// We provide a wraper in utils/conn.go of net.Dialer to make io timeout to the http connection
|
||||
// for individual buffer I/O operation,
|
||||
Timeout: 0,
|
||||
Transport: &http.Transport{
|
||||
DialContext: dialer.DialContext,
|
||||
MaxIdleConns: c.HTTPSettings.MaxIdleConns,
|
||||
MaxIdleConnsPerHost: c.HTTPSettings.MaxIdleConnsPerHost,
|
||||
IdleConnTimeout: c.HTTPSettings.IdleConnTimeout,
|
||||
TLSHandshakeTimeout: c.HTTPSettings.TLSHandshakeTimeout,
|
||||
ExpectContinueTimeout: c.HTTPSettings.ExpectContinueTimeout,
|
||||
},
|
||||
}
|
||||
}
|
||||
74
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/config/contract.go
generated
vendored
Executable file
74
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/config/contract.go
generated
vendored
Executable file
@@ -0,0 +1,74 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// DefaultConfigFileContent is the content of default config file.
|
||||
const DefaultConfigFileContent = `# QingStor services configuration
|
||||
|
||||
#access_key_id: ACCESS_KEY_ID
|
||||
#secret_access_key: SECRET_ACCESS_KEY
|
||||
|
||||
host: qingstor.com
|
||||
port: 443
|
||||
protocol: https
|
||||
connection_retries: 3
|
||||
|
||||
# Additional User-Agent
|
||||
additional_user_agent: ""
|
||||
|
||||
# Valid log levels are "debug", "info", "warn", "error", and "fatal".
|
||||
log_level: warn
|
||||
|
||||
`
|
||||
|
||||
// DefaultConfigFile is the filename of default config file.
|
||||
const DefaultConfigFile = "~/.qingstor/config.yaml"
|
||||
|
||||
// GetUserConfigFilePath returns the user config file path.
|
||||
func GetUserConfigFilePath() string {
|
||||
return strings.Replace(DefaultConfigFile, "~/", getHome()+"/", 1)
|
||||
}
|
||||
|
||||
// InstallDefaultUserConfig will install default config file.
|
||||
func InstallDefaultUserConfig() error {
|
||||
err := os.MkdirAll(path.Dir(GetUserConfigFilePath()), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(GetUserConfigFilePath(), []byte(DefaultConfigFileContent), 0644)
|
||||
}
|
||||
|
||||
func getHome() string {
|
||||
home := os.Getenv("HOME")
|
||||
if runtime.GOOS == "windows" {
|
||||
home = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
|
||||
if home == "" {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
}
|
||||
|
||||
return home
|
||||
}
|
||||
32
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/glide.lock
generated
vendored
Executable file
32
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/glide.lock
generated
vendored
Executable file
@@ -0,0 +1,32 @@
|
||||
hash: 6e1d4e547cdd58944ef920192480d29edd118cac0e8269d793315066d1249b4e
|
||||
updated: 2018-05-10T11:43:20.637418+08:00
|
||||
imports:
|
||||
- name: github.com/DATA-DOG/godog
|
||||
version: 272624afcc2fc5f818ce069e2e417e7b4fa8bb6c
|
||||
subpackages:
|
||||
- colors
|
||||
- gherkin
|
||||
- name: github.com/pengsrc/go-shared
|
||||
version: db9bcfc423552eef790d989bb81ef055d0d26286
|
||||
subpackages:
|
||||
- buffer
|
||||
- check
|
||||
- convert
|
||||
- log
|
||||
- reopen
|
||||
- name: gopkg.in/yaml.v2
|
||||
version: 287cf08546ab5e7e37d55a84f7ed3fd1db036de5
|
||||
repo: https://github.com/go-yaml/yaml.git
|
||||
testImports:
|
||||
- name: github.com/davecgh/go-spew
|
||||
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
|
||||
subpackages:
|
||||
- spew
|
||||
- name: github.com/pmezard/go-difflib
|
||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||
subpackages:
|
||||
- difflib
|
||||
- name: github.com/stretchr/testify
|
||||
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
|
||||
subpackages:
|
||||
- assert
|
||||
11
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/glide.yaml
generated
vendored
Executable file
11
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/glide.yaml
generated
vendored
Executable file
@@ -0,0 +1,11 @@
|
||||
package: github.com/yunify/qingstor-sdk-go
|
||||
import:
|
||||
|
||||
# YAML
|
||||
- package: gopkg.in/yaml.v2
|
||||
version: 287cf08546ab5e7e37d55a84f7ed3fd1db036de5
|
||||
repo: https://github.com/go-yaml/yaml.git
|
||||
|
||||
# Shared packages
|
||||
- package: github.com/pengsrc/go-shared
|
||||
version: db9bcfc423552eef790d989bb81ef055d0d26286
|
||||
102
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/logger/logger.go
generated
vendored
Executable file
102
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/logger/logger.go
generated
vendored
Executable file
@@ -0,0 +1,102 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
// Package logger provides support for logging to stdout and stderr.
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/pengsrc/go-shared/log"
|
||||
)
|
||||
|
||||
// Logger is the interface of SDK logger.
|
||||
type Logger interface {
|
||||
Debugf(ctx context.Context, format string, v ...interface{})
|
||||
Infof(ctx context.Context, format string, v ...interface{})
|
||||
Warnf(ctx context.Context, format string, v ...interface{})
|
||||
Errorf(ctx context.Context, format string, v ...interface{})
|
||||
Fatalf(ctx context.Context, format string, v ...interface{})
|
||||
Panicf(ctx context.Context, format string, v ...interface{})
|
||||
}
|
||||
|
||||
// CheckLevel checks whether the log level is valid.
|
||||
func CheckLevel(level string) error {
|
||||
if _, err := log.ParseLevel(level); err != nil {
|
||||
return fmt.Errorf(`log level not valid: "%s"`, level)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetLevel get the log level string.
|
||||
func GetLevel() string {
|
||||
if l, ok := instance.(*log.Logger); ok {
|
||||
return l.GetLevel()
|
||||
}
|
||||
return "UNKNOWN"
|
||||
}
|
||||
|
||||
// SetLevel sets the log level.
|
||||
// Valid levels are "debug", "info", "warn", "error", and "fatal".
|
||||
func SetLevel(level string) {
|
||||
if l, ok := instance.(*log.Logger); ok {
|
||||
err := l.SetLevel(level)
|
||||
if err != nil {
|
||||
Fatalf(nil, fmt.Sprintf(`log level not valid: "%s"`, level))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetLogger sets the a logger as SDK logger.
|
||||
func SetLogger(l Logger) {
|
||||
instance = l
|
||||
}
|
||||
|
||||
// Debugf logs a message with severity DEBUG.
|
||||
func Debugf(ctx context.Context, format string, v ...interface{}) {
|
||||
instance.Debugf(ctx, format, v...)
|
||||
}
|
||||
|
||||
// Infof logs a message with severity INFO.
|
||||
func Infof(ctx context.Context, format string, v ...interface{}) {
|
||||
instance.Infof(ctx, format, v...)
|
||||
}
|
||||
|
||||
// Warnf logs a message with severity WARN.
|
||||
func Warnf(ctx context.Context, format string, v ...interface{}) {
|
||||
instance.Warnf(ctx, format, v...)
|
||||
}
|
||||
|
||||
// Errorf logs a message with severity ERROR.
|
||||
func Errorf(ctx context.Context, format string, v ...interface{}) {
|
||||
instance.Errorf(ctx, format, v...)
|
||||
}
|
||||
|
||||
// Fatalf logs a message with severity ERROR followed by a call to os.Exit().
|
||||
func Fatalf(ctx context.Context, format string, v ...interface{}) {
|
||||
instance.Fatalf(ctx, format, v...)
|
||||
}
|
||||
|
||||
var instance Logger
|
||||
|
||||
func init() {
|
||||
l, err := log.NewTerminalLogger(log.WarnLevel.String())
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to initialize QingStor SDK logger: %v", err))
|
||||
}
|
||||
instance = l
|
||||
}
|
||||
291
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/builder/base.go
generated
vendored
Executable file
291
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/builder/base.go
generated
vendored
Executable file
@@ -0,0 +1,291 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/pengsrc/go-shared/convert"
|
||||
|
||||
"github.com/yunify/qingstor-sdk-go/request/data"
|
||||
"github.com/yunify/qingstor-sdk-go/utils"
|
||||
)
|
||||
|
||||
// BaseBuilder is the base builder for all services.
|
||||
type BaseBuilder struct {
|
||||
parsedURL string
|
||||
parsedProperties *map[string]string
|
||||
parsedQuery *map[string]string
|
||||
parsedHeaders *map[string]string
|
||||
parsedBodyString string
|
||||
parsedBody io.Reader
|
||||
|
||||
operation *data.Operation
|
||||
input *reflect.Value
|
||||
}
|
||||
|
||||
// BuildHTTPRequest builds http request with an operation and an input.
|
||||
func (b *BaseBuilder) BuildHTTPRequest(o *data.Operation, i *reflect.Value) (*http.Request, error) {
|
||||
b.operation = o
|
||||
b.input = i
|
||||
|
||||
_, err := b.parse()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return b.build()
|
||||
}
|
||||
|
||||
func (b *BaseBuilder) build() (*http.Request, error) {
|
||||
httpRequest, err := http.NewRequest(b.operation.RequestMethod, b.parsedURL, b.parsedBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = b.setupHeaders(httpRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return httpRequest, nil
|
||||
}
|
||||
|
||||
func (b *BaseBuilder) parse() (*BaseBuilder, error) {
|
||||
err := b.parseRequestQueryAndHeaders()
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
err = b.parseRequestBody()
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
err = b.parseRequestProperties()
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
err = b.parseRequestURL()
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (b *BaseBuilder) parseRequestQueryAndHeaders() error {
|
||||
requestQuery := map[string]string{}
|
||||
requestHeaders := map[string]string{}
|
||||
maps := map[string](map[string]string){
|
||||
"query": requestQuery,
|
||||
"headers": requestHeaders,
|
||||
}
|
||||
|
||||
b.parsedQuery = &requestQuery
|
||||
b.parsedHeaders = &requestHeaders
|
||||
|
||||
if !b.input.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
fields := b.input.Elem()
|
||||
if !fields.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < fields.NumField(); i++ {
|
||||
tagName := fields.Type().Field(i).Tag.Get("name")
|
||||
tagLocation := fields.Type().Field(i).Tag.Get("location")
|
||||
if tagDefault := fields.Type().Field(i).Tag.Get("default"); tagDefault != "" {
|
||||
maps[tagLocation][tagName] = tagDefault
|
||||
}
|
||||
if tagName != "" && tagLocation != "" && maps[tagLocation] != nil {
|
||||
switch value := fields.Field(i).Interface().(type) {
|
||||
case *string:
|
||||
if value != nil {
|
||||
maps[tagLocation][tagName] = *value
|
||||
}
|
||||
case *int:
|
||||
if value != nil {
|
||||
maps[tagLocation][tagName] = strconv.Itoa(int(*value))
|
||||
}
|
||||
case *int64:
|
||||
if value != nil {
|
||||
maps[tagLocation][tagName] = strconv.FormatInt(int64(*value), 10)
|
||||
}
|
||||
case *bool:
|
||||
case *time.Time:
|
||||
if value != nil {
|
||||
formatString := fields.Type().Field(i).Tag.Get("format")
|
||||
format := ""
|
||||
switch formatString {
|
||||
case "RFC 822":
|
||||
format = convert.RFC822
|
||||
case "ISO 8601":
|
||||
format = convert.ISO8601
|
||||
}
|
||||
maps[tagLocation][tagName] = convert.TimeToString(*value, format)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BaseBuilder) parseRequestBody() error {
|
||||
requestData := map[string]interface{}{}
|
||||
|
||||
if !b.input.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
fields := b.input.Elem()
|
||||
if !fields.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < fields.NumField(); i++ {
|
||||
location := fields.Type().Field(i).Tag.Get("location")
|
||||
if location == "elements" {
|
||||
name := fields.Type().Field(i).Tag.Get("name")
|
||||
requestData[name] = fields.Field(i).Interface()
|
||||
}
|
||||
}
|
||||
|
||||
if len(requestData) != 0 {
|
||||
dataValue, err := json.Marshal(requestData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.parsedBodyString = string(dataValue)
|
||||
b.parsedBody = strings.NewReader(b.parsedBodyString)
|
||||
(*b.parsedHeaders)["Content-Type"] = "application/json"
|
||||
} else {
|
||||
value := fields.FieldByName("Body")
|
||||
if value.IsValid() {
|
||||
switch value.Interface().(type) {
|
||||
case string:
|
||||
if value.String() != "" {
|
||||
b.parsedBodyString = value.String()
|
||||
b.parsedBody = strings.NewReader(value.String())
|
||||
}
|
||||
case io.Reader:
|
||||
if value.Interface().(io.Reader) != nil {
|
||||
b.parsedBody = value.Interface().(io.Reader)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BaseBuilder) parseRequestProperties() error {
|
||||
propertiesMap := map[string]string{}
|
||||
b.parsedProperties = &propertiesMap
|
||||
|
||||
if b.operation.Properties != nil {
|
||||
fields := reflect.ValueOf(b.operation.Properties).Elem()
|
||||
if fields.IsValid() {
|
||||
for i := 0; i < fields.NumField(); i++ {
|
||||
switch value := fields.Field(i).Interface().(type) {
|
||||
case *string:
|
||||
if value != nil {
|
||||
propertiesMap[fields.Type().Field(i).Tag.Get("name")] = *value
|
||||
}
|
||||
case *int:
|
||||
if value != nil {
|
||||
numberString := strconv.Itoa(int(*value))
|
||||
propertiesMap[fields.Type().Field(i).Tag.Get("name")] = numberString
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BaseBuilder) parseRequestURL() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BaseBuilder) setupHeaders(httpRequest *http.Request) error {
|
||||
if b.parsedHeaders != nil {
|
||||
|
||||
for headerKey, headerValue := range *b.parsedHeaders {
|
||||
for _, r := range headerValue {
|
||||
if r > unicode.MaxASCII {
|
||||
headerValue = utils.URLQueryEscape(headerValue)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
httpRequest.Header.Set(headerKey, headerValue)
|
||||
}
|
||||
}
|
||||
|
||||
if httpRequest.Header.Get("Content-Length") == "" {
|
||||
var length int64
|
||||
switch body := b.parsedBody.(type) {
|
||||
case nil:
|
||||
length = 0
|
||||
case io.Seeker:
|
||||
//start, err := body.Seek(0, io.SeekStart)
|
||||
start, err := body.Seek(0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//end, err := body.Seek(0, io.SeekEnd)
|
||||
end, err := body.Seek(0, 2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//body.Seek(0, io.SeekStart)
|
||||
body.Seek(0, 0)
|
||||
length = end - start
|
||||
default:
|
||||
return errors.New("can not get Content-Length")
|
||||
}
|
||||
if length > 0 {
|
||||
httpRequest.ContentLength = length
|
||||
httpRequest.Header.Set("Content-Length", strconv.Itoa(int(length)))
|
||||
} else {
|
||||
httpRequest.Header.Set("Content-Length", "0")
|
||||
}
|
||||
}
|
||||
length, err := strconv.Atoi(httpRequest.Header.Get("Content-Length"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
httpRequest.ContentLength = int64(length)
|
||||
|
||||
if httpRequest.Header.Get("Date") == "" {
|
||||
httpRequest.Header.Set("Date", convert.TimeToString(time.Now(), convert.RFC822))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
175
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/builder/qingstor.go
generated
vendored
Executable file
175
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/builder/qingstor.go
generated
vendored
Executable file
@@ -0,0 +1,175 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pengsrc/go-shared/convert"
|
||||
|
||||
"github.com/yunify/qingstor-sdk-go"
|
||||
"github.com/yunify/qingstor-sdk-go/logger"
|
||||
"github.com/yunify/qingstor-sdk-go/request/data"
|
||||
"github.com/yunify/qingstor-sdk-go/utils"
|
||||
)
|
||||
|
||||
// QingStorBuilder is the request builder for QingStor service.
|
||||
type QingStorBuilder struct {
|
||||
baseBuilder *BaseBuilder
|
||||
}
|
||||
|
||||
// BuildHTTPRequest builds http request with an operation and an input.
|
||||
func (qb *QingStorBuilder) BuildHTTPRequest(o *data.Operation, i *reflect.Value) (*http.Request, error) {
|
||||
qb.baseBuilder = &BaseBuilder{}
|
||||
qb.baseBuilder.operation = o
|
||||
qb.baseBuilder.input = i
|
||||
|
||||
_, err := qb.baseBuilder.parse()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = qb.parseURL()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
httpRequest, err := http.NewRequest(qb.baseBuilder.operation.RequestMethod,
|
||||
qb.baseBuilder.parsedURL, qb.baseBuilder.parsedBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = qb.baseBuilder.setupHeaders(httpRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = qb.setupHeaders(httpRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logger.Infof(nil, fmt.Sprintf(
|
||||
"Built QingStor request: [%d] %s",
|
||||
convert.StringToTimestamp(httpRequest.Header.Get("Date"), convert.RFC822),
|
||||
httpRequest.URL.String(),
|
||||
))
|
||||
|
||||
logger.Infof(nil, fmt.Sprintf(
|
||||
"QingStor request headers: [%d] %s",
|
||||
convert.StringToTimestamp(httpRequest.Header.Get("Date"), convert.RFC822),
|
||||
fmt.Sprint(httpRequest.Header),
|
||||
))
|
||||
|
||||
if qb.baseBuilder.parsedBodyString != "" {
|
||||
logger.Infof(nil, fmt.Sprintf(
|
||||
"QingStor request body string: [%d] %s",
|
||||
convert.StringToTimestamp(httpRequest.Header.Get("Date"), convert.RFC822),
|
||||
qb.baseBuilder.parsedBodyString,
|
||||
))
|
||||
}
|
||||
|
||||
return httpRequest, nil
|
||||
}
|
||||
|
||||
func (qb *QingStorBuilder) parseURL() error {
|
||||
config := qb.baseBuilder.operation.Config
|
||||
|
||||
zone := (*qb.baseBuilder.parsedProperties)["zone"]
|
||||
port := strconv.Itoa(config.Port)
|
||||
endpoint := config.Protocol + "://" + config.Host + ":" + port
|
||||
if zone != "" {
|
||||
endpoint = config.Protocol + "://" + zone + "." + config.Host + ":" + port
|
||||
}
|
||||
|
||||
requestURI := qb.baseBuilder.operation.RequestURI
|
||||
for key, value := range *qb.baseBuilder.parsedProperties {
|
||||
endpoint = strings.Replace(endpoint, "<"+key+">", utils.URLQueryEscape(value), -1)
|
||||
requestURI = strings.Replace(requestURI, "<"+key+">", utils.URLQueryEscape(value), -1)
|
||||
}
|
||||
requestURI = regexp.MustCompile(`/+`).ReplaceAllString(requestURI, "/")
|
||||
|
||||
requestURL, err := url.Parse(endpoint + requestURI)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if qb.baseBuilder.parsedQuery != nil {
|
||||
queryValue := requestURL.Query()
|
||||
for key, value := range *qb.baseBuilder.parsedQuery {
|
||||
queryValue.Set(key, value)
|
||||
}
|
||||
requestURL.RawQuery = queryValue.Encode()
|
||||
}
|
||||
|
||||
qb.baseBuilder.parsedURL = requestURL.String()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (qb *QingStorBuilder) setupHeaders(httpRequest *http.Request) error {
|
||||
method := httpRequest.Method
|
||||
if method == "POST" || method == "PUT" || method == "DELETE" {
|
||||
if httpRequest.Header.Get("Content-Type") == "" {
|
||||
mimeType := mime.TypeByExtension(path.Ext(httpRequest.URL.Path))
|
||||
if mimeType != "" {
|
||||
httpRequest.Header.Set("Content-Type", mimeType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if httpRequest.Header.Get("User-Agent") == "" {
|
||||
version := fmt.Sprintf(`Go v%s`, strings.Replace(runtime.Version(), "go", "", -1))
|
||||
system := fmt.Sprintf(`%s_%s_%s`, runtime.GOOS, runtime.GOARCH, runtime.Compiler)
|
||||
ua := fmt.Sprintf(`qingstor-sdk-go/%s (%s; %s)`, sdk.Version, version, system)
|
||||
if qb.baseBuilder.operation.Config.AdditionalUserAgent != "" {
|
||||
ua = fmt.Sprintf(`%s %s`, ua, qb.baseBuilder.operation.Config.AdditionalUserAgent)
|
||||
}
|
||||
httpRequest.Header.Set("User-Agent", ua)
|
||||
}
|
||||
|
||||
if s := httpRequest.Header.Get("X-QS-Fetch-Source"); s != "" {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid HTTP header value: %s", s)
|
||||
}
|
||||
httpRequest.Header.Set("X-QS-Fetch-Source", u.String())
|
||||
}
|
||||
|
||||
if qb.baseBuilder.operation.APIName == "Delete Multiple Objects" {
|
||||
buffer := &bytes.Buffer{}
|
||||
buffer.ReadFrom(httpRequest.Body)
|
||||
httpRequest.Body = ioutil.NopCloser(bytes.NewReader(buffer.Bytes()))
|
||||
|
||||
md5Value := md5.Sum(buffer.Bytes())
|
||||
httpRequest.Header.Set("Content-MD5", base64.StdEncoding.EncodeToString(md5Value[:]))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
22
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/data/input.go
generated
vendored
Executable file
22
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/data/input.go
generated
vendored
Executable file
@@ -0,0 +1,22 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package data
|
||||
|
||||
// Input defines the interfaces that input should implement.
|
||||
type Input interface {
|
||||
Validation
|
||||
}
|
||||
35
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/data/operation.go
generated
vendored
Executable file
35
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/data/operation.go
generated
vendored
Executable file
@@ -0,0 +1,35 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package data
|
||||
|
||||
import (
|
||||
"github.com/yunify/qingstor-sdk-go/config"
|
||||
)
|
||||
|
||||
// Operation stores information of an operation.
|
||||
type Operation struct {
|
||||
Config *config.Config
|
||||
Properties interface{}
|
||||
|
||||
APIName string
|
||||
ServiceName string
|
||||
|
||||
RequestMethod string
|
||||
RequestURI string
|
||||
|
||||
StatusCodes []int
|
||||
}
|
||||
22
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/data/validation.go
generated
vendored
Executable file
22
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/data/validation.go
generated
vendored
Executable file
@@ -0,0 +1,22 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package data
|
||||
|
||||
// Validation defines the validate interface.
|
||||
type Validation interface {
|
||||
Validate() error
|
||||
}
|
||||
53
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/errors/parameters.go
generated
vendored
Executable file
53
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/errors/parameters.go
generated
vendored
Executable file
@@ -0,0 +1,53 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ParameterRequiredError indicates that the required parameter is missing.
|
||||
type ParameterRequiredError struct {
|
||||
ParameterName string
|
||||
ParentName string
|
||||
}
|
||||
|
||||
// Error returns the description of ParameterRequiredError.
|
||||
func (e ParameterRequiredError) Error() string {
|
||||
return fmt.Sprintf(`"%s" is required in "%s"`, e.ParameterName, e.ParentName)
|
||||
}
|
||||
|
||||
// ParameterValueNotAllowedError indicates that the parameter value is not allowed.
|
||||
type ParameterValueNotAllowedError struct {
|
||||
ParameterName string
|
||||
ParameterValue string
|
||||
AllowedValues []string
|
||||
}
|
||||
|
||||
// Error returns the description of ParameterValueNotAllowedError.
|
||||
func (e ParameterValueNotAllowedError) Error() string {
|
||||
allowedValues := []string{}
|
||||
for _, value := range e.AllowedValues {
|
||||
allowedValues = append(allowedValues, "\""+value+"\"")
|
||||
}
|
||||
return fmt.Sprintf(
|
||||
`"%s" value "%s" is not allowed, should be one of %s`,
|
||||
e.ParameterName,
|
||||
e.ParameterValue,
|
||||
strings.Join(allowedValues, ", "))
|
||||
}
|
||||
36
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/errors/qingstor.go
generated
vendored
Executable file
36
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/errors/qingstor.go
generated
vendored
Executable file
@@ -0,0 +1,36 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package errors
|
||||
|
||||
import "fmt"
|
||||
|
||||
// QingStorError stores information of an QingStor error response.
|
||||
type QingStorError struct {
|
||||
StatusCode int
|
||||
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
RequestID string `json:"request_id"`
|
||||
ReferenceURL string `json:"url"`
|
||||
}
|
||||
|
||||
// Error returns the description of QingStor error response.
|
||||
func (qse QingStorError) Error() string {
|
||||
return fmt.Sprintf(
|
||||
"QingStor Error: StatusCode \"%d\", Code \"%s\", Message \"%s\", Request ID \"%s\", Reference URL \"%s\"",
|
||||
qse.StatusCode, qse.Code, qse.Message, qse.RequestID, qse.ReferenceURL)
|
||||
}
|
||||
253
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/request.go
generated
vendored
Executable file
253
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/request.go
generated
vendored
Executable file
@@ -0,0 +1,253 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package request
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/pengsrc/go-shared/convert"
|
||||
|
||||
"github.com/yunify/qingstor-sdk-go/logger"
|
||||
"github.com/yunify/qingstor-sdk-go/request/builder"
|
||||
"github.com/yunify/qingstor-sdk-go/request/data"
|
||||
"github.com/yunify/qingstor-sdk-go/request/signer"
|
||||
"github.com/yunify/qingstor-sdk-go/request/unpacker"
|
||||
)
|
||||
|
||||
// A Request can build, sign, send and unpack API request.
|
||||
type Request struct {
|
||||
Operation *data.Operation
|
||||
Input *reflect.Value
|
||||
Output *reflect.Value
|
||||
|
||||
HTTPRequest *http.Request
|
||||
HTTPResponse *http.Response
|
||||
}
|
||||
|
||||
// New create a Request from given Operation, Input and Output.
|
||||
// It returns a Request.
|
||||
func New(o *data.Operation, i data.Input, x interface{}) (*Request, error) {
|
||||
input := reflect.ValueOf(i)
|
||||
if input.IsValid() && input.Elem().IsValid() {
|
||||
err := i.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
output := reflect.ValueOf(x)
|
||||
|
||||
return &Request{
|
||||
Operation: o,
|
||||
Input: &input,
|
||||
Output: &output,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Send sends API request.
|
||||
// It returns error if error occurred.
|
||||
func (r *Request) Send() error {
|
||||
err := r.Build()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = r.Sign()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = r.Do()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build checks and builds the API request.
|
||||
// It returns error if error occurred.
|
||||
func (r *Request) Build() error {
|
||||
err := r.check()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = r.build()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Do sends and unpacks the API request.
|
||||
// It returns error if error occurred.
|
||||
func (r *Request) Do() error {
|
||||
err := r.send()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = r.unpack()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sign sign the API request by setting the authorization header.
|
||||
// It returns error if error occurred.
|
||||
func (r *Request) Sign() error {
|
||||
err := r.sign()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SignQuery sign the API request by appending query string.
|
||||
// It returns error if error occurred.
|
||||
func (r *Request) SignQuery(timeoutSeconds int) error {
|
||||
err := r.signQuery(int(time.Now().Unix()) + timeoutSeconds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplySignature applies the Authorization header.
|
||||
// It returns error if error occurred.
|
||||
func (r *Request) ApplySignature(authorization string) error {
|
||||
r.HTTPRequest.Header.Set("Authorization", authorization)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyQuerySignature applies the query signature.
|
||||
// It returns error if error occurred.
|
||||
func (r *Request) ApplyQuerySignature(accessKeyID string, expires int, signature string) error {
|
||||
queryValue := r.HTTPRequest.URL.Query()
|
||||
queryValue.Set("access_key_id", accessKeyID)
|
||||
queryValue.Set("expires", strconv.Itoa(expires))
|
||||
queryValue.Set("signature", signature)
|
||||
|
||||
r.HTTPRequest.URL.RawQuery = queryValue.Encode()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Request) check() error {
|
||||
if r.Operation.Config.AccessKeyID == "" {
|
||||
return errors.New("access key not provided")
|
||||
}
|
||||
|
||||
if r.Operation.Config.SecretAccessKey == "" {
|
||||
return errors.New("secret access key not provided")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Request) build() error {
|
||||
b := &builder.QingStorBuilder{}
|
||||
httpRequest, err := b.BuildHTTPRequest(r.Operation, r.Input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.HTTPRequest = httpRequest
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Request) sign() error {
|
||||
s := &signer.QingStorSigner{
|
||||
AccessKeyID: r.Operation.Config.AccessKeyID,
|
||||
SecretAccessKey: r.Operation.Config.SecretAccessKey,
|
||||
}
|
||||
err := s.WriteSignature(r.HTTPRequest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Request) signQuery(expires int) error {
|
||||
s := &signer.QingStorSigner{
|
||||
AccessKeyID: r.Operation.Config.AccessKeyID,
|
||||
SecretAccessKey: r.Operation.Config.SecretAccessKey,
|
||||
}
|
||||
err := s.WriteQuerySignature(r.HTTPRequest, expires)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Request) send() error {
|
||||
var response *http.Response
|
||||
var err error
|
||||
|
||||
if r.Operation.Config.Connection == nil {
|
||||
r.Operation.Config.InitHTTPClient()
|
||||
}
|
||||
|
||||
retries := r.Operation.Config.ConnectionRetries + 1
|
||||
for {
|
||||
if retries > 0 {
|
||||
logger.Infof(nil, fmt.Sprintf(
|
||||
"Sending request: [%d] %s %s",
|
||||
convert.StringToTimestamp(r.HTTPRequest.Header.Get("Date"), convert.RFC822),
|
||||
r.Operation.RequestMethod,
|
||||
r.HTTPRequest.Host,
|
||||
))
|
||||
|
||||
response, err = r.Operation.Config.Connection.Do(r.HTTPRequest)
|
||||
if err == nil {
|
||||
retries = 0
|
||||
} else {
|
||||
retries--
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.HTTPResponse = response
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Request) unpack() error {
|
||||
u := &unpacker.QingStorUnpacker{}
|
||||
err := u.UnpackHTTPRequest(r.Operation, r.HTTPResponse, r.Output)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
266
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/signer/qingstor.go
generated
vendored
Executable file
266
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/signer/qingstor.go
generated
vendored
Executable file
@@ -0,0 +1,266 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package signer
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/pengsrc/go-shared/convert"
|
||||
|
||||
"github.com/yunify/qingstor-sdk-go/logger"
|
||||
"github.com/yunify/qingstor-sdk-go/utils"
|
||||
)
|
||||
|
||||
// QingStorSigner is the http request signer for QingStor service.
|
||||
type QingStorSigner struct {
|
||||
AccessKeyID string
|
||||
SecretAccessKey string
|
||||
}
|
||||
|
||||
// WriteSignature calculates signature and write it to http request header.
|
||||
func (qss *QingStorSigner) WriteSignature(request *http.Request) error {
|
||||
authorization, err := qss.BuildSignature(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
request.Header.Set("Authorization", authorization)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteQuerySignature calculates signature and write it to http request url.
|
||||
func (qss *QingStorSigner) WriteQuerySignature(request *http.Request, expires int) error {
|
||||
query, err := qss.BuildQuerySignature(request, expires)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if request.URL.RawQuery != "" {
|
||||
query = "?" + request.URL.RawQuery + "&" + query
|
||||
} else {
|
||||
query = "?" + query
|
||||
}
|
||||
|
||||
newRequest, err := http.NewRequest(request.Method,
|
||||
request.URL.Scheme+"://"+request.URL.Host+utils.URLQueryEscape(request.URL.Path)+query, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
request.URL = newRequest.URL
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// BuildSignature calculates the signature string.
|
||||
func (qss *QingStorSigner) BuildSignature(request *http.Request) (string, error) {
|
||||
stringToSign, err := qss.BuildStringToSign(request)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
h := hmac.New(sha256.New, []byte(qss.SecretAccessKey))
|
||||
h.Write([]byte(stringToSign))
|
||||
|
||||
signature := strings.TrimSpace(base64.StdEncoding.EncodeToString(h.Sum(nil)))
|
||||
authorization := "QS " + qss.AccessKeyID + ":" + signature
|
||||
|
||||
logger.Debugf(nil, fmt.Sprintf(
|
||||
"QingStor authorization: [%d] %s",
|
||||
convert.StringToTimestamp(request.Header.Get("Date"), convert.RFC822),
|
||||
authorization,
|
||||
))
|
||||
|
||||
return authorization, nil
|
||||
}
|
||||
|
||||
// BuildQuerySignature calculates the signature string for query.
|
||||
func (qss *QingStorSigner) BuildQuerySignature(request *http.Request, expires int) (string, error) {
|
||||
stringToSign, err := qss.BuildQueryStringToSign(request, expires)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
h := hmac.New(sha256.New, []byte(qss.SecretAccessKey))
|
||||
h.Write([]byte(stringToSign))
|
||||
|
||||
signature := strings.TrimSpace(base64.StdEncoding.EncodeToString(h.Sum(nil)))
|
||||
signature = utils.URLQueryEscape(signature)
|
||||
query := fmt.Sprintf(
|
||||
"access_key_id=%s&expires=%d&signature=%s",
|
||||
qss.AccessKeyID, expires, signature,
|
||||
)
|
||||
|
||||
logger.Debugf(nil, fmt.Sprintf(
|
||||
"QingStor query signature: [%d] %s",
|
||||
convert.StringToTimestamp(request.Header.Get("Date"), convert.RFC822),
|
||||
query,
|
||||
))
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// BuildStringToSign build the string to sign.
|
||||
func (qss *QingStorSigner) BuildStringToSign(request *http.Request) (string, error) {
|
||||
date := request.Header.Get("Date")
|
||||
if request.Header.Get("X-QS-Date") != "" {
|
||||
date = ""
|
||||
}
|
||||
stringToSign := fmt.Sprintf(
|
||||
"%s\n%s\n%s\n%s\n",
|
||||
request.Method,
|
||||
request.Header.Get("Content-MD5"),
|
||||
request.Header.Get("Content-Type"),
|
||||
date,
|
||||
)
|
||||
|
||||
stringToSign += qss.buildCanonicalizedHeaders(request)
|
||||
canonicalizedResource, err := qss.buildCanonicalizedResource(request)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
stringToSign += canonicalizedResource
|
||||
|
||||
logger.Debugf(nil, fmt.Sprintf(
|
||||
"QingStor string to sign: [%d] %s",
|
||||
convert.StringToTimestamp(request.Header.Get("Date"), convert.RFC822),
|
||||
stringToSign,
|
||||
))
|
||||
|
||||
return stringToSign, nil
|
||||
}
|
||||
|
||||
// BuildQueryStringToSign build the string to sign for query.
|
||||
func (qss *QingStorSigner) BuildQueryStringToSign(request *http.Request, expires int) (string, error) {
|
||||
stringToSign := fmt.Sprintf(
|
||||
"%s\n%s\n%s\n%d\n",
|
||||
request.Method,
|
||||
request.Header.Get("Content-MD5"),
|
||||
request.Header.Get("Content-Type"),
|
||||
expires,
|
||||
)
|
||||
|
||||
stringToSign += qss.buildCanonicalizedHeaders(request)
|
||||
canonicalizedResource, err := qss.buildCanonicalizedResource(request)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
stringToSign += canonicalizedResource
|
||||
|
||||
logger.Debugf(nil, fmt.Sprintf(
|
||||
"QingStor query string to sign: [%d] %s",
|
||||
convert.StringToTimestamp(request.Header.Get("Date"), convert.RFC822),
|
||||
stringToSign,
|
||||
))
|
||||
|
||||
return stringToSign, nil
|
||||
}
|
||||
|
||||
func (qss *QingStorSigner) buildCanonicalizedHeaders(request *http.Request) string {
|
||||
keys := []string{}
|
||||
for key := range request.Header {
|
||||
if strings.HasPrefix(strings.ToLower(key), "x-qs-") {
|
||||
keys = append(keys, strings.TrimSpace(strings.ToLower(key)))
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
canonicalizedHeaders := ""
|
||||
for _, key := range keys {
|
||||
canonicalizedHeaders += key + ":" + strings.TrimSpace(request.Header.Get(key)) + "\n"
|
||||
}
|
||||
|
||||
return canonicalizedHeaders
|
||||
}
|
||||
|
||||
func (qss *QingStorSigner) buildCanonicalizedResource(request *http.Request) (string, error) {
|
||||
path := utils.URLQueryEscape(request.URL.Path)
|
||||
query := request.URL.Query()
|
||||
|
||||
keys := []string{}
|
||||
for key := range query {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
parts := []string{}
|
||||
for _, key := range keys {
|
||||
values := query[key]
|
||||
if qss.queryToSign(key) {
|
||||
if len(values) > 0 {
|
||||
if values[0] != "" {
|
||||
value := strings.TrimSpace(strings.Join(values, ""))
|
||||
value, err := utils.URLQueryUnescape(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
parts = append(parts, key+"="+value)
|
||||
} else {
|
||||
parts = append(parts, key)
|
||||
}
|
||||
} else {
|
||||
parts = append(parts, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
joinedParts := strings.Join(parts, "&")
|
||||
if joinedParts != "" {
|
||||
path = path + "?" + joinedParts
|
||||
}
|
||||
|
||||
logger.Debugf(nil, fmt.Sprintf(
|
||||
"QingStor canonicalized resource: [%d] %s",
|
||||
convert.StringToTimestamp(request.Header.Get("Date"), convert.RFC822),
|
||||
path,
|
||||
))
|
||||
|
||||
return path, nil
|
||||
}
|
||||
|
||||
func (qss *QingStorSigner) queryToSign(key string) bool {
|
||||
keysMap := map[string]bool{
|
||||
"acl": true,
|
||||
"cors": true,
|
||||
"delete": true,
|
||||
"mirror": true,
|
||||
"part_number": true,
|
||||
"policy": true,
|
||||
"stats": true,
|
||||
"upload_id": true,
|
||||
"uploads": true,
|
||||
"image": true,
|
||||
"lifecycle": true,
|
||||
"logging": true,
|
||||
"response-expires": true,
|
||||
"response-cache-control": true,
|
||||
"response-content-type": true,
|
||||
"response-content-language": true,
|
||||
"response-content-encoding": true,
|
||||
"response-content-disposition": true,
|
||||
}
|
||||
|
||||
return keysMap[key]
|
||||
}
|
||||
220
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/unpacker/base.go
generated
vendored
Executable file
220
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/unpacker/base.go
generated
vendored
Executable file
@@ -0,0 +1,220 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package unpacker
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/pengsrc/go-shared/convert"
|
||||
|
||||
"github.com/yunify/qingstor-sdk-go/logger"
|
||||
"github.com/yunify/qingstor-sdk-go/request/data"
|
||||
)
|
||||
|
||||
// BaseUnpacker is the base unpacker for all services.
|
||||
type BaseUnpacker struct {
|
||||
operation *data.Operation
|
||||
httpResponse *http.Response
|
||||
output *reflect.Value
|
||||
}
|
||||
|
||||
// UnpackHTTPRequest unpacks http response with an operation and an output.
|
||||
func (b *BaseUnpacker) UnpackHTTPRequest(o *data.Operation, r *http.Response, x *reflect.Value) error {
|
||||
b.operation = o
|
||||
b.httpResponse = r
|
||||
b.output = x
|
||||
|
||||
err := b.exposeStatusCode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.parseResponseHeaders()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.parseResponseBody()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.parseResponseElements()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BaseUnpacker) exposeStatusCode() error {
|
||||
value := b.output.Elem().FieldByName("StatusCode")
|
||||
if value.IsValid() {
|
||||
switch value.Interface().(type) {
|
||||
case *int:
|
||||
logger.Infof(nil, fmt.Sprintf(
|
||||
"QingStor response status code: [%d] %d",
|
||||
convert.StringToTimestamp(b.httpResponse.Header.Get("Date"), convert.RFC822),
|
||||
b.httpResponse.StatusCode,
|
||||
))
|
||||
value.Set(reflect.ValueOf(&b.httpResponse.StatusCode))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BaseUnpacker) parseResponseHeaders() error {
|
||||
logger.Infof(nil, fmt.Sprintf(
|
||||
"QingStor response headers: [%d] %s",
|
||||
convert.StringToTimestamp(b.httpResponse.Header.Get("Date"), convert.RFC822),
|
||||
fmt.Sprint(b.httpResponse.Header),
|
||||
))
|
||||
|
||||
if b.isResponseRight() {
|
||||
fields := b.output.Elem()
|
||||
for i := 0; i < fields.NumField(); i++ {
|
||||
field := fields.Field(i)
|
||||
fieldTagName := fields.Type().Field(i).Tag.Get("name")
|
||||
fieldTagLocation := fields.Type().Field(i).Tag.Get("location")
|
||||
fieldStringValue := b.httpResponse.Header.Get(fieldTagName)
|
||||
|
||||
// Empty value should be ignored.
|
||||
if fieldStringValue == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if fieldTagName != "" && fieldTagLocation == "headers" {
|
||||
switch field.Interface().(type) {
|
||||
case *string:
|
||||
field.Set(reflect.ValueOf(&fieldStringValue))
|
||||
case *int:
|
||||
intValue, err := strconv.Atoi(fieldStringValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
field.Set(reflect.ValueOf(&intValue))
|
||||
case *int64:
|
||||
int64Value, err := strconv.ParseInt(fieldStringValue, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
field.Set(reflect.ValueOf(&int64Value))
|
||||
case *bool:
|
||||
case *time.Time:
|
||||
formatString := fields.Type().Field(i).Tag.Get("format")
|
||||
format := ""
|
||||
switch formatString {
|
||||
case "RFC 822":
|
||||
format = convert.RFC822
|
||||
case "ISO 8601":
|
||||
format = convert.ISO8601
|
||||
}
|
||||
timeValue, err := convert.StringToTime(fieldStringValue, format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
field.Set(reflect.ValueOf(&timeValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BaseUnpacker) parseResponseBody() error {
|
||||
if b.isResponseRight() {
|
||||
value := b.output.Elem().FieldByName("Body")
|
||||
if value.IsValid() {
|
||||
switch value.Type().String() {
|
||||
case "string":
|
||||
buffer := &bytes.Buffer{}
|
||||
buffer.ReadFrom(b.httpResponse.Body)
|
||||
b.httpResponse.Body.Close()
|
||||
|
||||
logger.Infof(nil, fmt.Sprintf(
|
||||
"QingStor response body string: [%d] %s",
|
||||
convert.StringToTimestamp(b.httpResponse.Header.Get("Date"), convert.RFC822),
|
||||
string(buffer.Bytes()),
|
||||
))
|
||||
|
||||
value.SetString(string(buffer.Bytes()))
|
||||
case "io.ReadCloser":
|
||||
value.Set(reflect.ValueOf(b.httpResponse.Body))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BaseUnpacker) parseResponseElements() error {
|
||||
if !b.isResponseRight() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Do not parse GetObject and ImageProcess's body.
|
||||
if b.operation.APIName == "GET Object" ||
|
||||
b.operation.APIName == "Image Process" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if b.httpResponse.Header.Get("Content-Type") != "application/json" {
|
||||
return nil
|
||||
}
|
||||
|
||||
buffer := &bytes.Buffer{}
|
||||
buffer.ReadFrom(b.httpResponse.Body)
|
||||
b.httpResponse.Body.Close()
|
||||
|
||||
if buffer.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.Infof(nil, fmt.Sprintf(
|
||||
"QingStor response body string: [%d] %s",
|
||||
convert.StringToTimestamp(b.httpResponse.Header.Get("Date"), convert.RFC822),
|
||||
string(buffer.Bytes()),
|
||||
))
|
||||
|
||||
err := json.Unmarshal(buffer.Bytes(), b.output.Interface())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BaseUnpacker) isResponseRight() bool {
|
||||
rightStatusCodes := b.operation.StatusCodes
|
||||
if len(rightStatusCodes) == 0 {
|
||||
rightStatusCodes = append(rightStatusCodes, 200)
|
||||
}
|
||||
|
||||
flag := false
|
||||
for _, statusCode := range rightStatusCodes {
|
||||
if statusCode == b.httpResponse.StatusCode {
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
|
||||
return flag
|
||||
}
|
||||
84
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/unpacker/qingstor.go
generated
vendored
Executable file
84
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/request/unpacker/qingstor.go
generated
vendored
Executable file
@@ -0,0 +1,84 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package unpacker
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/yunify/qingstor-sdk-go/request/data"
|
||||
"github.com/yunify/qingstor-sdk-go/request/errors"
|
||||
)
|
||||
|
||||
// QingStorUnpacker is the response unpacker for QingStor service.
|
||||
type QingStorUnpacker struct {
|
||||
baseUnpacker *BaseUnpacker
|
||||
}
|
||||
|
||||
// UnpackHTTPRequest unpack the http response with an operation, http response and an output.
|
||||
func (qu *QingStorUnpacker) UnpackHTTPRequest(o *data.Operation, r *http.Response, x *reflect.Value) error {
|
||||
qu.baseUnpacker = &BaseUnpacker{}
|
||||
err := qu.baseUnpacker.UnpackHTTPRequest(o, r, x)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = qu.parseError()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Close body for every API except GetObject and ImageProcess.
|
||||
if o.APIName != "GET Object" && o.APIName != "Image Process" && r.Body != nil {
|
||||
err = r.Body.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.Body = nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (qu *QingStorUnpacker) parseError() error {
|
||||
if !qu.baseUnpacker.isResponseRight() {
|
||||
if qu.baseUnpacker.httpResponse.Header.Get("Content-Type") == "application/json" {
|
||||
buffer := &bytes.Buffer{}
|
||||
buffer.ReadFrom(qu.baseUnpacker.httpResponse.Body)
|
||||
qu.baseUnpacker.httpResponse.Body.Close()
|
||||
|
||||
qsError := &errors.QingStorError{}
|
||||
if buffer.Len() > 0 {
|
||||
err := json.Unmarshal(buffer.Bytes(), qsError)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
qsError.StatusCode = qu.baseUnpacker.httpResponse.StatusCode
|
||||
if qsError.RequestID == "" {
|
||||
qsError.RequestID = qu.baseUnpacker.httpResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID"))
|
||||
}
|
||||
|
||||
return qsError
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
1263
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/service/bucket.go
generated
vendored
Executable file
1263
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/service/bucket.go
generated
vendored
Executable file
File diff suppressed because it is too large
Load Diff
266
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/service/convert_types.go
generated
vendored
Executable file
266
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/service/convert_types.go
generated
vendored
Executable file
@@ -0,0 +1,266 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// String returns a pointer to the given string value.
|
||||
func String(v string) *string {
|
||||
return &v
|
||||
}
|
||||
|
||||
// StringValue returns the value of the given string pointer or
|
||||
// "" if the pointer is nil.
|
||||
func StringValue(v *string) string {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// StringSlice converts a slice of string values into a slice of
|
||||
// string pointers
|
||||
func StringSlice(src []string) []*string {
|
||||
dst := make([]*string, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// StringValueSlice converts a slice of string pointers into a slice of
|
||||
// string values
|
||||
func StringValueSlice(src []*string) []string {
|
||||
dst := make([]string, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// StringMap converts a string map of string values into a string
|
||||
// map of string pointers
|
||||
func StringMap(src map[string]string) map[string]*string {
|
||||
dst := make(map[string]*string)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// StringValueMap converts a string map of string pointers into a string
|
||||
// map of string values
|
||||
func StringValueMap(src map[string]*string) map[string]string {
|
||||
dst := make(map[string]string)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Bool returns a pointer to the given bool value.
|
||||
func Bool(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
// BoolValue returns the value of the given bool pointer or
|
||||
// false if the pointer is nil.
|
||||
func BoolValue(v *bool) bool {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// BoolSlice converts a slice of bool values into a slice of
|
||||
// bool pointers
|
||||
func BoolSlice(src []bool) []*bool {
|
||||
dst := make([]*bool, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// BoolValueSlice converts a slice of bool pointers into a slice of
|
||||
// bool values
|
||||
func BoolValueSlice(src []*bool) []bool {
|
||||
dst := make([]bool, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// BoolMap converts a string map of bool values into a string
|
||||
// map of bool pointers
|
||||
func BoolMap(src map[string]bool) map[string]*bool {
|
||||
dst := make(map[string]*bool)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// BoolValueMap converts a string map of bool pointers into a string
|
||||
// map of bool values
|
||||
func BoolValueMap(src map[string]*bool) map[string]bool {
|
||||
dst := make(map[string]bool)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int returns a pointer to the given int value.
|
||||
func Int(v int) *int {
|
||||
return &v
|
||||
}
|
||||
|
||||
// IntValue returns the value of the given int pointer or
|
||||
// 0 if the pointer is nil.
|
||||
func IntValue(v *int) int {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// IntSlice converts a slice of int values into a slice of
|
||||
// int pointers
|
||||
func IntSlice(src []int) []*int {
|
||||
dst := make([]*int, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// IntValueSlice converts a slice of int pointers into a slice of
|
||||
// int values
|
||||
func IntValueSlice(src []*int) []int {
|
||||
dst := make([]int, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// IntMap converts a string map of int values into a string
|
||||
// map of int pointers
|
||||
func IntMap(src map[string]int) map[string]*int {
|
||||
dst := make(map[string]*int)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// IntValueMap converts a string map of int pointers into a string
|
||||
// map of int values
|
||||
func IntValueMap(src map[string]*int) map[string]int {
|
||||
dst := make(map[string]int)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Time returns a pointer to the given time.Time value.
|
||||
func Time(v time.Time) *time.Time {
|
||||
return &v
|
||||
}
|
||||
|
||||
// TimeValue returns the value of the given time.Time pointer or
|
||||
// time.Time{} if the pointer is nil.
|
||||
func TimeValue(v *time.Time) time.Time {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC".
|
||||
// The result is undefined if the Unix time cannot be represented by an int64.
|
||||
// Which includes calling TimeUnixMilli on a zero Time is undefined.
|
||||
//
|
||||
// See Go stdlib https://golang.org/pkg/time/#Time.UnixNano for more information.
|
||||
func TimeUnixMilli(t time.Time) int64 {
|
||||
return t.UnixNano() / int64(time.Millisecond/time.Nanosecond)
|
||||
}
|
||||
|
||||
// TimeSlice converts a slice of time.Time values into a slice of
|
||||
// time.Time pointers
|
||||
func TimeSlice(src []time.Time) []*time.Time {
|
||||
dst := make([]*time.Time, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// TimeValueSlice converts a slice of time.Time pointers into a slice of
|
||||
// time.Time values
|
||||
func TimeValueSlice(src []*time.Time) []time.Time {
|
||||
dst := make([]time.Time, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// TimeMap converts a string map of time.Time values into a string
|
||||
// map of time.Time pointers
|
||||
func TimeMap(src map[string]time.Time) map[string]*time.Time {
|
||||
dst := make(map[string]*time.Time)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// TimeValueMap converts a string map of time.Time pointers into a string
|
||||
// map of time.Time values
|
||||
func TimeValueMap(src map[string]*time.Time) map[string]time.Time {
|
||||
dst := make(map[string]time.Time)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
1171
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/service/object.go
generated
vendored
Executable file
1171
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/service/object.go
generated
vendored
Executable file
File diff suppressed because it is too large
Load Diff
108
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/service/qingstor.go
generated
vendored
Executable file
108
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/service/qingstor.go
generated
vendored
Executable file
@@ -0,0 +1,108 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
// Package service provides QingStor Service API (API Version 2016-01-06)
|
||||
package service
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/yunify/qingstor-sdk-go/config"
|
||||
"github.com/yunify/qingstor-sdk-go/request"
|
||||
"github.com/yunify/qingstor-sdk-go/request/data"
|
||||
)
|
||||
|
||||
var _ http.Header
|
||||
|
||||
// Service QingStor provides low-cost and reliable online storage service with unlimited storage space, high read and write performance, high reliability and data safety, fine-grained access control, and easy to use API.
|
||||
type Service struct {
|
||||
Config *config.Config
|
||||
}
|
||||
|
||||
// Init initializes a new service.
|
||||
func Init(c *config.Config) (*Service, error) {
|
||||
return &Service{Config: c}, nil
|
||||
}
|
||||
|
||||
// ListBuckets does Retrieve the bucket list.
|
||||
// Documentation URL: https://docs.qingcloud.com/qingstor/api/service/get.html
|
||||
func (s *Service) ListBuckets(input *ListBucketsInput) (*ListBucketsOutput, error) {
|
||||
r, x, err := s.ListBucketsRequest(input)
|
||||
|
||||
if err != nil {
|
||||
return x, err
|
||||
}
|
||||
|
||||
err = r.Send()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID"))
|
||||
x.RequestID = &requestID
|
||||
|
||||
return x, err
|
||||
}
|
||||
|
||||
// ListBucketsRequest creates request and output object of ListBuckets.
|
||||
func (s *Service) ListBucketsRequest(input *ListBucketsInput) (*request.Request, *ListBucketsOutput, error) {
|
||||
|
||||
if input == nil {
|
||||
input = &ListBucketsInput{}
|
||||
}
|
||||
|
||||
o := &data.Operation{
|
||||
Config: s.Config,
|
||||
APIName: "Get Service",
|
||||
RequestMethod: "GET",
|
||||
RequestURI: "/",
|
||||
StatusCodes: []int{
|
||||
200, // OK
|
||||
},
|
||||
}
|
||||
|
||||
x := &ListBucketsOutput{}
|
||||
r, err := request.New(o, input, x)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return r, x, nil
|
||||
}
|
||||
|
||||
// ListBucketsInput presents input for ListBuckets.
|
||||
type ListBucketsInput struct {
|
||||
// Limits results to buckets that in the location
|
||||
Location *string `json:"Location,omitempty" name:"Location" location:"headers"`
|
||||
}
|
||||
|
||||
// Validate validates the input for ListBuckets.
|
||||
func (v *ListBucketsInput) Validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListBucketsOutput presents output for ListBuckets.
|
||||
type ListBucketsOutput struct {
|
||||
StatusCode *int `location:"statusCode"`
|
||||
|
||||
RequestID *string `location:"requestID"`
|
||||
|
||||
// Buckets information
|
||||
Buckets []*BucketType `json:"buckets,omitempty" name:"buckets" location:"elements"`
|
||||
// Bucket count
|
||||
Count *int `json:"count,omitempty" name:"count" location:"elements"`
|
||||
}
|
||||
463
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/service/types.go
generated
vendored
Executable file
463
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/service/types.go
generated
vendored
Executable file
@@ -0,0 +1,463 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/yunify/qingstor-sdk-go/request/errors"
|
||||
)
|
||||
|
||||
// Properties presents the service properties.
|
||||
type Properties struct {
|
||||
// Bucket name
|
||||
BucketName *string `json:"bucket-name" name:"bucket-name"` // Required
|
||||
// Object key
|
||||
ObjectKey *string `json:"object-key" name:"object-key"` // Required
|
||||
// QingCloud Zone ID
|
||||
Zone *string `json:"zone" name:"zone"`
|
||||
}
|
||||
|
||||
// ACLType presents ACL.
|
||||
type ACLType struct {
|
||||
Grantee *GranteeType `json:"grantee" name:"grantee"` // Required
|
||||
// Permission for this grantee
|
||||
// Permission's available values: READ, WRITE, FULL_CONTROL
|
||||
Permission *string `json:"permission" name:"permission"` // Required
|
||||
|
||||
}
|
||||
|
||||
// Validate validates the ACL.
|
||||
func (v *ACLType) Validate() error {
|
||||
|
||||
if v.Grantee != nil {
|
||||
if err := v.Grantee.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if v.Grantee == nil {
|
||||
return errors.ParameterRequiredError{
|
||||
ParameterName: "Grantee",
|
||||
ParentName: "ACL",
|
||||
}
|
||||
}
|
||||
|
||||
if v.Permission == nil {
|
||||
return errors.ParameterRequiredError{
|
||||
ParameterName: "Permission",
|
||||
ParentName: "ACL",
|
||||
}
|
||||
}
|
||||
|
||||
if v.Permission != nil {
|
||||
permissionValidValues := []string{"READ", "WRITE", "FULL_CONTROL"}
|
||||
permissionParameterValue := fmt.Sprint(*v.Permission)
|
||||
|
||||
permissionIsValid := false
|
||||
for _, value := range permissionValidValues {
|
||||
if value == permissionParameterValue {
|
||||
permissionIsValid = true
|
||||
}
|
||||
}
|
||||
|
||||
if !permissionIsValid {
|
||||
return errors.ParameterValueNotAllowedError{
|
||||
ParameterName: "Permission",
|
||||
ParameterValue: permissionParameterValue,
|
||||
AllowedValues: permissionValidValues,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// BucketType presents Bucket.
|
||||
type BucketType struct {
|
||||
// Created time of the bucket
|
||||
Created *time.Time `json:"created,omitempty" name:"created" format:"ISO 8601"`
|
||||
// QingCloud Zone ID
|
||||
Location *string `json:"location,omitempty" name:"location"`
|
||||
// Bucket name
|
||||
Name *string `json:"name,omitempty" name:"name"`
|
||||
// URL to access the bucket
|
||||
URL *string `json:"url,omitempty" name:"url"`
|
||||
}
|
||||
|
||||
// Validate validates the Bucket.
|
||||
func (v *BucketType) Validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ConditionType presents Condition.
|
||||
type ConditionType struct {
|
||||
IPAddress *IPAddressType `json:"ip_address,omitempty" name:"ip_address"`
|
||||
IsNull *IsNullType `json:"is_null,omitempty" name:"is_null"`
|
||||
NotIPAddress *NotIPAddressType `json:"not_ip_address,omitempty" name:"not_ip_address"`
|
||||
StringLike *StringLikeType `json:"string_like,omitempty" name:"string_like"`
|
||||
StringNotLike *StringNotLikeType `json:"string_not_like,omitempty" name:"string_not_like"`
|
||||
}
|
||||
|
||||
// Validate validates the Condition.
|
||||
func (v *ConditionType) Validate() error {
|
||||
|
||||
if v.IPAddress != nil {
|
||||
if err := v.IPAddress.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if v.IsNull != nil {
|
||||
if err := v.IsNull.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if v.NotIPAddress != nil {
|
||||
if err := v.NotIPAddress.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if v.StringLike != nil {
|
||||
if err := v.StringLike.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if v.StringNotLike != nil {
|
||||
if err := v.StringNotLike.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CORSRuleType presents CORSRule.
|
||||
type CORSRuleType struct {
|
||||
// Allowed headers
|
||||
AllowedHeaders []*string `json:"allowed_headers,omitempty" name:"allowed_headers"`
|
||||
// Allowed methods
|
||||
AllowedMethods []*string `json:"allowed_methods" name:"allowed_methods"` // Required
|
||||
// Allowed origin
|
||||
AllowedOrigin *string `json:"allowed_origin" name:"allowed_origin"` // Required
|
||||
// Expose headers
|
||||
ExposeHeaders []*string `json:"expose_headers,omitempty" name:"expose_headers"`
|
||||
// Max age seconds
|
||||
MaxAgeSeconds *int `json:"max_age_seconds,omitempty" name:"max_age_seconds"`
|
||||
}
|
||||
|
||||
// Validate validates the CORSRule.
|
||||
func (v *CORSRuleType) Validate() error {
|
||||
|
||||
if len(v.AllowedMethods) == 0 {
|
||||
return errors.ParameterRequiredError{
|
||||
ParameterName: "AllowedMethods",
|
||||
ParentName: "CORSRule",
|
||||
}
|
||||
}
|
||||
|
||||
if v.AllowedOrigin == nil {
|
||||
return errors.ParameterRequiredError{
|
||||
ParameterName: "AllowedOrigin",
|
||||
ParentName: "CORSRule",
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GranteeType presents Grantee.
|
||||
type GranteeType struct {
|
||||
// Grantee user ID
|
||||
ID *string `json:"id,omitempty" name:"id"`
|
||||
// Grantee group name
|
||||
Name *string `json:"name,omitempty" name:"name"`
|
||||
// Grantee type
|
||||
// Type's available values: user, group
|
||||
Type *string `json:"type" name:"type"` // Required
|
||||
|
||||
}
|
||||
|
||||
// Validate validates the Grantee.
|
||||
func (v *GranteeType) Validate() error {
|
||||
|
||||
if v.Type == nil {
|
||||
return errors.ParameterRequiredError{
|
||||
ParameterName: "Type",
|
||||
ParentName: "Grantee",
|
||||
}
|
||||
}
|
||||
|
||||
if v.Type != nil {
|
||||
typeValidValues := []string{"user", "group"}
|
||||
typeParameterValue := fmt.Sprint(*v.Type)
|
||||
|
||||
typeIsValid := false
|
||||
for _, value := range typeValidValues {
|
||||
if value == typeParameterValue {
|
||||
typeIsValid = true
|
||||
}
|
||||
}
|
||||
|
||||
if !typeIsValid {
|
||||
return errors.ParameterValueNotAllowedError{
|
||||
ParameterName: "Type",
|
||||
ParameterValue: typeParameterValue,
|
||||
AllowedValues: typeValidValues,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IPAddressType presents IPAddress.
|
||||
type IPAddressType struct {
|
||||
// Source IP
|
||||
SourceIP []*string `json:"source_ip,omitempty" name:"source_ip"`
|
||||
}
|
||||
|
||||
// Validate validates the IPAddress.
|
||||
func (v *IPAddressType) Validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsNullType presents IsNull.
|
||||
type IsNullType struct {
|
||||
// Refer url
|
||||
Referer *bool `json:"Referer,omitempty" name:"Referer"`
|
||||
}
|
||||
|
||||
// Validate validates the IsNull.
|
||||
func (v *IsNullType) Validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// KeyType presents Key.
|
||||
type KeyType struct {
|
||||
// Object created time
|
||||
Created *time.Time `json:"created,omitempty" name:"created" format:"ISO 8601"`
|
||||
// Whether this key is encrypted
|
||||
Encrypted *bool `json:"encrypted,omitempty" name:"encrypted"`
|
||||
// MD5sum of the object
|
||||
Etag *string `json:"etag,omitempty" name:"etag"`
|
||||
// Object key
|
||||
Key *string `json:"key,omitempty" name:"key"`
|
||||
// MIME type of the object
|
||||
MimeType *string `json:"mime_type,omitempty" name:"mime_type"`
|
||||
// Last modified time in unix time format
|
||||
Modified *int `json:"modified,omitempty" name:"modified"`
|
||||
// Object content size
|
||||
Size *int64 `json:"size,omitempty" name:"size"`
|
||||
}
|
||||
|
||||
// Validate validates the Key.
|
||||
func (v *KeyType) Validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// KeyDeleteErrorType presents KeyDeleteError.
|
||||
type KeyDeleteErrorType struct {
|
||||
// Error code
|
||||
Code *string `json:"code,omitempty" name:"code"`
|
||||
// Object key
|
||||
Key *string `json:"key,omitempty" name:"key"`
|
||||
// Error message
|
||||
Message *string `json:"message,omitempty" name:"message"`
|
||||
}
|
||||
|
||||
// Validate validates the KeyDeleteError.
|
||||
func (v *KeyDeleteErrorType) Validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NotIPAddressType presents NotIPAddress.
|
||||
type NotIPAddressType struct {
|
||||
// Source IP
|
||||
SourceIP []*string `json:"source_ip,omitempty" name:"source_ip"`
|
||||
}
|
||||
|
||||
// Validate validates the NotIPAddress.
|
||||
func (v *NotIPAddressType) Validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ObjectPartType presents ObjectPart.
|
||||
type ObjectPartType struct {
|
||||
// Object part created time
|
||||
Created *time.Time `json:"created,omitempty" name:"created" format:"ISO 8601"`
|
||||
// MD5sum of the object part
|
||||
Etag *string `json:"etag,omitempty" name:"etag"`
|
||||
// Object part number
|
||||
PartNumber *int `json:"part_number" name:"part_number" default:"0"` // Required
|
||||
// Object part size
|
||||
Size *int64 `json:"size,omitempty" name:"size"`
|
||||
}
|
||||
|
||||
// Validate validates the ObjectPart.
|
||||
func (v *ObjectPartType) Validate() error {
|
||||
|
||||
if v.PartNumber == nil {
|
||||
return errors.ParameterRequiredError{
|
||||
ParameterName: "PartNumber",
|
||||
ParentName: "ObjectPart",
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// OwnerType presents Owner.
|
||||
type OwnerType struct {
|
||||
// User ID
|
||||
ID *string `json:"id,omitempty" name:"id"`
|
||||
// Username
|
||||
Name *string `json:"name,omitempty" name:"name"`
|
||||
}
|
||||
|
||||
// Validate validates the Owner.
|
||||
func (v *OwnerType) Validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// StatementType presents Statement.
|
||||
type StatementType struct {
|
||||
// QingStor API methods
|
||||
Action []*string `json:"action" name:"action"` // Required
|
||||
Condition *ConditionType `json:"condition,omitempty" name:"condition"`
|
||||
// Statement effect
|
||||
// Effect's available values: allow, deny
|
||||
Effect *string `json:"effect" name:"effect"` // Required
|
||||
// Bucket policy id, must be unique
|
||||
ID *string `json:"id" name:"id"` // Required
|
||||
// The resources to apply bucket policy
|
||||
Resource []*string `json:"resource,omitempty" name:"resource"`
|
||||
// The user to apply bucket policy
|
||||
User []*string `json:"user" name:"user"` // Required
|
||||
|
||||
}
|
||||
|
||||
// Validate validates the Statement.
|
||||
func (v *StatementType) Validate() error {
|
||||
|
||||
if len(v.Action) == 0 {
|
||||
return errors.ParameterRequiredError{
|
||||
ParameterName: "Action",
|
||||
ParentName: "Statement",
|
||||
}
|
||||
}
|
||||
|
||||
if v.Condition != nil {
|
||||
if err := v.Condition.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if v.Effect == nil {
|
||||
return errors.ParameterRequiredError{
|
||||
ParameterName: "Effect",
|
||||
ParentName: "Statement",
|
||||
}
|
||||
}
|
||||
|
||||
if v.Effect != nil {
|
||||
effectValidValues := []string{"allow", "deny"}
|
||||
effectParameterValue := fmt.Sprint(*v.Effect)
|
||||
|
||||
effectIsValid := false
|
||||
for _, value := range effectValidValues {
|
||||
if value == effectParameterValue {
|
||||
effectIsValid = true
|
||||
}
|
||||
}
|
||||
|
||||
if !effectIsValid {
|
||||
return errors.ParameterValueNotAllowedError{
|
||||
ParameterName: "Effect",
|
||||
ParameterValue: effectParameterValue,
|
||||
AllowedValues: effectValidValues,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if v.ID == nil {
|
||||
return errors.ParameterRequiredError{
|
||||
ParameterName: "ID",
|
||||
ParentName: "Statement",
|
||||
}
|
||||
}
|
||||
|
||||
if len(v.User) == 0 {
|
||||
return errors.ParameterRequiredError{
|
||||
ParameterName: "User",
|
||||
ParentName: "Statement",
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// StringLikeType presents StringLike.
|
||||
type StringLikeType struct {
|
||||
// Refer url
|
||||
Referer []*string `json:"Referer,omitempty" name:"Referer"`
|
||||
}
|
||||
|
||||
// Validate validates the StringLike.
|
||||
func (v *StringLikeType) Validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// StringNotLikeType presents StringNotLike.
|
||||
type StringNotLikeType struct {
|
||||
// Refer url
|
||||
Referer []*string `json:"Referer,omitempty" name:"Referer"`
|
||||
}
|
||||
|
||||
// Validate validates the StringNotLike.
|
||||
func (v *StringNotLikeType) Validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UploadsType presents Uploads.
|
||||
type UploadsType struct {
|
||||
// Object part created time
|
||||
Created *time.Time `json:"created,omitempty" name:"created" format:"ISO 8601"`
|
||||
// Object key
|
||||
Key *string `json:"key,omitempty" name:"key"`
|
||||
// Object upload id
|
||||
UploadID *string `json:"upload_id,omitempty" name:"upload_id"`
|
||||
}
|
||||
|
||||
// Validate validates the Uploads.
|
||||
func (v *UploadsType) Validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
136
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/utils/conn.go
generated
vendored
Executable file
136
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/utils/conn.go
generated
vendored
Executable file
@@ -0,0 +1,136 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var connPool sync.Pool
|
||||
|
||||
type netConn net.Conn
|
||||
type netDialer net.Dialer
|
||||
|
||||
// Dialer is wrapped dialer provided by qingstor go sdk.
|
||||
//
|
||||
// We provide this dialer wrapper ReadTimeout & WriteTimeout attributes into connection object.
|
||||
// This timeout is for individual buffer I/O operation like other language (python, perl... etc),
|
||||
// so don't bother with SetDeadline or stupid nethttp.Client timeout.
|
||||
type Dialer struct {
|
||||
*net.Dialer
|
||||
ReadTimeout time.Duration
|
||||
WriteTimeout time.Duration
|
||||
}
|
||||
|
||||
// NewDialer will create a new dialer.
|
||||
func NewDialer(connTimeout, readTimeout, writeTimeout time.Duration) *Dialer {
|
||||
d := &net.Dialer{
|
||||
DualStack: false,
|
||||
Timeout: connTimeout,
|
||||
}
|
||||
return &Dialer{d, readTimeout, writeTimeout}
|
||||
}
|
||||
|
||||
// Dial connects to the address on the named network.
|
||||
func (d *Dialer) Dial(network, addr string) (net.Conn, error) {
|
||||
c, err := d.Dialer.Dial(network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn := NewConn(c)
|
||||
conn.readTimeout = d.ReadTimeout
|
||||
conn.writeTimeout = d.WriteTimeout
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// DialContext connects to the address on the named network using
|
||||
// the provided context.
|
||||
func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
c, err := d.Dialer.DialContext(ctx, network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn := NewConn(c)
|
||||
conn.readTimeout = d.ReadTimeout
|
||||
conn.writeTimeout = d.WriteTimeout
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// Conn is a generic stream-oriented network connection.
|
||||
type Conn struct {
|
||||
netConn
|
||||
readTimeout time.Duration
|
||||
writeTimeout time.Duration
|
||||
timeoutFunc func() bool
|
||||
}
|
||||
|
||||
// NewConn will create a new conn.
|
||||
func NewConn(c netConn) *Conn {
|
||||
conn, ok := c.(*Conn)
|
||||
if ok {
|
||||
return conn
|
||||
}
|
||||
conn, ok = connPool.Get().(*Conn)
|
||||
if !ok {
|
||||
conn = new(Conn)
|
||||
}
|
||||
conn.netConn = c
|
||||
return conn
|
||||
}
|
||||
|
||||
// SetReadTimeout will set the conn's read timeout.
|
||||
func (c *Conn) SetReadTimeout(d time.Duration) {
|
||||
c.readTimeout = d
|
||||
}
|
||||
|
||||
// SetWriteTimeout will set the conn's write timeout.
|
||||
func (c *Conn) SetWriteTimeout(d time.Duration) {
|
||||
c.writeTimeout = d
|
||||
}
|
||||
|
||||
// Read will read from the conn.
|
||||
func (c Conn) Read(buf []byte) (n int, err error) {
|
||||
if c.readTimeout > 0 {
|
||||
c.SetDeadline(time.Now().Add(c.readTimeout))
|
||||
}
|
||||
n, err = c.netConn.Read(buf)
|
||||
if c.readTimeout > 0 {
|
||||
c.SetDeadline(time.Time{}) // clear timeout
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Write will write into the conn.
|
||||
func (c Conn) Write(buf []byte) (n int, err error) {
|
||||
if c.writeTimeout > 0 {
|
||||
c.SetDeadline(time.Now().Add(c.writeTimeout))
|
||||
}
|
||||
n, err = c.netConn.Write(buf)
|
||||
if c.writeTimeout > 0 {
|
||||
c.SetDeadline(time.Time{})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Close will close the conn.
|
||||
func (c Conn) Close() (err error) {
|
||||
if c.netConn == nil {
|
||||
return nil
|
||||
}
|
||||
err = c.netConn.Close()
|
||||
connPool.Put(c)
|
||||
c.netConn = nil
|
||||
c.readTimeout = 0
|
||||
c.writeTimeout = 0
|
||||
return
|
||||
}
|
||||
|
||||
// IsTimeoutError will check whether the err is a timeout error.
|
||||
func IsTimeoutError(err error) bool {
|
||||
e, ok := err.(net.Error)
|
||||
if ok {
|
||||
return e.Timeout()
|
||||
}
|
||||
return false
|
||||
}
|
||||
23
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/utils/escape.go
generated
vendored
Executable file
23
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/utils/escape.go
generated
vendored
Executable file
@@ -0,0 +1,23 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// URLQueryEscape escapes the original string.
|
||||
func URLQueryEscape(origin string) string {
|
||||
escaped := url.QueryEscape(origin)
|
||||
escaped = strings.Replace(escaped, "%2F", "/", -1)
|
||||
escaped = strings.Replace(escaped, "%3D", "=", -1)
|
||||
escaped = strings.Replace(escaped, "+", "%20", -1)
|
||||
return escaped
|
||||
}
|
||||
|
||||
// URLQueryUnescape unescapes the escaped string.
|
||||
func URLQueryUnescape(escaped string) (string, error) {
|
||||
escaped = strings.Replace(escaped, "/", "%2F", -1)
|
||||
escaped = strings.Replace(escaped, "=", "%3D", -1)
|
||||
escaped = strings.Replace(escaped, "%20", " ", -1)
|
||||
return url.QueryUnescape(escaped)
|
||||
}
|
||||
23
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/version.go
generated
vendored
Executable file
23
.rclone_repo/vendor/github.com/yunify/qingstor-sdk-go/version.go
generated
vendored
Executable file
@@ -0,0 +1,23 @@
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Copyright (C) 2016 Yunify, Inc.
|
||||
// +-------------------------------------------------------------------------
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// | you may not use this work except in compliance with the License.
|
||||
// | You may obtain a copy of the License in the LICENSE file, or at:
|
||||
// |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// | Unless required by applicable law or agreed to in writing, software
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// | See the License for the specific language governing permissions and
|
||||
// | limitations under the License.
|
||||
// +-------------------------------------------------------------------------
|
||||
|
||||
// Package sdk is the official QingStor SDK for the Go programming language.
|
||||
//
|
||||
// https://github.com/yunify/qingstor-sdk-go
|
||||
package sdk
|
||||
|
||||
// Version number.
|
||||
const Version = "2.2.14"
|
||||
Reference in New Issue
Block a user