forked from TrueCloudLab/rclone
vendor: switch to using go1.11 modules
This commit is contained in:
parent
5c75453aba
commit
da1682a30e
6142 changed files with 390 additions and 5155875 deletions
288
vendor/github.com/Azure/azure-pipeline-go/.gitignore
generated
vendored
288
vendor/github.com/Azure/azure-pipeline-go/.gitignore
generated
vendored
|
@ -1,288 +0,0 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
**/Properties/launchSettings.json
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
14
vendor/github.com/Azure/azure-pipeline-go/README.md
generated
vendored
14
vendor/github.com/Azure/azure-pipeline-go/README.md
generated
vendored
|
@ -1,14 +0,0 @@
|
|||
|
||||
# Contributing
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a
|
||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
||||
the rights to use your contribution. For details, visit https://cla.microsoft.com.
|
||||
|
||||
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
|
||||
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
|
||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
|
||||
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/core.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/core.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_syslog.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_syslog.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/doc.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/doc.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/error.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/error.go
generated
vendored
Executable file → Normal file
75
vendor/github.com/Azure/azure-pipeline-go/pipeline/policies_test.go
generated
vendored
75
vendor/github.com/Azure/azure-pipeline-go/pipeline/policies_test.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
package pipeline_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// Here is the template for defining your own Factory & Policy:
|
||||
|
||||
// newMyPolicyFactory creates a 'My' policy factory. Make this function
|
||||
// public if this should be callable from another package; everything
|
||||
// else about the factory/policy should remain private to the package.
|
||||
func newMyPolicyFactory( /* Desired parameters */ ) pipeline.Factory {
|
||||
return &myPolicyFactory{ /* Set desired fields */ }
|
||||
}
|
||||
|
||||
type myPolicyFactory struct {
|
||||
// Desired fields (goroutine-safe because the factory is shared by many Policy objects)
|
||||
}
|
||||
|
||||
// New initializes a Xxx policy object.
|
||||
func (f *myPolicyFactory) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
return &myPolicy{next: next, po: po /* Set desired fields */}
|
||||
}
|
||||
|
||||
type myPolicy struct {
|
||||
next pipeline.Policy
|
||||
po *pipeline.PolicyOptions // Optional private field
|
||||
// Additional desired fields (mutable for use by this specific Policy object)
|
||||
}
|
||||
|
||||
func (p *myPolicy) Do(ctx context.Context, request pipeline.Request) (response pipeline.Response, err error) {
|
||||
// TODO: Put your policy behavior code here
|
||||
// Your code should NOT mutate the ctx or request parameters
|
||||
// However, you can make a copy of the request and mutate the copy
|
||||
// You can also pass a different Context on.
|
||||
// You can optionally use po (PolicyOptions) in this func.
|
||||
|
||||
// Forward the request to the next node in the pipeline:
|
||||
response, err = p.next.Do(ctx, request)
|
||||
|
||||
// Process the response here. You can deserialize the body into an object.
|
||||
// If you do this, also define a struct that wraps an http.Response & your
|
||||
// deserialized struct. Have your wrapper struct implement the
|
||||
// pipeline.Response interface and then return your struct (via the interface)
|
||||
// After the pipeline completes, take response and perform a type assertion
|
||||
// to get back to the wrapper struct so you can access the deserialized object.
|
||||
|
||||
return // Return the response & err
|
||||
}
|
||||
|
||||
func newMyPolicyFactory2( /* Desired parameters */ ) pipeline.Factory {
|
||||
return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc {
|
||||
return func(ctx context.Context, request pipeline.Request) (response pipeline.Response, err error) {
|
||||
// TODO: Put your policy behavior code here
|
||||
// Your code should NOT mutate the ctx or request parameters
|
||||
// However, you can make a copy of the request and mutate the copy
|
||||
// You can also pass a different Context on.
|
||||
// You can optionally use po (PolicyOptions) in this func.
|
||||
|
||||
// Forward the request to the next node in the pipeline:
|
||||
response, err = next.Do(ctx, request)
|
||||
|
||||
// Process the response here. You can deserialize the body into an object.
|
||||
// If you do this, also define a struct that wraps an http.Response & your
|
||||
// deserialized struct. Have your wrapper struct implement the
|
||||
// pipeline.Response interface and then return your struct (via the interface)
|
||||
// After the pipeline completes, take response and perform a type assertion
|
||||
// to get back to the wrapper struct so you can access the deserialized object.
|
||||
|
||||
return // Return the response & err
|
||||
}
|
||||
})
|
||||
}
|
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/progress.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/progress.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/request.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/request.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/response.go
generated
vendored
Executable file → Normal file
0
vendor/github.com/Azure/azure-pipeline-go/pipeline/response.go
generated
vendored
Executable file → Normal file
290
vendor/github.com/Azure/azure-storage-blob-go/.gitignore
generated
vendored
290
vendor/github.com/Azure/azure-storage-blob-go/.gitignore
generated
vendored
|
@ -1,290 +0,0 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
**/Properties/launchSettings.json
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
vendor/
|
7
vendor/github.com/Azure/azure-storage-blob-go/.travis.yml
generated
vendored
7
vendor/github.com/Azure/azure-storage-blob-go/.travis.yml
generated
vendored
|
@ -1,7 +0,0 @@
|
|||
language: python
|
||||
python:
|
||||
- 3.6
|
||||
services:
|
||||
- docker
|
||||
script:
|
||||
- make all
|
21
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/Gopkg.lock
generated
vendored
21
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/Gopkg.lock
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/Azure/azure-pipeline-go"
|
||||
packages = ["pipeline"]
|
||||
revision = "0f0dbf237bd47d5688310dbd3fac369353f280d0"
|
||||
version = "0.1.5"
|
||||
|
||||
[[projects]]
|
||||
branch = "v1"
|
||||
name = "gopkg.in/check.v1"
|
||||
packages = ["."]
|
||||
revision = "20d25e2804050c1cd24a7eea1e7a6447dd0e74ec"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "a6aef008d020b1455ef28ec8264c056f69bc26c0d32f711127c05dde5802f737"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
38
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/Gopkg.toml
generated
vendored
38
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/Gopkg.toml
generated
vendored
|
@ -1,38 +0,0 @@
|
|||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/Azure/azure-pipeline-go"
|
||||
version = "0.1.5"
|
||||
|
||||
[[constraint]]
|
||||
branch = "v1"
|
||||
name = "gopkg.in/check.v1"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
67
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/access_conditions.go
generated
vendored
67
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/access_conditions.go
generated
vendored
|
@ -1,67 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// HTTPAccessConditions identifies standard HTTP access conditions which you optionally set.
|
||||
type HTTPAccessConditions struct {
|
||||
IfModifiedSince time.Time
|
||||
IfUnmodifiedSince time.Time
|
||||
IfMatch ETag
|
||||
IfNoneMatch ETag
|
||||
}
|
||||
|
||||
// pointers is for internal infrastructure. It returns the fields as pointers.
|
||||
func (ac HTTPAccessConditions) pointers() (ims *time.Time, ius *time.Time, ime *ETag, inme *ETag) {
|
||||
if !ac.IfModifiedSince.IsZero() {
|
||||
ims = &ac.IfModifiedSince
|
||||
}
|
||||
if !ac.IfUnmodifiedSince.IsZero() {
|
||||
ius = &ac.IfUnmodifiedSince
|
||||
}
|
||||
if ac.IfMatch != ETagNone {
|
||||
ime = &ac.IfMatch
|
||||
}
|
||||
if ac.IfNoneMatch != ETagNone {
|
||||
inme = &ac.IfNoneMatch
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ContainerAccessConditions identifies container-specific access conditions which you optionally set.
|
||||
type ContainerAccessConditions struct {
|
||||
HTTPAccessConditions
|
||||
LeaseAccessConditions
|
||||
}
|
||||
|
||||
// BlobAccessConditions identifies blob-specific access conditions which you optionally set.
|
||||
type BlobAccessConditions struct {
|
||||
HTTPAccessConditions
|
||||
LeaseAccessConditions
|
||||
AppendBlobAccessConditions
|
||||
PageBlobAccessConditions
|
||||
}
|
||||
|
||||
// LeaseAccessConditions identifies lease access conditions for a container or blob which you optionally set.
|
||||
type LeaseAccessConditions struct {
|
||||
LeaseID string
|
||||
}
|
||||
|
||||
// pointers is for internal infrastructure. It returns the fields as pointers.
|
||||
func (ac LeaseAccessConditions) pointers() (leaseID *string) {
|
||||
if ac.LeaseID != "" {
|
||||
leaseID = &ac.LeaseID
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
// getInt32 is for internal infrastructure. It is used with access condition values where
|
||||
// 0 (the default setting) is meaningful. The library interprets 0 as do not send the header
|
||||
// and the privately-storage field in the access condition object is stored as +1 higher than desired.
|
||||
// THis method returns true, if the value is > 0 (explicitly set) and the stored value - 1 (the set desired value).
|
||||
func getInt32(value int32) (bool, int32) {
|
||||
return value > 0, value - 1
|
||||
}
|
||||
*/
|
56
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/credential_anonymous.go
generated
vendored
56
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/credential_anonymous.go
generated
vendored
|
@ -1,56 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// Credential represent any credential type; it is used to create a credential policy Factory.
|
||||
type Credential interface {
|
||||
pipeline.Factory
|
||||
credentialMarker()
|
||||
}
|
||||
|
||||
type credentialFunc pipeline.FactoryFunc
|
||||
|
||||
func (f credentialFunc) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
return f(next, po)
|
||||
}
|
||||
|
||||
// credentialMarker is a package-internal method that exists just to satisfy the Credential interface.
|
||||
func (credentialFunc) credentialMarker() {}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// NewAnonymousCredential creates an anonymous credential for use with HTTP(S)
|
||||
// requests that read blobs from public containers or for use with Shared Access
|
||||
// Signatures (SAS).
|
||||
func NewAnonymousCredential() Credential {
|
||||
return anonymousCredentialFactory
|
||||
}
|
||||
|
||||
var anonymousCredentialFactory Credential = &anonymousCredentialPolicyFactory{} // Singleton
|
||||
|
||||
// anonymousCredentialPolicyFactory is the credential's policy factory.
|
||||
type anonymousCredentialPolicyFactory struct {
|
||||
}
|
||||
|
||||
// New creates a credential policy object.
|
||||
func (f *anonymousCredentialPolicyFactory) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
return &anonymousCredentialPolicy{next: next}
|
||||
}
|
||||
|
||||
// credentialMarker is a package-internal method that exists just to satisfy the Credential interface.
|
||||
func (*anonymousCredentialPolicyFactory) credentialMarker() {}
|
||||
|
||||
// anonymousCredentialPolicy is the credential's policy object.
|
||||
type anonymousCredentialPolicy struct {
|
||||
next pipeline.Policy
|
||||
}
|
||||
|
||||
// Do implements the credential's policy interface.
|
||||
func (p anonymousCredentialPolicy) Do(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
|
||||
// For anonymous credentials, this is effectively a no-op
|
||||
return p.next.Do(ctx, request)
|
||||
}
|
187
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/credential_shared_key.go
generated
vendored
187
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/credential_shared_key.go
generated
vendored
|
@ -1,187 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// NewSharedKeyCredential creates an immutable SharedKeyCredential containing the
|
||||
// storage account's name and either its primary or secondary key.
|
||||
func NewSharedKeyCredential(accountName, accountKey string) *SharedKeyCredential {
|
||||
bytes, err := base64.StdEncoding.DecodeString(accountKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &SharedKeyCredential{accountName: accountName, accountKey: bytes}
|
||||
}
|
||||
|
||||
// SharedKeyCredential contains an account's name and its primary or secondary key.
|
||||
// It is immutable making it shareable and goroutine-safe.
|
||||
type SharedKeyCredential struct {
|
||||
// Only the NewSharedKeyCredential method should set these; all other methods should treat them as read-only
|
||||
accountName string
|
||||
accountKey []byte
|
||||
}
|
||||
|
||||
// AccountName returns the Storage account's name.
|
||||
func (f SharedKeyCredential) AccountName() string {
|
||||
return f.accountName
|
||||
}
|
||||
|
||||
// New creates a credential policy object.
|
||||
func (f *SharedKeyCredential) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
return pipeline.PolicyFunc(func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
|
||||
// Add a x-ms-date header if it doesn't already exist
|
||||
if d := request.Header.Get(headerXmsDate); d == "" {
|
||||
request.Header[headerXmsDate] = []string{time.Now().UTC().Format(http.TimeFormat)}
|
||||
}
|
||||
stringToSign := f.buildStringToSign(request)
|
||||
signature := f.ComputeHMACSHA256(stringToSign)
|
||||
authHeader := strings.Join([]string{"SharedKey ", f.accountName, ":", signature}, "")
|
||||
request.Header[headerAuthorization] = []string{authHeader}
|
||||
|
||||
response, err := next.Do(ctx, request)
|
||||
if err != nil && response != nil && response.Response() != nil && response.Response().StatusCode == http.StatusForbidden {
|
||||
// Service failed to authenticate request, log it
|
||||
po.Log(pipeline.LogError, "===== HTTP Forbidden status, String-to-Sign:\n"+stringToSign+"\n===============================\n")
|
||||
}
|
||||
return response, err
|
||||
})
|
||||
}
|
||||
|
||||
// credentialMarker is a package-internal method that exists just to satisfy the Credential interface.
|
||||
func (*SharedKeyCredential) credentialMarker() {}
|
||||
|
||||
// Constants ensuring that header names are correctly spelled and consistently cased.
|
||||
const (
|
||||
headerAuthorization = "Authorization"
|
||||
headerCacheControl = "Cache-Control"
|
||||
headerContentEncoding = "Content-Encoding"
|
||||
headerContentDisposition = "Content-Disposition"
|
||||
headerContentLanguage = "Content-Language"
|
||||
headerContentLength = "Content-Length"
|
||||
headerContentMD5 = "Content-MD5"
|
||||
headerContentType = "Content-Type"
|
||||
headerDate = "Date"
|
||||
headerIfMatch = "If-Match"
|
||||
headerIfModifiedSince = "If-Modified-Since"
|
||||
headerIfNoneMatch = "If-None-Match"
|
||||
headerIfUnmodifiedSince = "If-Unmodified-Since"
|
||||
headerRange = "Range"
|
||||
headerUserAgent = "User-Agent"
|
||||
headerXmsDate = "x-ms-date"
|
||||
headerXmsVersion = "x-ms-version"
|
||||
)
|
||||
|
||||
// ComputeHMACSHA256 generates a hash signature for an HTTP request or for a SAS.
|
||||
func (f *SharedKeyCredential) ComputeHMACSHA256(message string) (base64String string) {
|
||||
h := hmac.New(sha256.New, f.accountKey)
|
||||
h.Write([]byte(message))
|
||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
func (f *SharedKeyCredential) buildStringToSign(request pipeline.Request) string {
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services
|
||||
headers := request.Header
|
||||
contentLength := headers.Get(headerContentLength)
|
||||
if contentLength == "0" {
|
||||
contentLength = ""
|
||||
}
|
||||
|
||||
stringToSign := strings.Join([]string{
|
||||
request.Method,
|
||||
headers.Get(headerContentEncoding),
|
||||
headers.Get(headerContentLanguage),
|
||||
contentLength,
|
||||
headers.Get(headerContentMD5),
|
||||
headers.Get(headerContentType),
|
||||
"", // Empty date because x-ms-date is expected (as per web page above)
|
||||
headers.Get(headerIfModifiedSince),
|
||||
headers.Get(headerIfMatch),
|
||||
headers.Get(headerIfNoneMatch),
|
||||
headers.Get(headerIfUnmodifiedSince),
|
||||
headers.Get(headerRange),
|
||||
buildCanonicalizedHeader(headers),
|
||||
f.buildCanonicalizedResource(request.URL),
|
||||
}, "\n")
|
||||
return stringToSign
|
||||
}
|
||||
|
||||
func buildCanonicalizedHeader(headers http.Header) string {
|
||||
cm := map[string][]string{}
|
||||
for k, v := range headers {
|
||||
headerName := strings.TrimSpace(strings.ToLower(k))
|
||||
if strings.HasPrefix(headerName, "x-ms-") {
|
||||
cm[headerName] = v // NOTE: the value must not have any whitespace around it.
|
||||
}
|
||||
}
|
||||
if len(cm) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(cm))
|
||||
for key := range cm {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
ch := bytes.NewBufferString("")
|
||||
for i, key := range keys {
|
||||
if i > 0 {
|
||||
ch.WriteRune('\n')
|
||||
}
|
||||
ch.WriteString(key)
|
||||
ch.WriteRune(':')
|
||||
ch.WriteString(strings.Join(cm[key], ","))
|
||||
}
|
||||
return string(ch.Bytes())
|
||||
}
|
||||
|
||||
func (f *SharedKeyCredential) buildCanonicalizedResource(u *url.URL) string {
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services
|
||||
cr := bytes.NewBufferString("/")
|
||||
cr.WriteString(f.accountName)
|
||||
|
||||
if len(u.Path) > 0 {
|
||||
// Any portion of the CanonicalizedResource string that is derived from
|
||||
// the resource's URI should be encoded exactly as it is in the URI.
|
||||
// -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx
|
||||
cr.WriteString(u.EscapedPath())
|
||||
} else {
|
||||
// a slash is required to indicate the root path
|
||||
cr.WriteString("/")
|
||||
}
|
||||
|
||||
// params is a map[string][]string; param name is key; params values is []string
|
||||
params, err := url.ParseQuery(u.RawQuery) // Returns URL decoded values
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if len(params) > 0 { // There is at least 1 query parameter
|
||||
paramNames := []string{} // We use this to sort the parameter key names
|
||||
for paramName := range params {
|
||||
paramNames = append(paramNames, paramName) // paramNames must be lowercase
|
||||
}
|
||||
sort.Strings(paramNames)
|
||||
|
||||
for _, paramName := range paramNames {
|
||||
paramValues := params[paramName]
|
||||
sort.Strings(paramValues)
|
||||
|
||||
// Join the sorted key values separated by ','
|
||||
// Then prepend "keyName:"; then add this string to the buffer
|
||||
cr.WriteString("\n" + paramName + ":" + strings.Join(paramValues, ","))
|
||||
}
|
||||
}
|
||||
return string(cr.Bytes())
|
||||
}
|
39
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/credential_token.go
generated
vendored
39
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/credential_token.go
generated
vendored
|
@ -1,39 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// NewTokenCredential creates a token credential for use with role-based
|
||||
// access control (RBAC) access to Azure Storage resources.
|
||||
func NewTokenCredential(token string) *TokenCredential {
|
||||
f := &TokenCredential{}
|
||||
f.SetToken(token)
|
||||
return f
|
||||
}
|
||||
|
||||
// TokenCredential is a pipeline.Factory is the credential's policy factory.
|
||||
type TokenCredential struct{ token atomic.Value }
|
||||
|
||||
// Token returns the current token value
|
||||
func (f *TokenCredential) Token() string { return f.token.Load().(string) }
|
||||
|
||||
// SetToken changes the current token value
|
||||
func (f *TokenCredential) SetToken(token string) { f.token.Store(token) }
|
||||
|
||||
// credentialMarker is a package-internal method that exists just to satisfy the Credential interface.
|
||||
func (*TokenCredential) credentialMarker() {}
|
||||
|
||||
// New creates a credential policy object.
|
||||
func (f *TokenCredential) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
return pipeline.PolicyFunc(func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
|
||||
if request.URL.Scheme != "https" {
|
||||
panic("Token credentials require a URL using the https protocol scheme.")
|
||||
}
|
||||
request.Header[headerAuthorization] = []string{"Bearer " + f.Token()}
|
||||
return next.Do(ctx, request)
|
||||
})
|
||||
}
|
250
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/highlevel.go
generated
vendored
250
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/highlevel.go
generated
vendored
|
@ -1,250 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"bytes"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// CommonResponseHeaders returns the headers common to all blob REST API responses.
|
||||
type CommonResponse interface {
|
||||
// ETag returns the value for header ETag.
|
||||
ETag() ETag
|
||||
|
||||
// LastModified returns the value for header Last-Modified.
|
||||
LastModified() time.Time
|
||||
|
||||
// RequestID returns the value for header x-ms-request-id.
|
||||
RequestID() string
|
||||
|
||||
// Date returns the value for header Date.
|
||||
Date() time.Time
|
||||
|
||||
// Version returns the value for header x-ms-version.
|
||||
Version() string
|
||||
|
||||
// Response returns the raw HTTP response object.
|
||||
Response() *http.Response
|
||||
}
|
||||
|
||||
// UploadToBlockBlobOptions identifies options used by the UploadBufferToBlockBlob and UploadFileToBlockBlob functions.
|
||||
type UploadToBlockBlobOptions struct {
|
||||
// BlockSize specifies the block size to use; the default (and maximum size) is BlockBlobMaxPutBlockBytes.
|
||||
BlockSize uint64
|
||||
|
||||
// Progress is a function that is invoked periodically as bytes are send in a PutBlock call to the BlockBlobURL.
|
||||
Progress pipeline.ProgressReceiver
|
||||
|
||||
// BlobHTTPHeaders indicates the HTTP headers to be associated with the blob when PutBlockList is called.
|
||||
BlobHTTPHeaders BlobHTTPHeaders
|
||||
|
||||
// Metadata indicates the metadata to be associated with the blob when PutBlockList is called.
|
||||
Metadata Metadata
|
||||
|
||||
// AccessConditions indicates the access conditions for the block blob.
|
||||
AccessConditions BlobAccessConditions
|
||||
|
||||
// Parallelism indicates the maximum number of blocks to upload in parallel (0=default)
|
||||
Parallelism uint16
|
||||
}
|
||||
|
||||
// UploadBufferToBlockBlob uploads a buffer in blocks to a block blob.
|
||||
func UploadBufferToBlockBlob(ctx context.Context, b []byte,
|
||||
blockBlobURL BlockBlobURL, o UploadToBlockBlobOptions) (CommonResponse, error) {
|
||||
|
||||
if o.BlockSize < 0 || o.BlockSize > BlockBlobMaxPutBlockBytes {
|
||||
panic(fmt.Sprintf("BlockSize option must be > 0 and <= %d", BlockBlobMaxPutBlockBytes))
|
||||
}
|
||||
if o.BlockSize == 0 {
|
||||
o.BlockSize = BlockBlobMaxPutBlockBytes // Default if unspecified
|
||||
}
|
||||
size := uint64(len(b))
|
||||
|
||||
if size <= BlockBlobMaxPutBlobBytes {
|
||||
// If the size can fit in 1 Put Blob call, do it this way
|
||||
var body io.ReadSeeker = bytes.NewReader(b)
|
||||
if o.Progress != nil {
|
||||
body = pipeline.NewRequestBodyProgress(body, o.Progress)
|
||||
}
|
||||
return blockBlobURL.PutBlob(ctx, body, o.BlobHTTPHeaders, o.Metadata, o.AccessConditions)
|
||||
}
|
||||
|
||||
parallelism := o.Parallelism
|
||||
if parallelism == 0 {
|
||||
parallelism = 5 // default parallelism
|
||||
}
|
||||
|
||||
var numBlocks uint16 = uint16(((size - 1) / o.BlockSize) + 1)
|
||||
if numBlocks > BlockBlobMaxBlocks {
|
||||
panic(fmt.Sprintf("The streamSize is too big or the BlockSize is too small; the number of blocks must be <= %d", BlockBlobMaxBlocks))
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
blockIDList := make([]string, numBlocks) // Base 64 encoded block IDs
|
||||
blockSize := o.BlockSize
|
||||
|
||||
putBlockChannel := make(chan func() (*BlockBlobsPutBlockResponse, error), parallelism) // Create the channel that release 'parallelism' goroutines concurrently
|
||||
putBlockResponseChannel := make(chan error, numBlocks) // Holds each Put Block's response
|
||||
|
||||
// Create the goroutines that process each Put Block (in parallel)
|
||||
for g := uint16(0); g < parallelism; g++ {
|
||||
go func() {
|
||||
for f := range putBlockChannel {
|
||||
_, err := f()
|
||||
putBlockResponseChannel <- err
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
blobProgress := int64(0)
|
||||
progressLock := &sync.Mutex{}
|
||||
|
||||
// Add each put block to the channel
|
||||
for blockNum := uint16(0); blockNum < numBlocks; blockNum++ {
|
||||
if blockNum == numBlocks-1 { // Last block
|
||||
blockSize = size - (uint64(blockNum) * o.BlockSize) // Remove size of all uploaded blocks from total
|
||||
}
|
||||
offset := uint64(blockNum) * o.BlockSize
|
||||
|
||||
// Prepare to read the proper block/section of the buffer
|
||||
var body io.ReadSeeker = bytes.NewReader(b[offset : offset+blockSize])
|
||||
capturedBlockNum := blockNum
|
||||
if o.Progress != nil {
|
||||
blockProgress := int64(0)
|
||||
body = pipeline.NewRequestBodyProgress(body,
|
||||
func(bytesTransferred int64) {
|
||||
diff := bytesTransferred - blockProgress
|
||||
blockProgress = bytesTransferred
|
||||
progressLock.Lock()
|
||||
blobProgress += diff
|
||||
o.Progress(blobProgress)
|
||||
progressLock.Unlock()
|
||||
})
|
||||
}
|
||||
|
||||
// Block IDs are unique values to avoid issue if 2+ clients are uploading blocks
|
||||
// at the same time causing PutBlockList to get a mix of blocks from all the clients.
|
||||
blockIDList[blockNum] = base64.StdEncoding.EncodeToString(newUUID().bytes())
|
||||
putBlockChannel <- func() (*BlockBlobsPutBlockResponse, error) {
|
||||
return blockBlobURL.PutBlock(ctx, blockIDList[capturedBlockNum], body, o.AccessConditions.LeaseAccessConditions)
|
||||
}
|
||||
}
|
||||
close(putBlockChannel)
|
||||
|
||||
// Wait for the put blocks to complete
|
||||
for blockNum := uint16(0); blockNum < numBlocks; blockNum++ {
|
||||
responseError := <-putBlockResponseChannel
|
||||
if responseError != nil {
|
||||
cancel() // As soon as any Put Block fails, cancel all remaining Put Block calls
|
||||
return nil, responseError // No need to process anymore responses
|
||||
}
|
||||
}
|
||||
// All put blocks were successful, call Put Block List to finalize the blob
|
||||
return blockBlobURL.PutBlockList(ctx, blockIDList, o.BlobHTTPHeaders, o.Metadata, o.AccessConditions)
|
||||
}
|
||||
|
||||
// UploadFileToBlockBlob uploads a file in blocks to a block blob.
|
||||
func UploadFileToBlockBlob(ctx context.Context, file *os.File,
|
||||
blockBlobURL BlockBlobURL, o UploadToBlockBlobOptions) (CommonResponse, error) {
|
||||
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := mmf{} // Default to an empty slice; used for 0-size file
|
||||
if stat.Size() != 0 {
|
||||
m, err = newMMF(file, false, 0, int(stat.Size()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer m.unmap()
|
||||
}
|
||||
return UploadBufferToBlockBlob(ctx, m, blockBlobURL, o)
|
||||
}
|
||||
|
||||
// DownloadStreamOptions is used to configure a call to NewDownloadBlobToStream to download a large stream with intelligent retries.
|
||||
type DownloadStreamOptions struct {
|
||||
// Range indicates the starting offset and count of bytes within the blob to download.
|
||||
Range BlobRange
|
||||
|
||||
// AccessConditions indicates the BlobAccessConditions to use when accessing the blob.
|
||||
AccessConditions BlobAccessConditions
|
||||
}
|
||||
|
||||
type retryStream struct {
|
||||
ctx context.Context
|
||||
getBlob func(ctx context.Context, blobRange BlobRange, ac BlobAccessConditions, rangeGetContentMD5 bool) (*GetResponse, error)
|
||||
o DownloadStreamOptions
|
||||
response *http.Response
|
||||
}
|
||||
|
||||
// NewDownloadStream creates a stream over a blob allowing you download the blob's contents.
|
||||
// When network errors occur, the retry stream internally issues new HTTP GET requests for
|
||||
// the remaining range of the blob's contents. The GetBlob argument identifies the function
|
||||
// to invoke when the GetRetryStream needs to make an HTTP GET request as Read methods are called.
|
||||
// The callback can wrap the response body (with progress reporting, for example) before returning.
|
||||
func NewDownloadStream(ctx context.Context,
|
||||
getBlob func(ctx context.Context, blobRange BlobRange, ac BlobAccessConditions, rangeGetContentMD5 bool) (*GetResponse, error),
|
||||
o DownloadStreamOptions) io.ReadCloser {
|
||||
|
||||
// BlobAccessConditions may already have an If-Match:etag header
|
||||
if getBlob == nil {
|
||||
panic("getBlob must not be nil")
|
||||
}
|
||||
return &retryStream{ctx: ctx, getBlob: getBlob, o: o, response: nil}
|
||||
}
|
||||
|
||||
func (s *retryStream) Read(p []byte) (n int, err error) {
|
||||
for {
|
||||
if s.response != nil { // We working with a successful response
|
||||
n, err := s.response.Body.Read(p) // Read from the stream
|
||||
if err == nil || err == io.EOF { // We successfully read data or end EOF
|
||||
s.o.Range.Offset += int64(n) // Increments the start offset in case we need to make a new HTTP request in the future
|
||||
if s.o.Range.Count != 0 {
|
||||
s.o.Range.Count -= int64(n) // Decrement the count in case we need to make a new HTTP request in the future
|
||||
}
|
||||
return n, err // Return the return to the caller
|
||||
}
|
||||
s.Close()
|
||||
s.response = nil // Something went wrong; our stream is no longer good
|
||||
if nerr, ok := err.(net.Error); ok {
|
||||
if !nerr.Timeout() && !nerr.Temporary() {
|
||||
return n, err // Not retryable
|
||||
}
|
||||
} else {
|
||||
return n, err // Not retryable, just return
|
||||
}
|
||||
}
|
||||
|
||||
// We don't have a response stream to read from, try to get one
|
||||
response, err := s.getBlob(s.ctx, s.o.Range, s.o.AccessConditions, false)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Successful GET; this is the network stream we'll read from
|
||||
s.response = response.Response()
|
||||
|
||||
// Ensure that future requests are from the same version of the source
|
||||
s.o.AccessConditions.IfMatch = response.ETag()
|
||||
|
||||
// Loop around and try to read from this stream
|
||||
}
|
||||
}
|
||||
|
||||
func (s *retryStream) Close() error {
|
||||
if s.response != nil && s.response.Body != nil {
|
||||
return s.response.Body.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
27
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/mmf_unix.go
generated
vendored
27
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/mmf_unix.go
generated
vendored
|
@ -1,27 +0,0 @@
|
|||
// +build linux darwin freebsd
|
||||
|
||||
package azblob
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type mmf []byte
|
||||
|
||||
func newMMF(file *os.File, writable bool, offset int64, length int) (mmf, error) {
|
||||
prot, flags := syscall.PROT_READ, syscall.MAP_SHARED // Assume read-only
|
||||
if writable {
|
||||
prot, flags = syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED
|
||||
}
|
||||
addr, err := syscall.Mmap(int(file.Fd()), offset, length, prot, flags)
|
||||
return mmf(addr), err
|
||||
}
|
||||
|
||||
func (m *mmf) unmap() {
|
||||
err := syscall.Munmap(*m)
|
||||
*m = nil
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
38
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/mmf_windows.go
generated
vendored
38
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/mmf_windows.go
generated
vendored
|
@ -1,38 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type mmf []byte
|
||||
|
||||
func newMMF(file *os.File, writable bool, offset int64, length int) (mmf, error) {
|
||||
prot, access := uint32(syscall.PAGE_READONLY), uint32(syscall.FILE_MAP_READ) // Assume read-only
|
||||
if writable {
|
||||
prot, access = uint32(syscall.PAGE_READWRITE), uint32(syscall.FILE_MAP_WRITE)
|
||||
}
|
||||
hMMF, errno := syscall.CreateFileMapping(syscall.Handle(file.Fd()), nil, prot, uint32(int64(length)>>32), uint32(int64(length)&0xffffffff), nil)
|
||||
if hMMF == 0 {
|
||||
return nil, os.NewSyscallError("CreateFileMapping", errno)
|
||||
}
|
||||
defer syscall.CloseHandle(hMMF)
|
||||
addr, errno := syscall.MapViewOfFile(hMMF, access, uint32(offset>>32), uint32(offset&0xffffffff), uintptr(length))
|
||||
m := mmf{}
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&m))
|
||||
h.Data = addr
|
||||
h.Len = length
|
||||
h.Cap = h.Len
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m *mmf) unmap() {
|
||||
addr := uintptr(unsafe.Pointer(&(([]byte)(*m)[0])))
|
||||
*m = mmf{}
|
||||
err := syscall.UnmapViewOfFile(addr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
111
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/parsing_urls.go
generated
vendored
111
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/parsing_urls.go
generated
vendored
|
@ -1,111 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
snapshotTimeFormat = "2006-01-02T15:04:05.0000000Z07:00"
|
||||
)
|
||||
|
||||
// A BlobURLParts object represents the components that make up an Azure Storage Container/Blob URL. You parse an
|
||||
// existing URL into its parts by calling NewBlobURLParts(). You construct a URL from parts by calling URL().
|
||||
// NOTE: Changing any SAS-related field requires computing a new SAS signature.
|
||||
type BlobURLParts struct {
|
||||
Scheme string // Ex: "https://"
|
||||
Host string // Ex: "account.blob.core.windows.net"
|
||||
ContainerName string // "" if no container
|
||||
BlobName string // "" if no blob
|
||||
Snapshot time.Time // IsZero is true if not a snapshot
|
||||
SAS SASQueryParameters
|
||||
UnparsedParams string
|
||||
}
|
||||
|
||||
// NewBlobURLParts parses a URL initializing BlobURLParts' fields including any SAS-related & snapshot query parameters. Any other
|
||||
// query parameters remain in the UnparsedParams field. This method overwrites all fields in the BlobURLParts object.
|
||||
func NewBlobURLParts(u url.URL) BlobURLParts {
|
||||
up := BlobURLParts{
|
||||
Scheme: u.Scheme,
|
||||
Host: u.Host,
|
||||
}
|
||||
|
||||
// Find the container & blob names (if any)
|
||||
if u.Path != "" {
|
||||
path := u.Path
|
||||
if path[0] == '/' {
|
||||
path = path[1:] // If path starts with a slash, remove it
|
||||
}
|
||||
|
||||
// Find the next slash (if it exists)
|
||||
containerEndIndex := strings.Index(path, "/")
|
||||
if containerEndIndex == -1 { // Slash not found; path has container name & no blob name
|
||||
up.ContainerName = path
|
||||
} else {
|
||||
up.ContainerName = path[:containerEndIndex] // The container name is the part between the slashes
|
||||
up.BlobName = path[containerEndIndex+1:] // The blob name is after the container slash
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the query parameters to a case-sensitive map & trim whitespace
|
||||
paramsMap := u.Query()
|
||||
|
||||
up.Snapshot = time.Time{} // Assume no snapshot
|
||||
if snapshotStr, ok := caseInsensitiveValues(paramsMap).Get("snapshot"); ok {
|
||||
up.Snapshot, _ = time.Parse(snapshotTimeFormat, snapshotStr[0])
|
||||
// If we recognized the query parameter, remove it from the map
|
||||
delete(paramsMap, "snapshot")
|
||||
}
|
||||
up.SAS = newSASQueryParameters(paramsMap, true)
|
||||
up.UnparsedParams = paramsMap.Encode()
|
||||
return up
|
||||
}
|
||||
|
||||
type caseInsensitiveValues url.Values // map[string][]string
|
||||
func (values caseInsensitiveValues) Get(key string) ([]string, bool) {
|
||||
key = strings.ToLower(key)
|
||||
for k, v := range values {
|
||||
if strings.ToLower(k) == key {
|
||||
return v, true
|
||||
}
|
||||
}
|
||||
return []string{}, false
|
||||
}
|
||||
|
||||
// URL returns a URL object whose fields are initialized from the BlobURLParts fields. The URL's RawQuery
|
||||
// field contains the SAS, snapshot, and unparsed query parameters.
|
||||
func (up BlobURLParts) URL() url.URL {
|
||||
path := ""
|
||||
// Concatenate container & blob names (if they exist)
|
||||
if up.ContainerName != "" {
|
||||
path += "/" + up.ContainerName
|
||||
if up.BlobName != "" {
|
||||
path += "/" + up.BlobName
|
||||
}
|
||||
}
|
||||
|
||||
rawQuery := up.UnparsedParams
|
||||
|
||||
// Concatenate blob snapshot query parameter (if it exists)
|
||||
if !up.Snapshot.IsZero() {
|
||||
if len(rawQuery) > 0 {
|
||||
rawQuery += "&"
|
||||
}
|
||||
rawQuery += "snapshot=" + up.Snapshot.Format(snapshotTimeFormat)
|
||||
}
|
||||
sas := up.SAS.Encode()
|
||||
if sas != "" {
|
||||
if len(rawQuery) > 0 {
|
||||
rawQuery += "&"
|
||||
}
|
||||
rawQuery += sas
|
||||
}
|
||||
u := url.URL{
|
||||
Scheme: up.Scheme,
|
||||
Host: up.Host,
|
||||
Path: path,
|
||||
RawQuery: rawQuery,
|
||||
}
|
||||
return u
|
||||
}
|
150
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/policy_request_log.go
generated
vendored
150
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/policy_request_log.go
generated
vendored
|
@ -1,150 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// RequestLogOptions configures the retry policy's behavior.
|
||||
type RequestLogOptions struct {
|
||||
// LogWarningIfTryOverThreshold logs a warning if a tried operation takes longer than the specified
|
||||
// duration (-1=no logging; 0=default threshold).
|
||||
LogWarningIfTryOverThreshold time.Duration
|
||||
}
|
||||
|
||||
func (o RequestLogOptions) defaults() RequestLogOptions {
|
||||
if o.LogWarningIfTryOverThreshold == 0 {
|
||||
// It would be good to relate this to https://azure.microsoft.com/en-us/support/legal/sla/storage/v1_2/
|
||||
// But this monitors the time to get the HTTP response; NOT the time to download the response body.
|
||||
o.LogWarningIfTryOverThreshold = 3 * time.Second // Default to 3 seconds
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// NewRequestLogPolicyFactory creates a RequestLogPolicyFactory object configured using the specified options.
|
||||
func NewRequestLogPolicyFactory(o RequestLogOptions) pipeline.Factory {
|
||||
o = o.defaults() // Force defaults to be calculated
|
||||
return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc {
|
||||
// These variables are per-policy; shared by multiple calls to Do
|
||||
var try int32
|
||||
operationStart := time.Now() // If this is the 1st try, record the operation state time
|
||||
return func(ctx context.Context, request pipeline.Request) (response pipeline.Response, err error) {
|
||||
try++ // The first try is #1 (not #0)
|
||||
|
||||
// Log the outgoing request as informational
|
||||
if po.ShouldLog(pipeline.LogInfo) {
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "==> OUTGOING REQUEST (Try=%d)\n", try)
|
||||
pipeline.WriteRequestWithResponse(b, prepareRequestForLogging(request), nil, nil)
|
||||
po.Log(pipeline.LogInfo, b.String())
|
||||
}
|
||||
|
||||
// Set the time for this particular retry operation and then Do the operation.
|
||||
tryStart := time.Now()
|
||||
response, err = next.Do(ctx, request) // Make the request
|
||||
tryEnd := time.Now()
|
||||
tryDuration := tryEnd.Sub(tryStart)
|
||||
opDuration := tryEnd.Sub(operationStart)
|
||||
|
||||
logLevel, forceLog := pipeline.LogInfo, false // Default logging information
|
||||
|
||||
// If the response took too long, we'll upgrade to warning.
|
||||
if o.LogWarningIfTryOverThreshold > 0 && tryDuration > o.LogWarningIfTryOverThreshold {
|
||||
// Log a warning if the try duration exceeded the specified threshold
|
||||
logLevel, forceLog = pipeline.LogWarning, true
|
||||
}
|
||||
|
||||
if err == nil { // We got a response from the service
|
||||
sc := response.Response().StatusCode
|
||||
if ((sc >= 400 && sc <= 499) && sc != http.StatusNotFound && sc != http.StatusConflict && sc != http.StatusPreconditionFailed && sc != http.StatusRequestedRangeNotSatisfiable) || (sc >= 500 && sc <= 599) {
|
||||
logLevel, forceLog = pipeline.LogError, true // Promote to Error any 4xx (except those listed is an error) or any 5xx
|
||||
} else {
|
||||
// For other status codes, we leave the level as is.
|
||||
}
|
||||
} else { // This error did not get an HTTP response from the service; upgrade the severity to Error
|
||||
logLevel, forceLog = pipeline.LogError, true
|
||||
}
|
||||
|
||||
if shouldLog := po.ShouldLog(logLevel); forceLog || shouldLog {
|
||||
// We're going to log this; build the string to log
|
||||
b := &bytes.Buffer{}
|
||||
slow := ""
|
||||
if o.LogWarningIfTryOverThreshold > 0 && tryDuration > o.LogWarningIfTryOverThreshold {
|
||||
slow = fmt.Sprintf("[SLOW >%v]", o.LogWarningIfTryOverThreshold)
|
||||
}
|
||||
fmt.Fprintf(b, "==> REQUEST/RESPONSE (Try=%d/%v%s, OpTime=%v) -- ", try, tryDuration, slow, opDuration)
|
||||
if err != nil { // This HTTP request did not get a response from the service
|
||||
fmt.Fprintf(b, "REQUEST ERROR\n")
|
||||
} else {
|
||||
if logLevel == pipeline.LogError {
|
||||
fmt.Fprintf(b, "RESPONSE STATUS CODE ERROR\n")
|
||||
} else {
|
||||
fmt.Fprintf(b, "RESPONSE SUCCESSFULLY RECEIVED\n")
|
||||
}
|
||||
}
|
||||
|
||||
pipeline.WriteRequestWithResponse(b, prepareRequestForLogging(request), response.Response(), err)
|
||||
if logLevel <= pipeline.LogError {
|
||||
b.Write(stack()) // For errors (or lower levels), we append the stack trace (an expensive operation)
|
||||
}
|
||||
msg := b.String()
|
||||
|
||||
if forceLog {
|
||||
pipeline.ForceLog(logLevel, msg)
|
||||
}
|
||||
if shouldLog {
|
||||
po.Log(logLevel, msg)
|
||||
}
|
||||
}
|
||||
return response, err
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func redactSigQueryParam(rawQuery string) (bool, string) {
|
||||
rawQuery = strings.ToLower(rawQuery) // lowercase the string so we can look for ?sig= and &sig=
|
||||
sigFound := strings.Contains(rawQuery, "?sig=")
|
||||
if !sigFound {
|
||||
sigFound = strings.Contains(rawQuery, "&sig=")
|
||||
if !sigFound {
|
||||
return sigFound, rawQuery // [?|&]sig= not found; return same rawQuery passed in (no memory allocation)
|
||||
}
|
||||
}
|
||||
// [?|&]sig= found, redact its value
|
||||
values, _ := url.ParseQuery(rawQuery)
|
||||
for name := range values {
|
||||
if strings.EqualFold(name, "sig") {
|
||||
values[name] = []string{"REDACTED"}
|
||||
}
|
||||
}
|
||||
return sigFound, values.Encode()
|
||||
}
|
||||
|
||||
func prepareRequestForLogging(request pipeline.Request) *http.Request {
|
||||
req := request
|
||||
if sigFound, rawQuery := redactSigQueryParam(req.URL.RawQuery); sigFound {
|
||||
// Make copy so we don't destroy the query parameters we actually need to send in the request
|
||||
req = request.Copy()
|
||||
req.Request.URL.RawQuery = rawQuery
|
||||
}
|
||||
return req.Request
|
||||
}
|
||||
|
||||
func stack() []byte {
|
||||
buf := make([]byte, 1024)
|
||||
for {
|
||||
n := runtime.Stack(buf, false)
|
||||
if n < len(buf) {
|
||||
return buf[:n]
|
||||
}
|
||||
buf = make([]byte, 2*len(buf))
|
||||
}
|
||||
}
|
302
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/policy_retry.go
generated
vendored
302
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/policy_retry.go
generated
vendored
|
@ -1,302 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// RetryPolicy tells the pipeline what kind of retry policy to use. See the RetryPolicy* constants.
|
||||
type RetryPolicy int32
|
||||
|
||||
const (
|
||||
// RetryPolicyExponential tells the pipeline to use an exponential back-off retry policy
|
||||
RetryPolicyExponential RetryPolicy = 0
|
||||
|
||||
// RetryPolicyFixed tells the pipeline to use a fixed back-off retry policy
|
||||
RetryPolicyFixed RetryPolicy = 1
|
||||
)
|
||||
|
||||
// RetryOptions configures the retry policy's behavior.
|
||||
type RetryOptions struct {
|
||||
// Policy tells the pipeline what kind of retry policy to use. See the RetryPolicy* constants.\
|
||||
// A value of zero means that you accept our default policy.
|
||||
Policy RetryPolicy
|
||||
|
||||
// MaxTries specifies the maximum number of attempts an operation will be tried before producing an error (0=default).
|
||||
// A value of zero means that you accept our default policy. A value of 1 means 1 try and no retries.
|
||||
MaxTries int32
|
||||
|
||||
// TryTimeout indicates the maximum time allowed for any single try of an HTTP request.
|
||||
// A value of zero means that you accept our default timeout. NOTE: When transferring large amounts
|
||||
// of data, the default TryTimeout will probably not be sufficient. You should override this value
|
||||
// based on the bandwidth available to the host machine and proximity to the Storage service. A good
|
||||
// starting point may be something like (60 seconds per MB of anticipated-payload-size).
|
||||
TryTimeout time.Duration
|
||||
|
||||
// RetryDelay specifies the amount of delay to use before retrying an operation (0=default).
|
||||
// The delay increases (exponentially or linearly) with each retry up to a maximum specified by
|
||||
// MaxRetryDelay. If you specify 0, then you must also specify 0 for MaxRetryDelay.
|
||||
RetryDelay time.Duration
|
||||
|
||||
// MaxRetryDelay specifies the maximum delay allowed before retrying an operation (0=default).
|
||||
// If you specify 0, then you must also specify 0 for RetryDelay.
|
||||
MaxRetryDelay time.Duration
|
||||
|
||||
// RetryReadsFromSecondaryHost specifies whether the retry policy should retry a read operation against another host.
|
||||
// If RetryReadsFromSecondaryHost is "" (the default) then operations are not retried against another host.
|
||||
// NOTE: Before setting this field, make sure you understand the issues around reading stale & potentially-inconsistent
|
||||
// data at this webpage: https://docs.microsoft.com/en-us/azure/storage/common/storage-designing-ha-apps-with-ragrs
|
||||
RetryReadsFromSecondaryHost string
|
||||
}
|
||||
|
||||
func (o RetryOptions) defaults() RetryOptions {
|
||||
if o.Policy != RetryPolicyExponential && o.Policy != RetryPolicyFixed {
|
||||
panic("RetryPolicy must be RetryPolicyExponential or RetryPolicyFixed")
|
||||
}
|
||||
if o.MaxTries < 0 {
|
||||
panic("MaxTries must be >= 0")
|
||||
}
|
||||
if o.TryTimeout < 0 || o.RetryDelay < 0 || o.MaxRetryDelay < 0 {
|
||||
panic("TryTimeout, RetryDelay, and MaxRetryDelay must all be >= 0")
|
||||
}
|
||||
if o.RetryDelay > o.MaxRetryDelay {
|
||||
panic("RetryDelay must be <= MaxRetryDelay")
|
||||
}
|
||||
if (o.RetryDelay == 0 && o.MaxRetryDelay != 0) || (o.RetryDelay != 0 && o.MaxRetryDelay == 0) {
|
||||
panic("Both RetryDelay and MaxRetryDelay must be 0 or neither can be 0")
|
||||
}
|
||||
|
||||
IfDefault := func(current *time.Duration, desired time.Duration) {
|
||||
if *current == time.Duration(0) {
|
||||
*current = desired
|
||||
}
|
||||
}
|
||||
|
||||
// Set defaults if unspecified
|
||||
if o.MaxTries == 0 {
|
||||
o.MaxTries = 4
|
||||
}
|
||||
switch o.Policy {
|
||||
case RetryPolicyExponential:
|
||||
IfDefault(&o.TryTimeout, 1*time.Minute)
|
||||
IfDefault(&o.RetryDelay, 4*time.Second)
|
||||
IfDefault(&o.MaxRetryDelay, 120*time.Second)
|
||||
|
||||
case RetryPolicyFixed:
|
||||
IfDefault(&o.TryTimeout, 1*time.Minute)
|
||||
IfDefault(&o.RetryDelay, 30*time.Second)
|
||||
IfDefault(&o.MaxRetryDelay, 120*time.Second)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o RetryOptions) calcDelay(try int32) time.Duration { // try is >=1; never 0
|
||||
pow := func(number int64, exponent int32) int64 { // pow is nested helper function
|
||||
var result int64 = 1
|
||||
for n := int32(0); n < exponent; n++ {
|
||||
result *= number
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
delay := time.Duration(0)
|
||||
switch o.Policy {
|
||||
case RetryPolicyExponential:
|
||||
delay = time.Duration(pow(2, try-1)-1) * o.RetryDelay
|
||||
|
||||
case RetryPolicyFixed:
|
||||
if try > 1 { // Any try after the 1st uses the fixed delay
|
||||
delay = o.RetryDelay
|
||||
}
|
||||
}
|
||||
|
||||
// Introduce some jitter: [0.0, 1.0) / 2 = [0.0, 0.5) + 0.8 = [0.8, 1.3)
|
||||
delay *= time.Duration(rand.Float32()/2 + 0.8) // NOTE: We want math/rand; not crypto/rand
|
||||
if delay > o.MaxRetryDelay {
|
||||
delay = o.MaxRetryDelay
|
||||
}
|
||||
return delay
|
||||
}
|
||||
|
||||
// NewRetryPolicyFactory creates a RetryPolicyFactory object configured using the specified options.
|
||||
func NewRetryPolicyFactory(o RetryOptions) pipeline.Factory {
|
||||
o = o.defaults() // Force defaults to be calculated
|
||||
return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc {
|
||||
return func(ctx context.Context, request pipeline.Request) (response pipeline.Response, err error) {
|
||||
// Before each try, we'll select either the primary or secondary URL.
|
||||
primaryTry := int32(0) // This indicates how many tries we've attempted against the primary DC
|
||||
|
||||
// We only consider retrying against a secondary if we have a read request (GET/HEAD) AND this policy has a Secondary URL it can use
|
||||
considerSecondary := (request.Method == http.MethodGet || request.Method == http.MethodHead) && o.RetryReadsFromSecondaryHost != ""
|
||||
|
||||
// Exponential retry algorithm: ((2 ^ attempt) - 1) * delay * random(0.8, 1.2)
|
||||
// When to retry: connection failure or an HTTP status code of 500 or greater, except 501 and 505
|
||||
// If using a secondary:
|
||||
// Even tries go against primary; odd tries go against the secondary
|
||||
// For a primary wait ((2 ^ primaryTries - 1) * delay * random(0.8, 1.2)
|
||||
// If secondary gets a 404, don't fail, retry but future retries are only against the primary
|
||||
// When retrying against a secondary, ignore the retry count and wait (.1 second * random(0.8, 1.2))
|
||||
for try := int32(1); try <= o.MaxTries; try++ {
|
||||
logf("\n=====> Try=%d\n", try)
|
||||
|
||||
// Determine which endpoint to try. It's primary if there is no secondary or if it is an add # attempt.
|
||||
tryingPrimary := !considerSecondary || (try%2 == 1)
|
||||
// Select the correct host and delay
|
||||
if tryingPrimary {
|
||||
primaryTry++
|
||||
delay := o.calcDelay(primaryTry)
|
||||
logf("Primary try=%d, Delay=%v\n", primaryTry, delay)
|
||||
time.Sleep(delay) // The 1st try returns 0 delay
|
||||
} else {
|
||||
delay := time.Second * time.Duration(rand.Float32()/2+0.8)
|
||||
logf("Secondary try=%d, Delay=%v\n", try-primaryTry, delay)
|
||||
time.Sleep(delay) // Delay with some jitter before trying secondary
|
||||
}
|
||||
|
||||
// Clone the original request to ensure that each try starts with the original (unmutated) request.
|
||||
requestCopy := request.Copy()
|
||||
|
||||
// For each try, seek to the beginning of the Body stream. We do this even for the 1st try because
|
||||
// the stream may not be at offset 0 when we first get it and we want the same behavior for the
|
||||
// 1st try as for additional tries.
|
||||
if err = requestCopy.RewindBody(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !tryingPrimary {
|
||||
requestCopy.Request.URL.Host = o.RetryReadsFromSecondaryHost
|
||||
}
|
||||
|
||||
// Set the server-side timeout query parameter "timeout=[seconds]"
|
||||
timeout := int32(o.TryTimeout.Seconds()) // Max seconds per try
|
||||
if deadline, ok := ctx.Deadline(); ok { // If user's ctx has a deadline, make the timeout the smaller of the two
|
||||
t := int32(deadline.Sub(time.Now()).Seconds()) // Duration from now until user's ctx reaches its deadline
|
||||
logf("MaxTryTimeout=%d secs, TimeTilDeadline=%d sec\n", timeout, t)
|
||||
if t < timeout {
|
||||
timeout = t
|
||||
}
|
||||
if timeout < 0 {
|
||||
timeout = 0 // If timeout ever goes negative, set it to zero; this happen while debugging
|
||||
}
|
||||
logf("TryTimeout adjusted to=%d sec\n", timeout)
|
||||
}
|
||||
q := requestCopy.Request.URL.Query()
|
||||
q.Set("timeout", strconv.Itoa(int(timeout+1))) // Add 1 to "round up"
|
||||
requestCopy.Request.URL.RawQuery = q.Encode()
|
||||
logf("Url=%s\n", requestCopy.Request.URL.String())
|
||||
|
||||
// Set the time for this particular retry operation and then Do the operation.
|
||||
tryCtx, tryCancel := context.WithTimeout(ctx, time.Second*time.Duration(timeout))
|
||||
//requestCopy.Body = &deadlineExceededReadCloser{r: requestCopy.Request.Body}
|
||||
response, err = next.Do(tryCtx, requestCopy) // Make the request
|
||||
/*err = improveDeadlineExceeded(err)
|
||||
if err == nil {
|
||||
response.Response().Body = &deadlineExceededReadCloser{r: response.Response().Body}
|
||||
}*/
|
||||
logf("Err=%v, response=%v\n", err, response)
|
||||
|
||||
action := "" // This MUST get changed within the switch code below
|
||||
switch {
|
||||
case ctx.Err() != nil:
|
||||
action = "NoRetry: Op timeout"
|
||||
case !tryingPrimary && response != nil && response.Response().StatusCode == http.StatusNotFound:
|
||||
// If attempt was against the secondary & it returned a StatusNotFound (404), then
|
||||
// the resource was not found. This may be due to replication delay. So, in this
|
||||
// case, we'll never try the secondary again for this operation.
|
||||
considerSecondary = false
|
||||
action = "Retry: Secondary URL returned 404"
|
||||
case err != nil:
|
||||
// NOTE: Protocol Responder returns non-nil if REST API returns invalid status code for the invoked operation
|
||||
if nerr, ok := err.(net.Error); ok && (nerr.Temporary() || nerr.Timeout()) {
|
||||
action = "Retry: net.Error and Temporary() or Timeout()"
|
||||
} else {
|
||||
action = "NoRetry: unrecognized error"
|
||||
}
|
||||
default:
|
||||
action = "NoRetry: successful HTTP request" // no error
|
||||
}
|
||||
|
||||
logf("Action=%s\n", action)
|
||||
// fmt.Println(action + "\n") // This is where we could log the retry operation; action is why we're retrying
|
||||
if action[0] != 'R' { // Retry only if action starts with 'R'
|
||||
if err != nil {
|
||||
tryCancel() // If we're returning an error, cancel this current/last per-retry timeout context
|
||||
} else {
|
||||
// TODO: Right now, we've decided to leak the per-try Context until the user's Context is canceled.
|
||||
// Another option is that we wrap the last per-try context in a body and overwrite the Response's Body field with our wrapper.
|
||||
// So, when the user closes the Body, the our per-try context gets closed too.
|
||||
// Another option, is that the Last Policy do this wrapping for a per-retry context (not for the user's context)
|
||||
_ = tryCancel // So, for now, we don't call cancel: cancel()
|
||||
}
|
||||
break // Don't retry
|
||||
}
|
||||
// If retrying, cancel the current per-try timeout context
|
||||
tryCancel()
|
||||
}
|
||||
return response, err // Not retryable or too many retries; return the last response/error
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// According to https://github.com/golang/go/wiki/CompilerOptimizations, the compiler will inline this method and hopefully optimize all calls to it away
|
||||
var logf = func(format string, a ...interface{}) {}
|
||||
|
||||
// Use this version to see the retry method's code path (import "fmt")
|
||||
//var logf = fmt.Printf
|
||||
|
||||
/*
|
||||
type deadlineExceededReadCloser struct {
|
||||
r io.ReadCloser
|
||||
}
|
||||
|
||||
func (r *deadlineExceededReadCloser) Read(p []byte) (int, error) {
|
||||
n, err := 0, io.EOF
|
||||
if r.r != nil {
|
||||
n, err = r.r.Read(p)
|
||||
}
|
||||
return n, improveDeadlineExceeded(err)
|
||||
}
|
||||
func (r *deadlineExceededReadCloser) Seek(offset int64, whence int) (int64, error) {
|
||||
// For an HTTP request, the ReadCloser MUST also implement seek
|
||||
// For an HTTP Repsonse, Seek MUST not be called (or this will panic)
|
||||
o, err := r.r.(io.Seeker).Seek(offset, whence)
|
||||
return o, improveDeadlineExceeded(err)
|
||||
}
|
||||
func (r *deadlineExceededReadCloser) Close() error {
|
||||
if c, ok := r.r.(io.Closer); ok {
|
||||
c.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// timeoutError is the internal struct that implements our richer timeout error.
|
||||
type deadlineExceeded struct {
|
||||
responseError
|
||||
}
|
||||
|
||||
var _ net.Error = (*deadlineExceeded)(nil) // Ensure deadlineExceeded implements the net.Error interface at compile time
|
||||
|
||||
// improveDeadlineExceeded creates a timeoutError object that implements the error interface IF cause is a context.DeadlineExceeded error.
|
||||
func improveDeadlineExceeded(cause error) error {
|
||||
// If cause is not DeadlineExceeded, return the same error passed in.
|
||||
if cause != context.DeadlineExceeded {
|
||||
return cause
|
||||
}
|
||||
// Else, convert DeadlineExceeded to our timeoutError which gives a richer string message
|
||||
return &deadlineExceeded{
|
||||
responseError: responseError{
|
||||
ErrorNode: pipeline.ErrorNode{}.Initialize(cause, 3),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Error implements the error interface's Error method to return a string representation of the error.
|
||||
func (e *deadlineExceeded) Error() string {
|
||||
return e.ErrorNode.Error("context deadline exceeded; when creating a pipeline, consider increasing RetryOptions' TryTimeout field")
|
||||
}
|
||||
*/
|
51
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/policy_telemetry.go
generated
vendored
51
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/policy_telemetry.go
generated
vendored
|
@ -1,51 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// TelemetryOptions configures the telemetry policy's behavior.
|
||||
type TelemetryOptions struct {
|
||||
// Value is a string prepended to each request's User-Agent and sent to the service.
|
||||
// The service records the user-agent in logs for diagnostics and tracking of client requests.
|
||||
Value string
|
||||
}
|
||||
|
||||
// NewTelemetryPolicyFactory creates a factory that can create telemetry policy objects
|
||||
// which add telemetry information to outgoing HTTP requests.
|
||||
func NewTelemetryPolicyFactory(o TelemetryOptions) pipeline.Factory {
|
||||
b := &bytes.Buffer{}
|
||||
b.WriteString(o.Value)
|
||||
if b.Len() > 0 {
|
||||
b.WriteRune(' ')
|
||||
}
|
||||
fmt.Fprintf(b, "Azure-Storage/%s %s", serviceLibVersion, platformInfo)
|
||||
telemetryValue := b.String()
|
||||
|
||||
return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc {
|
||||
return func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
|
||||
request.Header.Set("User-Agent", telemetryValue)
|
||||
return next.Do(ctx, request)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// NOTE: the ONLY function that should write to this variable is this func
|
||||
var platformInfo = func() string {
|
||||
// Azure-Storage/version (runtime; os type and version)”
|
||||
// Azure-Storage/1.4.0 (NODE-VERSION v4.5.0; Windows_NT 10.0.14393)'
|
||||
operatingSystem := runtime.GOOS // Default OS string
|
||||
switch operatingSystem {
|
||||
case "windows":
|
||||
operatingSystem = os.Getenv("OS") // Get more specific OS information
|
||||
case "linux": // accept default OS info
|
||||
case "freebsd": // accept default OS info
|
||||
}
|
||||
return fmt.Sprintf("(%s; %s)", runtime.Version(), operatingSystem)
|
||||
}()
|
|
@ -1,25 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// NewUniqueRequestIDPolicyFactory creates a UniqueRequestIDPolicyFactory object
|
||||
// that sets the request's x-ms-client-request-id header if it doesn't already exist.
|
||||
func NewUniqueRequestIDPolicyFactory() pipeline.Factory {
|
||||
return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc {
|
||||
// This is Policy's Do method:
|
||||
return func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
|
||||
id := request.Header.Get(xMsClientRequestID)
|
||||
if id == "" { // Add a unique request ID if the caller didn't specify one already
|
||||
request.Header.Set(xMsClientRequestID, newUUID().String())
|
||||
}
|
||||
return next.Do(ctx, request)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const xMsClientRequestID = "x-ms-client-request-id"
|
||||
|
217
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/sas_account.go
generated
vendored
217
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/sas_account.go
generated
vendored
|
@ -1,217 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AccountSASSignatureValues is used to generate a Shared Access Signature (SAS) for an Azure Storage account.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/constructing-an-account-sas
|
||||
type AccountSASSignatureValues struct {
|
||||
Version string `param:"sv"` // If not specified, this defaults to SASVersion
|
||||
Protocol SASProtocol `param:"spr"` // See the SASProtocol* constants
|
||||
StartTime time.Time `param:"st"` // Not specified if IsZero
|
||||
ExpiryTime time.Time `param:"se"` // Not specified if IsZero
|
||||
Permissions string `param:"sp"` // Create by initializing a AccountSASPermissions and then call String()
|
||||
IPRange IPRange `param:"sip"`
|
||||
Services string `param:"ss"` // Create by initializing AccountSASServices and then call String()
|
||||
ResourceTypes string `param:"srt"` // Create by initializing AccountSASResourceTypes and then call String()
|
||||
}
|
||||
|
||||
// NewSASQueryParameters uses an account's shared key credential to sign this signature values to produce
|
||||
// the proper SAS query parameters.
|
||||
func (v AccountSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *SharedKeyCredential) SASQueryParameters {
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/Constructing-an-Account-SAS
|
||||
if v.ExpiryTime.IsZero() || v.Permissions == "" || v.ResourceTypes == "" || v.Services == "" {
|
||||
panic("Account SAS is missing at least one of these: ExpiryTime, Permissions, Service, or ResourceType")
|
||||
}
|
||||
if v.Version == "" {
|
||||
v.Version = SASVersion
|
||||
}
|
||||
perms := &AccountSASPermissions{}
|
||||
if err := perms.Parse(v.Permissions); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
v.Permissions = perms.String()
|
||||
|
||||
startTime, expiryTime := FormatTimesForSASSigning(v.StartTime, v.ExpiryTime)
|
||||
|
||||
stringToSign := strings.Join([]string{
|
||||
sharedKeyCredential.AccountName(),
|
||||
v.Permissions,
|
||||
v.Services,
|
||||
v.ResourceTypes,
|
||||
startTime,
|
||||
expiryTime,
|
||||
v.IPRange.String(),
|
||||
string(v.Protocol),
|
||||
v.Version,
|
||||
""}, // That right, the account SAS requires a terminating extra newline
|
||||
"\n")
|
||||
|
||||
signature := sharedKeyCredential.ComputeHMACSHA256(stringToSign)
|
||||
p := SASQueryParameters{
|
||||
// Common SAS parameters
|
||||
version: v.Version,
|
||||
protocol: v.Protocol,
|
||||
startTime: v.StartTime,
|
||||
expiryTime: v.ExpiryTime,
|
||||
permissions: v.Permissions,
|
||||
ipRange: v.IPRange,
|
||||
|
||||
// Account-specific SAS parameters
|
||||
services: v.Services,
|
||||
resourceTypes: v.ResourceTypes,
|
||||
|
||||
// Calculated SAS signature
|
||||
signature: signature,
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// The AccountSASPermissions type simplifies creating the permissions string for an Azure Storage Account SAS.
|
||||
// Initialize an instance of this type and then call its String method to set AccountSASSignatureValues's Permissions field.
|
||||
type AccountSASPermissions struct {
|
||||
Read, Write, Delete, List, Add, Create, Update, Process bool
|
||||
}
|
||||
|
||||
// String produces the SAS permissions string for an Azure Storage account.
|
||||
// Call this method to set AccountSASSignatureValues's Permissions field.
|
||||
func (p AccountSASPermissions) String() string {
|
||||
var buffer bytes.Buffer
|
||||
if p.Read {
|
||||
buffer.WriteRune('r')
|
||||
}
|
||||
if p.Write {
|
||||
buffer.WriteRune('w')
|
||||
}
|
||||
if p.Delete {
|
||||
buffer.WriteRune('d')
|
||||
}
|
||||
if p.List {
|
||||
buffer.WriteRune('l')
|
||||
}
|
||||
if p.Add {
|
||||
buffer.WriteRune('a')
|
||||
}
|
||||
if p.Create {
|
||||
buffer.WriteRune('c')
|
||||
}
|
||||
if p.Update {
|
||||
buffer.WriteRune('u')
|
||||
}
|
||||
if p.Process {
|
||||
buffer.WriteRune('p')
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// Parse initializes the AccountSASPermissions's fields from a string.
|
||||
func (p *AccountSASPermissions) Parse(s string) error {
|
||||
*p = AccountSASPermissions{} // Clear out the flags
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 'r':
|
||||
p.Read = true
|
||||
case 'w':
|
||||
p.Write = true
|
||||
case 'd':
|
||||
p.Delete = true
|
||||
case 'l':
|
||||
p.List = true
|
||||
case 'a':
|
||||
p.Add = true
|
||||
case 'c':
|
||||
p.Create = true
|
||||
case 'u':
|
||||
p.Update = true
|
||||
case 'p':
|
||||
p.Process = true
|
||||
default:
|
||||
return fmt.Errorf("Invalid permission character: '%v'", r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// The AccountSASServices type simplifies creating the services string for an Azure Storage Account SAS.
|
||||
// Initialize an instance of this type and then call its String method to set AccountSASSignatureValues's Services field.
|
||||
type AccountSASServices struct {
|
||||
Blob, Queue, File bool
|
||||
}
|
||||
|
||||
// String produces the SAS services string for an Azure Storage account.
|
||||
// Call this method to set AccountSASSignatureValues's Services field.
|
||||
func (s AccountSASServices) String() string {
|
||||
var buffer bytes.Buffer
|
||||
if s.Blob {
|
||||
buffer.WriteRune('b')
|
||||
}
|
||||
if s.Queue {
|
||||
buffer.WriteRune('q')
|
||||
}
|
||||
if s.File {
|
||||
buffer.WriteRune('f')
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// Parse initializes the AccountSASServices' fields from a string.
|
||||
func (a *AccountSASServices) Parse(s string) error {
|
||||
*a = AccountSASServices{} // Clear out the flags
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 'b':
|
||||
a.Blob = true
|
||||
case 'q':
|
||||
a.Queue = true
|
||||
case 'f':
|
||||
a.File = true
|
||||
default:
|
||||
return fmt.Errorf("Invalid service character: '%v'", r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// The AccountSASResourceTypes type simplifies creating the resource types string for an Azure Storage Account SAS.
|
||||
// Initialize an instance of this type and then call its String method to set AccountSASSignatureValues's ResourceTypes field.
|
||||
type AccountSASResourceTypes struct {
|
||||
Service, Container, Object bool
|
||||
}
|
||||
|
||||
// String produces the SAS resource types string for an Azure Storage account.
|
||||
// Call this method to set AccountSASSignatureValues's ResourceTypes field.
|
||||
func (rt AccountSASResourceTypes) String() string {
|
||||
var buffer bytes.Buffer
|
||||
if rt.Service {
|
||||
buffer.WriteRune('s')
|
||||
}
|
||||
if rt.Container {
|
||||
buffer.WriteRune('c')
|
||||
}
|
||||
if rt.Object {
|
||||
buffer.WriteRune('o')
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// Parse initializes the AccountSASResourceType's fields from a string.
|
||||
func (rt *AccountSASResourceTypes) Parse(s string) error {
|
||||
*rt = AccountSASResourceTypes{} // Clear out the flags
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 's':
|
||||
rt.Service = true
|
||||
case 'q':
|
||||
rt.Container = true
|
||||
case 'o':
|
||||
rt.Object = true
|
||||
default:
|
||||
return fmt.Errorf("Invalid resource type: '%v'", r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
211
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/sas_query_params.go
generated
vendored
211
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/sas_query_params.go
generated
vendored
|
@ -1,211 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SASVersion indicates the SAS version.
|
||||
const SASVersion = "2015-04-05"
|
||||
|
||||
type SASProtocol string
|
||||
|
||||
const (
|
||||
// SASProtocolHTTPS can be specified for a SAS protocol
|
||||
SASProtocolHTTPS SASProtocol = "https"
|
||||
|
||||
// SASProtocolHTTPSandHTTP can be specified for a SAS protocol
|
||||
SASProtocolHTTPSandHTTP SASProtocol = "https,http"
|
||||
)
|
||||
|
||||
// FormatTimesForSASSigning converts a time.Time to a snapshotTimeFormat string suitable for a
|
||||
// SASField's StartTime or ExpiryTime fields. Returns "" if value.IsZero().
|
||||
func FormatTimesForSASSigning(startTime, expiryTime time.Time) (string, string) {
|
||||
ss := ""
|
||||
if !startTime.IsZero() {
|
||||
ss = startTime.Format(SASTimeFormat) // "yyyy-MM-ddTHH:mm:ssZ"
|
||||
}
|
||||
se := ""
|
||||
if !expiryTime.IsZero() {
|
||||
se = expiryTime.Format(SASTimeFormat) // "yyyy-MM-ddTHH:mm:ssZ"
|
||||
}
|
||||
return ss, se
|
||||
}
|
||||
|
||||
// SASTimeFormat represents the format of a SAS start or expiry time. Use it when formatting/parsing a time.Time.
|
||||
const SASTimeFormat = "2006-01-02T15:04:05Z" //"2017-07-27T00:00:00Z" // ISO 8601
|
||||
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
|
||||
// A SASQueryParameters object represents the components that make up an Azure Storage SAS' query parameters.
|
||||
// You parse a map of query parameters into its fields by calling NewSASQueryParameters(). You add the components
|
||||
// to a query parameter map by calling AddToValues().
|
||||
// NOTE: Changing any field requires computing a new SAS signature using a XxxSASSignatureValues type.
|
||||
//
|
||||
// This type defines the components used by all Azure Storage resources (Containers, Blobs, Files, & Queues).
|
||||
type SASQueryParameters struct {
|
||||
// All members are immutable or values so copies of this struct are goroutine-safe.
|
||||
version string `param:"sv"`
|
||||
services string `param:"ss"`
|
||||
resourceTypes string `param:"srt"`
|
||||
protocol SASProtocol `param:"spr"`
|
||||
startTime time.Time `param:"st"`
|
||||
expiryTime time.Time `param:"se"`
|
||||
ipRange IPRange `param:"sip"`
|
||||
identifier string `param:"si"`
|
||||
resource string `param:"sr"`
|
||||
permissions string `param:"sp"`
|
||||
signature string `param:"sig"`
|
||||
}
|
||||
|
||||
func (p *SASQueryParameters) Version() string {
|
||||
return p.version
|
||||
}
|
||||
|
||||
func (p *SASQueryParameters) Services() string {
|
||||
return p.services
|
||||
}
|
||||
func (p *SASQueryParameters) ResourceTypes() string {
|
||||
return p.resourceTypes
|
||||
}
|
||||
func (p *SASQueryParameters) Protocol() SASProtocol {
|
||||
return p.protocol
|
||||
}
|
||||
func (p *SASQueryParameters) StartTime() time.Time {
|
||||
return p.startTime
|
||||
}
|
||||
func (p *SASQueryParameters) ExpiryTime() time.Time {
|
||||
return p.expiryTime
|
||||
}
|
||||
|
||||
func (p *SASQueryParameters) IPRange() IPRange {
|
||||
return p.ipRange
|
||||
}
|
||||
|
||||
func (p *SASQueryParameters) Identifier() string {
|
||||
return p.identifier
|
||||
}
|
||||
|
||||
func (p *SASQueryParameters) Resource() string {
|
||||
return p.resource
|
||||
}
|
||||
func (p *SASQueryParameters) Permissions() string {
|
||||
return p.permissions
|
||||
}
|
||||
|
||||
func (p *SASQueryParameters) Signature() string {
|
||||
return p.signature
|
||||
}
|
||||
|
||||
// IPRange represents a SAS IP range's start IP and (optionally) end IP.
|
||||
type IPRange struct {
|
||||
Start net.IP // Not specified if length = 0
|
||||
End net.IP // Not specified if length = 0
|
||||
}
|
||||
|
||||
// String returns a string representation of an IPRange.
|
||||
func (ipr *IPRange) String() string {
|
||||
if len(ipr.Start) == 0 {
|
||||
return ""
|
||||
}
|
||||
start := ipr.Start.String()
|
||||
if len(ipr.End) == 0 {
|
||||
return start
|
||||
}
|
||||
return start + "-" + ipr.End.String()
|
||||
}
|
||||
|
||||
// NewSASQueryParameters creates and initializes a SASQueryParameters object based on the
|
||||
// query parameter map's passed-in values. If deleteSASParametersFromValues is true,
|
||||
// all SAS-related query parameters are removed from the passed-in map. If
|
||||
// deleteSASParametersFromValues is false, the map passed-in map is unaltered.
|
||||
func newSASQueryParameters(values url.Values, deleteSASParametersFromValues bool) SASQueryParameters {
|
||||
p := SASQueryParameters{}
|
||||
for k, v := range values {
|
||||
val := v[0]
|
||||
isSASKey := true
|
||||
switch strings.ToLower(k) {
|
||||
case "sv":
|
||||
p.version = val
|
||||
case "ss":
|
||||
p.services = val
|
||||
case "srt":
|
||||
p.resourceTypes = val
|
||||
case "spr":
|
||||
p.protocol = SASProtocol(val)
|
||||
case "st":
|
||||
p.startTime, _ = time.Parse(SASTimeFormat, val)
|
||||
case "se":
|
||||
p.expiryTime, _ = time.Parse(SASTimeFormat, val)
|
||||
case "sip":
|
||||
dashIndex := strings.Index(val, "-")
|
||||
if dashIndex == -1 {
|
||||
p.ipRange.Start = net.ParseIP(val)
|
||||
} else {
|
||||
p.ipRange.Start = net.ParseIP(val[:dashIndex])
|
||||
p.ipRange.End = net.ParseIP(val[dashIndex+1:])
|
||||
}
|
||||
case "si":
|
||||
p.identifier = val
|
||||
case "sr":
|
||||
p.resource = val
|
||||
case "sp":
|
||||
p.permissions = val
|
||||
case "sig":
|
||||
p.signature = val
|
||||
default:
|
||||
isSASKey = false // We didn't recognize the query parameter
|
||||
}
|
||||
if isSASKey && deleteSASParametersFromValues {
|
||||
delete(values, k)
|
||||
}
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// AddToValues adds the SAS components to the specified query parameters map.
|
||||
func (p *SASQueryParameters) addToValues(v url.Values) url.Values {
|
||||
if p.version != "" {
|
||||
v.Add("sv", p.version)
|
||||
}
|
||||
if p.services != "" {
|
||||
v.Add("ss", p.services)
|
||||
}
|
||||
if p.resourceTypes != "" {
|
||||
v.Add("srt", p.resourceTypes)
|
||||
}
|
||||
if p.protocol != "" {
|
||||
v.Add("spr", string(p.protocol))
|
||||
}
|
||||
if !p.startTime.IsZero() {
|
||||
v.Add("st", p.startTime.Format(SASTimeFormat))
|
||||
}
|
||||
if !p.expiryTime.IsZero() {
|
||||
v.Add("se", p.expiryTime.Format(SASTimeFormat))
|
||||
}
|
||||
if len(p.ipRange.Start) > 0 {
|
||||
v.Add("sip", p.ipRange.String())
|
||||
}
|
||||
if p.identifier != "" {
|
||||
v.Add("si", p.identifier)
|
||||
}
|
||||
if p.resource != "" {
|
||||
v.Add("sr", p.resource)
|
||||
}
|
||||
if p.permissions != "" {
|
||||
v.Add("sp", p.permissions)
|
||||
}
|
||||
if p.signature != "" {
|
||||
v.Add("sig", p.signature)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Encode encodes the SAS query parameters into URL encoded form sorted by key.
|
||||
func (p *SASQueryParameters) Encode() string {
|
||||
v := url.Values{}
|
||||
p.addToValues(v)
|
||||
return v.Encode()
|
||||
}
|
206
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/sas_service.go
generated
vendored
206
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/sas_service.go
generated
vendored
|
@ -1,206 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BlobSASSignatureValues is used to generate a Shared Access Signature (SAS) for an Azure Storage container or blob.
|
||||
type BlobSASSignatureValues struct {
|
||||
Version string `param:"sv"` // If not specified, this defaults to SASVersion
|
||||
Protocol SASProtocol `param:"spr"` // See the SASProtocol* constants
|
||||
StartTime time.Time `param:"st"` // Not specified if IsZero
|
||||
ExpiryTime time.Time `param:"se"` // Not specified if IsZero
|
||||
Permissions string `param:"sp"` // Create by initializing a ContainerSASPermissions or BlobSASPermissions and then call String()
|
||||
IPRange IPRange `param:"sip"`
|
||||
Identifier string `param:"si"`
|
||||
ContainerName string
|
||||
BlobName string // Use "" to create a Container SAS
|
||||
CacheControl string // rscc
|
||||
ContentDisposition string // rscd
|
||||
ContentEncoding string // rsce
|
||||
ContentLanguage string // rscl
|
||||
ContentType string // rsct
|
||||
}
|
||||
|
||||
// NewSASQueryParameters uses an account's shared key credential to sign this signature values to produce
|
||||
// the proper SAS query parameters.
|
||||
func (v BlobSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *SharedKeyCredential) SASQueryParameters {
|
||||
if sharedKeyCredential == nil {
|
||||
panic("sharedKeyCredential can't be nil")
|
||||
}
|
||||
|
||||
resource := "c"
|
||||
if v.BlobName == "" {
|
||||
// Make sure the permission characters are in the correct order
|
||||
perms := &ContainerSASPermissions{}
|
||||
if err := perms.Parse(v.Permissions); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
v.Permissions = perms.String()
|
||||
} else {
|
||||
resource = "b"
|
||||
// Make sure the permission characters are in the correct order
|
||||
perms := &BlobSASPermissions{}
|
||||
if err := perms.Parse(v.Permissions); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
v.Permissions = perms.String()
|
||||
}
|
||||
if v.Version == "" {
|
||||
v.Version = SASVersion
|
||||
}
|
||||
startTime, expiryTime := FormatTimesForSASSigning(v.StartTime, v.ExpiryTime)
|
||||
|
||||
// String to sign: http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx
|
||||
stringToSign := strings.Join([]string{
|
||||
v.Permissions,
|
||||
startTime,
|
||||
expiryTime,
|
||||
getCanonicalName(sharedKeyCredential.AccountName(), v.ContainerName, v.BlobName),
|
||||
v.Identifier,
|
||||
v.IPRange.String(),
|
||||
string(v.Protocol),
|
||||
v.Version,
|
||||
v.CacheControl, // rscc
|
||||
v.ContentDisposition, // rscd
|
||||
v.ContentEncoding, // rsce
|
||||
v.ContentLanguage, // rscl
|
||||
v.ContentType}, // rsct
|
||||
"\n")
|
||||
signature := sharedKeyCredential.ComputeHMACSHA256(stringToSign)
|
||||
|
||||
p := SASQueryParameters{
|
||||
// Common SAS parameters
|
||||
version: v.Version,
|
||||
protocol: v.Protocol,
|
||||
startTime: v.StartTime,
|
||||
expiryTime: v.ExpiryTime,
|
||||
permissions: v.Permissions,
|
||||
ipRange: v.IPRange,
|
||||
|
||||
// Container/Blob-specific SAS parameters
|
||||
resource: resource,
|
||||
identifier: v.Identifier,
|
||||
|
||||
// Calculated SAS signature
|
||||
signature: signature,
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// getCanonicalName computes the canonical name for a container or blob resource for SAS signing.
|
||||
func getCanonicalName(account string, containerName string, blobName string) string {
|
||||
// Container: "/blob/account/containername"
|
||||
// Blob: "/blob/account/containername/blobname"
|
||||
elements := []string{"/blob/", account, "/", containerName}
|
||||
if blobName != "" {
|
||||
elements = append(elements, "/", strings.Replace(blobName, "\\", "/", -1))
|
||||
}
|
||||
return strings.Join(elements, "")
|
||||
}
|
||||
|
||||
// The ContainerSASPermissions type simplifies creating the permissions string for an Azure Storage container SAS.
|
||||
// Initialize an instance of this type and then call its String method to set BlobSASSignatureValues's Permissions field.
|
||||
type ContainerSASPermissions struct {
|
||||
Read, Add, Create, Write, Delete, List bool
|
||||
}
|
||||
|
||||
// String produces the SAS permissions string for an Azure Storage container.
|
||||
// Call this method to set BlobSASSignatureValues's Permissions field.
|
||||
func (p ContainerSASPermissions) String() string {
|
||||
var b bytes.Buffer
|
||||
if p.Read {
|
||||
b.WriteRune('r')
|
||||
}
|
||||
if p.Add {
|
||||
b.WriteRune('a')
|
||||
}
|
||||
if p.Create {
|
||||
b.WriteRune('c')
|
||||
}
|
||||
if p.Write {
|
||||
b.WriteRune('w')
|
||||
}
|
||||
if p.Delete {
|
||||
b.WriteRune('d')
|
||||
}
|
||||
if p.List {
|
||||
b.WriteRune('l')
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Parse initializes the ContainerSASPermissions's fields from a string.
|
||||
func (p *ContainerSASPermissions) Parse(s string) error {
|
||||
*p = ContainerSASPermissions{} // Clear the flags
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 'r':
|
||||
p.Read = true
|
||||
case 'a':
|
||||
p.Add = true
|
||||
case 'c':
|
||||
p.Create = true
|
||||
case 'w':
|
||||
p.Write = true
|
||||
case 'd':
|
||||
p.Delete = true
|
||||
case 'l':
|
||||
p.List = true
|
||||
default:
|
||||
return fmt.Errorf("Invalid permission: '%v'", r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// The BlobSASPermissions type simplifies creating the permissions string for an Azure Storage blob SAS.
|
||||
// Initialize an instance of this type and then call its String method to set BlobSASSignatureValues's Permissions field.
|
||||
type BlobSASPermissions struct{ Read, Add, Create, Write, Delete bool }
|
||||
|
||||
// String produces the SAS permissions string for an Azure Storage blob.
|
||||
// Call this method to set BlobSASSignatureValues's Permissions field.
|
||||
func (p BlobSASPermissions) String() string {
|
||||
var b bytes.Buffer
|
||||
if p.Read {
|
||||
b.WriteRune('r')
|
||||
}
|
||||
if p.Add {
|
||||
b.WriteRune('a')
|
||||
}
|
||||
if p.Create {
|
||||
b.WriteRune('c')
|
||||
}
|
||||
if p.Write {
|
||||
b.WriteRune('w')
|
||||
}
|
||||
if p.Delete {
|
||||
b.WriteRune('d')
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Parse initializes the BlobSASPermissions's fields from a string.
|
||||
func (p *BlobSASPermissions) Parse(s string) error {
|
||||
*p = BlobSASPermissions{} // Clear the flags
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 'r':
|
||||
p.Read = true
|
||||
case 'a':
|
||||
p.Add = true
|
||||
case 'c':
|
||||
p.Create = true
|
||||
case 'w':
|
||||
p.Write = true
|
||||
case 'd':
|
||||
p.Delete = true
|
||||
default:
|
||||
return fmt.Errorf("Invalid permission: '%v'", r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
195
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/service_codes_blob.go
generated
vendored
195
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/service_codes_blob.go
generated
vendored
|
@ -1,195 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/blob-service-error-codes
|
||||
|
||||
// ServiceCode values indicate a service failure.
|
||||
const (
|
||||
// ServiceCodeAppendPositionConditionNotMet means the append position condition specified was not met.
|
||||
ServiceCodeAppendPositionConditionNotMet ServiceCodeType = "AppendPositionConditionNotMet"
|
||||
|
||||
// ServiceCodeBlobAlreadyExists means the specified blob already exists.
|
||||
ServiceCodeBlobAlreadyExists ServiceCodeType = "BlobAlreadyExists"
|
||||
|
||||
// ServiceCodeBlobNotFound means the specified blob does not exist.
|
||||
ServiceCodeBlobNotFound ServiceCodeType = "BlobNotFound"
|
||||
|
||||
// ServiceCodeBlobOverwritten means the blob has been recreated since the previous snapshot was taken.
|
||||
ServiceCodeBlobOverwritten ServiceCodeType = "BlobOverwritten"
|
||||
|
||||
// ServiceCodeBlobTierInadequateForContentLength means the specified blob tier size limit cannot be less than content length.
|
||||
ServiceCodeBlobTierInadequateForContentLength ServiceCodeType = "BlobTierInadequateForContentLength"
|
||||
|
||||
// ServiceCodeBlockCountExceedsLimit means the committed block count cannot exceed the maximum limit of 50,000 blocks
|
||||
// or that the uncommitted block count cannot exceed the maximum limit of 100,000 blocks.
|
||||
ServiceCodeBlockCountExceedsLimit ServiceCodeType = "BlockCountExceedsLimit"
|
||||
|
||||
// ServiceCodeBlockListTooLong means the block list may not contain more than 50,000 blocks.
|
||||
ServiceCodeBlockListTooLong ServiceCodeType = "BlockListTooLong"
|
||||
|
||||
// ServiceCodeCannotChangeToLowerTier means that a higher blob tier has already been explicitly set.
|
||||
ServiceCodeCannotChangeToLowerTier ServiceCodeType = "CannotChangeToLowerTier"
|
||||
|
||||
// ServiceCodeCannotVerifyCopySource means that the service could not verify the copy source within the specified time.
|
||||
// Examine the HTTP status code and message for more information about the failure.
|
||||
ServiceCodeCannotVerifyCopySource ServiceCodeType = "CannotVerifyCopySource"
|
||||
|
||||
// ServiceCodeContainerAlreadyExists means the specified container already exists.
|
||||
ServiceCodeContainerAlreadyExists ServiceCodeType = "ContainerAlreadyExists"
|
||||
|
||||
// ServiceCodeContainerBeingDeleted means the specified container is being deleted.
|
||||
ServiceCodeContainerBeingDeleted ServiceCodeType = "ContainerBeingDeleted"
|
||||
|
||||
// ServiceCodeContainerDisabled means the specified container has been disabled by the administrator.
|
||||
ServiceCodeContainerDisabled ServiceCodeType = "ContainerDisabled"
|
||||
|
||||
// ServiceCodeContainerNotFound means the specified container does not exist.
|
||||
ServiceCodeContainerNotFound ServiceCodeType = "ContainerNotFound"
|
||||
|
||||
// ServiceCodeContentLengthLargerThanTierLimit means the blob's content length cannot exceed its tier limit.
|
||||
ServiceCodeContentLengthLargerThanTierLimit ServiceCodeType = "ContentLengthLargerThanTierLimit"
|
||||
|
||||
// ServiceCodeCopyAcrossAccountsNotSupported means the copy source account and destination account must be the same.
|
||||
ServiceCodeCopyAcrossAccountsNotSupported ServiceCodeType = "CopyAcrossAccountsNotSupported"
|
||||
|
||||
// ServiceCodeCopyIDMismatch means the specified copy ID did not match the copy ID for the pending copy operation.
|
||||
ServiceCodeCopyIDMismatch ServiceCodeType = "CopyIdMismatch"
|
||||
|
||||
// ServiceCodeFeatureVersionMismatch means the type of blob in the container is unrecognized by this version or
|
||||
// that the operation for AppendBlob requires at least version 2015-02-21.
|
||||
ServiceCodeFeatureVersionMismatch ServiceCodeType = "FeatureVersionMismatch"
|
||||
|
||||
// ServiceCodeIncrementalCopyBlobMismatch means the specified source blob is different than the copy source of the existing incremental copy blob.
|
||||
ServiceCodeIncrementalCopyBlobMismatch ServiceCodeType = "IncrementalCopyBlobMismatch"
|
||||
|
||||
// ServiceCodeIncrementalCopyOfEralierVersionSnapshotNotAllowed means the specified snapshot is earlier than the last snapshot copied into the incremental copy blob.
|
||||
ServiceCodeIncrementalCopyOfEralierVersionSnapshotNotAllowed ServiceCodeType = "IncrementalCopyOfEralierVersionSnapshotNotAllowed"
|
||||
|
||||
// ServiceCodeIncrementalCopySourceMustBeSnapshot means the source for incremental copy request must be a snapshot.
|
||||
ServiceCodeIncrementalCopySourceMustBeSnapshot ServiceCodeType = "IncrementalCopySourceMustBeSnapshot"
|
||||
|
||||
// ServiceCodeInfiniteLeaseDurationRequired means the lease ID matched, but the specified lease must be an infinite-duration lease.
|
||||
ServiceCodeInfiniteLeaseDurationRequired ServiceCodeType = "InfiniteLeaseDurationRequired"
|
||||
|
||||
// ServiceCodeInvalidBlobOrBlock means the specified blob or block content is invalid.
|
||||
ServiceCodeInvalidBlobOrBlock ServiceCodeType = "InvalidBlobOrBlock"
|
||||
|
||||
// ServiceCodeInvalidBlobType means the blob type is invalid for this operation.
|
||||
ServiceCodeInvalidBlobType ServiceCodeType = "InvalidBlobType"
|
||||
|
||||
// ServiceCodeInvalidBlockID means the specified block ID is invalid. The block ID must be Base64-encoded.
|
||||
ServiceCodeInvalidBlockID ServiceCodeType = "InvalidBlockId"
|
||||
|
||||
// ServiceCodeInvalidBlockList means the specified block list is invalid.
|
||||
ServiceCodeInvalidBlockList ServiceCodeType = "InvalidBlockList"
|
||||
|
||||
// ServiceCodeInvalidOperation means an invalid operation against a blob snapshot.
|
||||
ServiceCodeInvalidOperation ServiceCodeType = "InvalidOperation"
|
||||
|
||||
// ServiceCodeInvalidPageRange means the page range specified is invalid.
|
||||
ServiceCodeInvalidPageRange ServiceCodeType = "InvalidPageRange"
|
||||
|
||||
// ServiceCodeInvalidSourceBlobType means the copy source blob type is invalid for this operation.
|
||||
ServiceCodeInvalidSourceBlobType ServiceCodeType = "InvalidSourceBlobType"
|
||||
|
||||
// ServiceCodeInvalidSourceBlobURL means the source URL for incremental copy request must be valid Azure Storage blob URL.
|
||||
ServiceCodeInvalidSourceBlobURL ServiceCodeType = "InvalidSourceBlobUrl"
|
||||
|
||||
// ServiceCodeInvalidVersionForPageBlobOperation means that all operations on page blobs require at least version 2009-09-19.
|
||||
ServiceCodeInvalidVersionForPageBlobOperation ServiceCodeType = "InvalidVersionForPageBlobOperation"
|
||||
|
||||
// ServiceCodeLeaseAlreadyPresent means there is already a lease present.
|
||||
ServiceCodeLeaseAlreadyPresent ServiceCodeType = "LeaseAlreadyPresent"
|
||||
|
||||
// ServiceCodeLeaseAlreadyBroken means the lease has already been broken and cannot be broken again.
|
||||
ServiceCodeLeaseAlreadyBroken ServiceCodeType = "LeaseAlreadyBroken"
|
||||
|
||||
// ServiceCodeLeaseIDMismatchWithBlobOperation means the lease ID specified did not match the lease ID for the blob.
|
||||
ServiceCodeLeaseIDMismatchWithBlobOperation ServiceCodeType = "LeaseIdMismatchWithBlobOperation"
|
||||
|
||||
// ServiceCodeLeaseIDMismatchWithContainerOperation means the lease ID specified did not match the lease ID for the container.
|
||||
ServiceCodeLeaseIDMismatchWithContainerOperation ServiceCodeType = "LeaseIdMismatchWithContainerOperation"
|
||||
|
||||
// ServiceCodeLeaseIDMismatchWithLeaseOperation means the lease ID specified did not match the lease ID for the blob/container.
|
||||
ServiceCodeLeaseIDMismatchWithLeaseOperation ServiceCodeType = "LeaseIdMismatchWithLeaseOperation"
|
||||
|
||||
// ServiceCodeLeaseIDMissing means there is currently a lease on the blob/container and no lease ID was specified in the request.
|
||||
ServiceCodeLeaseIDMissing ServiceCodeType = "LeaseIdMissing"
|
||||
|
||||
// ServiceCodeLeaseIsBreakingAndCannotBeAcquired means the lease ID matched, but the lease is currently in breaking state and cannot be acquired until it is broken.
|
||||
ServiceCodeLeaseIsBreakingAndCannotBeAcquired ServiceCodeType = "LeaseIsBreakingAndCannotBeAcquired"
|
||||
|
||||
// ServiceCodeLeaseIsBreakingAndCannotBeChanged means the lease ID matched, but the lease is currently in breaking state and cannot be changed.
|
||||
ServiceCodeLeaseIsBreakingAndCannotBeChanged ServiceCodeType = "LeaseIsBreakingAndCannotBeChanged"
|
||||
|
||||
// ServiceCodeLeaseIsBrokenAndCannotBeRenewed means the lease ID matched, but the lease has been broken explicitly and cannot be renewed.
|
||||
ServiceCodeLeaseIsBrokenAndCannotBeRenewed ServiceCodeType = "LeaseIsBrokenAndCannotBeRenewed"
|
||||
|
||||
// ServiceCodeLeaseLost means a lease ID was specified, but the lease for the blob/container has expired.
|
||||
ServiceCodeLeaseLost ServiceCodeType = "LeaseLost"
|
||||
|
||||
// ServiceCodeLeaseNotPresentWithBlobOperation means there is currently no lease on the blob.
|
||||
ServiceCodeLeaseNotPresentWithBlobOperation ServiceCodeType = "LeaseNotPresentWithBlobOperation"
|
||||
|
||||
// ServiceCodeLeaseNotPresentWithContainerOperation means there is currently no lease on the container.
|
||||
ServiceCodeLeaseNotPresentWithContainerOperation ServiceCodeType = "LeaseNotPresentWithContainerOperation"
|
||||
|
||||
// ServiceCodeLeaseNotPresentWithLeaseOperation means there is currently no lease on the blob/container.
|
||||
ServiceCodeLeaseNotPresentWithLeaseOperation ServiceCodeType = "LeaseNotPresentWithLeaseOperation"
|
||||
|
||||
// ServiceCodeMaxBlobSizeConditionNotMet means the max blob size condition specified was not met.
|
||||
ServiceCodeMaxBlobSizeConditionNotMet ServiceCodeType = "MaxBlobSizeConditionNotMet"
|
||||
|
||||
// ServiceCodeNoPendingCopyOperation means there is currently no pending copy operation.
|
||||
ServiceCodeNoPendingCopyOperation ServiceCodeType = "NoPendingCopyOperation"
|
||||
|
||||
// ServiceCodeOperationNotAllowedOnIncrementalCopyBlob means the specified operation is not allowed on an incremental copy blob.
|
||||
ServiceCodeOperationNotAllowedOnIncrementalCopyBlob ServiceCodeType = "OperationNotAllowedOnIncrementalCopyBlob"
|
||||
|
||||
// ServiceCodePendingCopyOperation means there is currently a pending copy operation.
|
||||
ServiceCodePendingCopyOperation ServiceCodeType = "PendingCopyOperation"
|
||||
|
||||
// ServiceCodePreviousSnapshotCannotBeNewer means the prevsnapshot query parameter value cannot be newer than snapshot query parameter value.
|
||||
ServiceCodePreviousSnapshotCannotBeNewer ServiceCodeType = "PreviousSnapshotCannotBeNewer"
|
||||
|
||||
// ServiceCodePreviousSnapshotNotFound means the previous snapshot is not found.
|
||||
ServiceCodePreviousSnapshotNotFound ServiceCodeType = "PreviousSnapshotNotFound"
|
||||
|
||||
// ServiceCodePreviousSnapshotOperationNotSupported means that differential Get Page Ranges is not supported on the previous snapshot.
|
||||
ServiceCodePreviousSnapshotOperationNotSupported ServiceCodeType = "PreviousSnapshotOperationNotSupported"
|
||||
|
||||
// ServiceCodeSequenceNumberConditionNotMet means the sequence number condition specified was not met.
|
||||
ServiceCodeSequenceNumberConditionNotMet ServiceCodeType = "SequenceNumberConditionNotMet"
|
||||
|
||||
// ServiceCodeSequenceNumberIncrementTooLarge means the sequence number increment cannot be performed because it would result in overflow of the sequence number.
|
||||
ServiceCodeSequenceNumberIncrementTooLarge ServiceCodeType = "SequenceNumberIncrementTooLarge"
|
||||
|
||||
// ServiceCodeSnapshotCountExceeded means the snapshot count against this blob has been exceeded.
|
||||
ServiceCodeSnapshotCountExceeded ServiceCodeType = "SnapshotCountExceeded"
|
||||
|
||||
// ServiceCodeSnaphotOperationRateExceeded means the rate of snapshot operations against this blob has been exceeded.
|
||||
ServiceCodeSnaphotOperationRateExceeded ServiceCodeType = "SnaphotOperationRateExceeded"
|
||||
|
||||
// ServiceCodeSnapshotsPresent means this operation is not permitted while the blob has snapshots.
|
||||
ServiceCodeSnapshotsPresent ServiceCodeType = "SnapshotsPresent"
|
||||
|
||||
// ServiceCodeSourceConditionNotMet means the source condition specified using HTTP conditional header(s) is not met.
|
||||
ServiceCodeSourceConditionNotMet ServiceCodeType = "SourceConditionNotMet"
|
||||
|
||||
// ServiceCodeSystemInUse means this blob is in use by the system.
|
||||
ServiceCodeSystemInUse ServiceCodeType = "SystemInUse"
|
||||
|
||||
// ServiceCodeTargetConditionNotMet means the target condition specified using HTTP conditional header(s) is not met.
|
||||
ServiceCodeTargetConditionNotMet ServiceCodeType = "TargetConditionNotMet"
|
||||
|
||||
// ServiceCodeUnauthorizedBlobOverwrite means this request is not authorized to perform blob overwrites.
|
||||
ServiceCodeUnauthorizedBlobOverwrite ServiceCodeType = "UnauthorizedBlobOverwrite"
|
||||
|
||||
// ServiceCodeBlobBeingRehydrated means this operation is not permitted because the blob is being rehydrated.
|
||||
ServiceCodeBlobBeingRehydrated ServiceCodeType = "BlobBeingRehydrated"
|
||||
|
||||
// ServiceCodeBlobArchived means this operation is not permitted on an archived blob.
|
||||
ServiceCodeBlobArchived ServiceCodeType = "BlobArchived"
|
||||
|
||||
// ServiceCodeBlobNotArchived means this blob is currently not in the archived state.
|
||||
ServiceCodeBlobNotArchived ServiceCodeType = "BlobNotArchived"
|
||||
)
|
131
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/service_codes_common.go
generated
vendored
131
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/service_codes_common.go
generated
vendored
|
@ -1,131 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/common-rest-api-error-codes
|
||||
|
||||
const (
|
||||
// ServiceCodeNone is the default value. It indicates that the error was related to the service or that the service didn't return a code.
|
||||
ServiceCodeNone ServiceCodeType = ""
|
||||
|
||||
// ServiceCodeAccountAlreadyExists means the specified account already exists.
|
||||
ServiceCodeAccountAlreadyExists ServiceCodeType = "AccountAlreadyExists"
|
||||
|
||||
// ServiceCodeAccountBeingCreated means the specified account is in the process of being created (403).
|
||||
ServiceCodeAccountBeingCreated ServiceCodeType = "AccountBeingCreated"
|
||||
|
||||
// ServiceCodeAccountIsDisabled means the specified account is disabled (403).
|
||||
ServiceCodeAccountIsDisabled ServiceCodeType = "AccountIsDisabled"
|
||||
|
||||
// ServiceCodeAuthenticationFailed means the server failed to authenticate the request. Make sure the value of the Authorization header is formed correctly including the signature (403).
|
||||
ServiceCodeAuthenticationFailed ServiceCodeType = "AuthenticationFailed"
|
||||
|
||||
// ServiceCodeConditionHeadersNotSupported means the condition headers are not supported (400).
|
||||
ServiceCodeConditionHeadersNotSupported ServiceCodeType = "ConditionHeadersNotSupported"
|
||||
|
||||
// ServiceCodeConditionNotMet means the condition specified in the conditional header(s) was not met for a read/write operation (304/412).
|
||||
ServiceCodeConditionNotMet ServiceCodeType = "ConditionNotMet"
|
||||
|
||||
// ServiceCodeEmptyMetadataKey means the key for one of the metadata key-value pairs is empty (400).
|
||||
ServiceCodeEmptyMetadataKey ServiceCodeType = "EmptyMetadataKey"
|
||||
|
||||
// ServiceCodeInsufficientAccountPermissions means read operations are currently disabled or Write operations are not allowed or The account being accessed does not have sufficient permissions to execute this operation (403).
|
||||
ServiceCodeInsufficientAccountPermissions ServiceCodeType = "InsufficientAccountPermissions"
|
||||
|
||||
// ServiceCodeInternalError means the server encountered an internal error. Please retry the request (500).
|
||||
ServiceCodeInternalError ServiceCodeType = "InternalError"
|
||||
|
||||
// ServiceCodeInvalidAuthenticationInfo means the authentication information was not provided in the correct format. Verify the value of Authorization header (400).
|
||||
ServiceCodeInvalidAuthenticationInfo ServiceCodeType = "InvalidAuthenticationInfo"
|
||||
|
||||
// ServiceCodeInvalidHeaderValue means the value provided for one of the HTTP headers was not in the correct format (400).
|
||||
ServiceCodeInvalidHeaderValue ServiceCodeType = "InvalidHeaderValue"
|
||||
|
||||
// ServiceCodeInvalidHTTPVerb means the HTTP verb specified was not recognized by the server (400).
|
||||
ServiceCodeInvalidHTTPVerb ServiceCodeType = "InvalidHttpVerb"
|
||||
|
||||
// ServiceCodeInvalidInput means one of the request inputs is not valid (400).
|
||||
ServiceCodeInvalidInput ServiceCodeType = "InvalidInput"
|
||||
|
||||
// ServiceCodeInvalidMd5 means the MD5 value specified in the request is invalid. The MD5 value must be 128 bits and Base64-encoded (400).
|
||||
ServiceCodeInvalidMd5 ServiceCodeType = "InvalidMd5"
|
||||
|
||||
// ServiceCodeInvalidMetadata means the specified metadata is invalid. It includes characters that are not permitted (400).
|
||||
ServiceCodeInvalidMetadata ServiceCodeType = "InvalidMetadata"
|
||||
|
||||
// ServiceCodeInvalidQueryParameterValue means an invalid value was specified for one of the query parameters in the request URI (400).
|
||||
ServiceCodeInvalidQueryParameterValue ServiceCodeType = "InvalidQueryParameterValue"
|
||||
|
||||
// ServiceCodeInvalidRange means the range specified is invalid for the current size of the resource (416).
|
||||
ServiceCodeInvalidRange ServiceCodeType = "InvalidRange"
|
||||
|
||||
// ServiceCodeInvalidResourceName means the specified resource name contains invalid characters (400).
|
||||
ServiceCodeInvalidResourceName ServiceCodeType = "InvalidResourceName"
|
||||
|
||||
// ServiceCodeInvalidURI means the requested URI does not represent any resource on the server (400).
|
||||
ServiceCodeInvalidURI ServiceCodeType = "InvalidUri"
|
||||
|
||||
// ServiceCodeInvalidXMLDocument means the specified XML is not syntactically valid (400).
|
||||
ServiceCodeInvalidXMLDocument ServiceCodeType = "InvalidXmlDocument"
|
||||
|
||||
// ServiceCodeInvalidXMLNodeValue means the value provided for one of the XML nodes in the request body was not in the correct format (400).
|
||||
ServiceCodeInvalidXMLNodeValue ServiceCodeType = "InvalidXmlNodeValue"
|
||||
|
||||
// ServiceCodeMd5Mismatch means the MD5 value specified in the request did not match the MD5 value calculated by the server (400).
|
||||
ServiceCodeMd5Mismatch ServiceCodeType = "Md5Mismatch"
|
||||
|
||||
// ServiceCodeMetadataTooLarge means the size of the specified metadata exceeds the maximum size permitted (400).
|
||||
ServiceCodeMetadataTooLarge ServiceCodeType = "MetadataTooLarge"
|
||||
|
||||
// ServiceCodeMissingContentLengthHeader means the Content-Length header was not specified (411).
|
||||
ServiceCodeMissingContentLengthHeader ServiceCodeType = "MissingContentLengthHeader"
|
||||
|
||||
// ServiceCodeMissingRequiredQueryParameter means a required query parameter was not specified for this request (400).
|
||||
ServiceCodeMissingRequiredQueryParameter ServiceCodeType = "MissingRequiredQueryParameter"
|
||||
|
||||
// ServiceCodeMissingRequiredHeader means a required HTTP header was not specified (400).
|
||||
ServiceCodeMissingRequiredHeader ServiceCodeType = "MissingRequiredHeader"
|
||||
|
||||
// ServiceCodeMissingRequiredXMLNode means a required XML node was not specified in the request body (400).
|
||||
ServiceCodeMissingRequiredXMLNode ServiceCodeType = "MissingRequiredXmlNode"
|
||||
|
||||
// ServiceCodeMultipleConditionHeadersNotSupported means multiple condition headers are not supported (400).
|
||||
ServiceCodeMultipleConditionHeadersNotSupported ServiceCodeType = "MultipleConditionHeadersNotSupported"
|
||||
|
||||
// ServiceCodeOperationTimedOut means the operation could not be completed within the permitted time (500).
|
||||
ServiceCodeOperationTimedOut ServiceCodeType = "OperationTimedOut"
|
||||
|
||||
// ServiceCodeOutOfRangeInput means one of the request inputs is out of range (400).
|
||||
ServiceCodeOutOfRangeInput ServiceCodeType = "OutOfRangeInput"
|
||||
|
||||
// ServiceCodeOutOfRangeQueryParameterValue means a query parameter specified in the request URI is outside the permissible range (400).
|
||||
ServiceCodeOutOfRangeQueryParameterValue ServiceCodeType = "OutOfRangeQueryParameterValue"
|
||||
|
||||
// ServiceCodeRequestBodyTooLarge means the size of the request body exceeds the maximum size permitted (413).
|
||||
ServiceCodeRequestBodyTooLarge ServiceCodeType = "RequestBodyTooLarge"
|
||||
|
||||
// ServiceCodeResourceTypeMismatch means the specified resource type does not match the type of the existing resource (409).
|
||||
ServiceCodeResourceTypeMismatch ServiceCodeType = "ResourceTypeMismatch"
|
||||
|
||||
// ServiceCodeRequestURLFailedToParse means the url in the request could not be parsed (400).
|
||||
ServiceCodeRequestURLFailedToParse ServiceCodeType = "RequestUrlFailedToParse"
|
||||
|
||||
// ServiceCodeResourceAlreadyExists means the specified resource already exists (409).
|
||||
ServiceCodeResourceAlreadyExists ServiceCodeType = "ResourceAlreadyExists"
|
||||
|
||||
// ServiceCodeResourceNotFound means the specified resource does not exist (404).
|
||||
ServiceCodeResourceNotFound ServiceCodeType = "ResourceNotFound"
|
||||
|
||||
// ServiceCodeServerBusy means the server is currently unable to receive requests. Please retry your request or Ingress/egress is over the account limit or operations per second is over the account limit (503).
|
||||
ServiceCodeServerBusy ServiceCodeType = "ServerBusy"
|
||||
|
||||
// ServiceCodeUnsupportedHeader means one of the HTTP headers specified in the request is not supported (400).
|
||||
ServiceCodeUnsupportedHeader ServiceCodeType = "UnsupportedHeader"
|
||||
|
||||
// ServiceCodeUnsupportedXMLNode means one of the XML nodes specified in the request body is not supported (400).
|
||||
ServiceCodeUnsupportedXMLNode ServiceCodeType = "UnsupportedXmlNode"
|
||||
|
||||
// ServiceCodeUnsupportedQueryParameter means one of the query parameters specified in the request URI is not supported (400).
|
||||
ServiceCodeUnsupportedQueryParameter ServiceCodeType = "UnsupportedQueryParameter"
|
||||
|
||||
// ServiceCodeUnsupportedHTTPVerb means the resource doesn't support the specified HTTP verb (405).
|
||||
ServiceCodeUnsupportedHTTPVerb ServiceCodeType = "UnsupportedHttpVerb"
|
||||
)
|
110
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/storage_error.go
generated
vendored
110
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/storage_error.go
generated
vendored
|
@ -1,110 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// wire up our custom error handling constructor
|
||||
responseErrorFactory = newStorageError
|
||||
}
|
||||
|
||||
// ServiceCodeType is a string identifying a specific container or blob error.
|
||||
// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/blob-service-error-codes
|
||||
type ServiceCodeType string
|
||||
|
||||
// StorageError identifies a responder-generated network or response parsing error.
|
||||
type StorageError interface {
|
||||
// ResponseError implements error's Error(), net.Error's Temporary() and Timeout() methods & Response().
|
||||
ResponseError
|
||||
|
||||
// ServiceCode returns a service error code. Your code can use this to make error recovery decisions.
|
||||
ServiceCode() ServiceCodeType
|
||||
}
|
||||
|
||||
// storageError is the internat struct that implements the public StorageError interface.
|
||||
type storageError struct {
|
||||
responseError
|
||||
serviceCode ServiceCodeType
|
||||
details map[string]string
|
||||
}
|
||||
|
||||
// newStorageError creates an error object that implements the error interface.
|
||||
func newStorageError(cause error, response *http.Response, description string) error {
|
||||
return &storageError{
|
||||
responseError: responseError{
|
||||
ErrorNode: pipeline.ErrorNode{}.Initialize(cause, 3),
|
||||
response: response,
|
||||
description: description,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ServiceCode returns service-error information. The caller may examine these values but should not modify any of them.
|
||||
func (e *storageError) ServiceCode() ServiceCodeType { return e.serviceCode }
|
||||
|
||||
// Error implements the error interface's Error method to return a string representation of the error.
|
||||
func (e *storageError) Error() string {
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "===== RESPONSE ERROR (ServiceCode=%s) =====\n", e.serviceCode)
|
||||
fmt.Fprintf(b, "Description=%s, Details: ", e.description)
|
||||
if len(e.details) == 0 {
|
||||
b.WriteString("(none)\n")
|
||||
} else {
|
||||
b.WriteRune('\n')
|
||||
keys := make([]string, 0, len(e.details))
|
||||
// Alphabetize the details
|
||||
for k := range e.details {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
fmt.Fprintf(b, " %s: %+v\n", k, e.details[k])
|
||||
}
|
||||
}
|
||||
req := pipeline.Request{Request: e.response.Request}.Copy() // Make a copy of the response's request
|
||||
pipeline.WriteRequestWithResponse(b, prepareRequestForLogging(req), e.response, nil)
|
||||
return e.ErrorNode.Error(b.String())
|
||||
}
|
||||
|
||||
// Temporary returns true if the error occurred due to a temporary condition (including an HTTP status of 500 or 503).
|
||||
func (e *storageError) Temporary() bool {
|
||||
if e.response != nil {
|
||||
if (e.response.StatusCode == http.StatusInternalServerError) || (e.response.StatusCode == http.StatusServiceUnavailable) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return e.ErrorNode.Temporary()
|
||||
}
|
||||
|
||||
// UnmarshalXML performs custom unmarshalling of XML-formatted Azure storage request errors.
|
||||
func (e *storageError) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
|
||||
tokName := ""
|
||||
var t xml.Token
|
||||
for t, err = d.Token(); err == nil; t, err = d.Token() {
|
||||
switch tt := t.(type) {
|
||||
case xml.StartElement:
|
||||
tokName = tt.Name.Local
|
||||
break
|
||||
case xml.CharData:
|
||||
switch tokName {
|
||||
case "Code":
|
||||
e.serviceCode = ServiceCodeType(tt)
|
||||
case "Message":
|
||||
e.description = string(tt)
|
||||
default:
|
||||
if e.details == nil {
|
||||
e.details = map[string]string{}
|
||||
}
|
||||
e.details[tokName] = string(tt)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
113
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/url_append_blob.go
generated
vendored
113
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/url_append_blob.go
generated
vendored
|
@ -1,113 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
const (
|
||||
// AppendBlobMaxAppendBlockBytes indicates the maximum number of bytes that can be sent in a call to AppendBlock.
|
||||
AppendBlobMaxAppendBlockBytes = 4 * 1024 * 1024 // 4MB
|
||||
|
||||
// AppendBlobMaxBlocks indicates the maximum number of blocks allowed in an append blob.
|
||||
AppendBlobMaxBlocks = 50000
|
||||
)
|
||||
|
||||
// AppendBlobURL defines a set of operations applicable to append blobs.
|
||||
type AppendBlobURL struct {
|
||||
BlobURL
|
||||
abClient appendBlobsClient
|
||||
}
|
||||
|
||||
// NewAppendBlobURL creates an AppendBlobURL object using the specified URL and request policy pipeline.
|
||||
func NewAppendBlobURL(url url.URL, p pipeline.Pipeline) AppendBlobURL {
|
||||
blobClient := newBlobsClient(url, p)
|
||||
abClient := newAppendBlobsClient(url, p)
|
||||
return AppendBlobURL{BlobURL: BlobURL{blobClient: blobClient}, abClient: abClient}
|
||||
}
|
||||
|
||||
// WithPipeline creates a new AppendBlobURL object identical to the source but with the specific request policy pipeline.
|
||||
func (ab AppendBlobURL) WithPipeline(p pipeline.Pipeline) AppendBlobURL {
|
||||
return NewAppendBlobURL(ab.blobClient.URL(), p)
|
||||
}
|
||||
|
||||
// WithSnapshot creates a new AppendBlobURL object identical to the source but with the specified snapshot timestamp.
|
||||
// Pass time.Time{} to remove the snapshot returning a URL to the base blob.
|
||||
func (ab AppendBlobURL) WithSnapshot(snapshot time.Time) AppendBlobURL {
|
||||
p := NewBlobURLParts(ab.URL())
|
||||
p.Snapshot = snapshot
|
||||
return NewAppendBlobURL(p.URL(), ab.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// Create creates a 0-length append blob. Call AppendBlock to append data to an append blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-blob.
|
||||
func (ab AppendBlobURL) Create(ctx context.Context, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions) (*BlobsPutResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch := ac.HTTPAccessConditions.pointers()
|
||||
return ab.blobClient.Put(ctx, BlobAppendBlob, nil, nil, nil,
|
||||
&h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.contentMD5Pointer(), &h.CacheControl,
|
||||
metadata, ac.LeaseAccessConditions.pointers(),
|
||||
&h.ContentDisposition,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, nil, nil, nil)
|
||||
|
||||
}
|
||||
|
||||
// AppendBlock commits a new block of data to the end of the existing append blob.
|
||||
// Note that the http client closes the body stream after the request is sent to the service.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/append-block.
|
||||
func (ab AppendBlobURL) AppendBlock(ctx context.Context, body io.ReadSeeker, ac BlobAccessConditions) (*AppendBlobsAppendBlockResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
ifAppendPositionEqual, ifMaxSizeLessThanOrEqual := ac.AppendBlobAccessConditions.pointers()
|
||||
return ab.abClient.AppendBlock(ctx, body, nil, ac.LeaseAccessConditions.pointers(),
|
||||
ifMaxSizeLessThanOrEqual, ifAppendPositionEqual,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// AppendBlobAccessConditions identifies append blob-specific access conditions which you optionally set.
|
||||
type AppendBlobAccessConditions struct {
|
||||
// IfAppendPositionEqual ensures that the AppendBlock operation succeeds
|
||||
// only if the append position is equal to a value.
|
||||
// IfAppendPositionEqual=0 means no 'IfAppendPositionEqual' header specified.
|
||||
// IfAppendPositionEqual>0 means 'IfAppendPositionEqual' header specified with its value
|
||||
// IfAppendPositionEqual==-1 means IfAppendPositionEqual' header specified with a value of 0
|
||||
IfAppendPositionEqual int32
|
||||
|
||||
// IfMaxSizeLessThanOrEqual ensures that the AppendBlock operation succeeds
|
||||
// only if the append blob's size is less than or equal to a value.
|
||||
// IfMaxSizeLessThanOrEqual=0 means no 'IfMaxSizeLessThanOrEqual' header specified.
|
||||
// IfMaxSizeLessThanOrEqual>0 means 'IfMaxSizeLessThanOrEqual' header specified with its value
|
||||
// IfMaxSizeLessThanOrEqual==-1 means 'IfMaxSizeLessThanOrEqual' header specified with a value of 0
|
||||
IfMaxSizeLessThanOrEqual int32
|
||||
}
|
||||
|
||||
// pointers is for internal infrastructure. It returns the fields as pointers.
|
||||
func (ac AppendBlobAccessConditions) pointers() (iape *int32, imsltoe *int32) {
|
||||
if ac.IfAppendPositionEqual < -1 {
|
||||
panic("IfAppendPositionEqual can't be less than -1")
|
||||
}
|
||||
if ac.IfMaxSizeLessThanOrEqual < -1 {
|
||||
panic("IfMaxSizeLessThanOrEqual can't be less than -1")
|
||||
}
|
||||
var zero int32 // defaults to 0
|
||||
switch ac.IfAppendPositionEqual {
|
||||
case -1:
|
||||
iape = &zero
|
||||
case 0:
|
||||
iape = nil
|
||||
default:
|
||||
iape = &ac.IfAppendPositionEqual
|
||||
}
|
||||
|
||||
switch ac.IfMaxSizeLessThanOrEqual {
|
||||
case -1:
|
||||
imsltoe = &zero
|
||||
case 0:
|
||||
imsltoe = nil
|
||||
default:
|
||||
imsltoe = &ac.IfMaxSizeLessThanOrEqual
|
||||
}
|
||||
return
|
||||
}
|
224
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/url_blob.go
generated
vendored
224
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/url_blob.go
generated
vendored
|
@ -1,224 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// A BlobURL represents a URL to an Azure Storage blob; the blob may be a block blob, append blob, or page blob.
|
||||
type BlobURL struct {
|
||||
blobClient blobsClient
|
||||
}
|
||||
|
||||
// NewBlobURL creates a BlobURL object using the specified URL and request policy pipeline.
|
||||
func NewBlobURL(url url.URL, p pipeline.Pipeline) BlobURL {
|
||||
if p == nil {
|
||||
panic("p can't be nil")
|
||||
}
|
||||
blobClient := newBlobsClient(url, p)
|
||||
return BlobURL{blobClient: blobClient}
|
||||
}
|
||||
|
||||
// URL returns the URL endpoint used by the BlobURL object.
|
||||
func (b BlobURL) URL() url.URL {
|
||||
return b.blobClient.URL()
|
||||
}
|
||||
|
||||
// String returns the URL as a string.
|
||||
func (b BlobURL) String() string {
|
||||
u := b.URL()
|
||||
return u.String()
|
||||
}
|
||||
|
||||
// WithPipeline creates a new BlobURL object identical to the source but with the specified request policy pipeline.
|
||||
func (b BlobURL) WithPipeline(p pipeline.Pipeline) BlobURL {
|
||||
if p == nil {
|
||||
panic("p can't be nil")
|
||||
}
|
||||
return NewBlobURL(b.blobClient.URL(), p)
|
||||
}
|
||||
|
||||
// WithSnapshot creates a new BlobURL object identical to the source but with the specified snapshot timestamp.
|
||||
// Pass time.Time{} to remove the snapshot returning a URL to the base blob.
|
||||
func (b BlobURL) WithSnapshot(snapshot time.Time) BlobURL {
|
||||
p := NewBlobURLParts(b.URL())
|
||||
p.Snapshot = snapshot
|
||||
return NewBlobURL(p.URL(), b.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// ToAppendBlobURL creates an AppendBlobURL using the source's URL and pipeline.
|
||||
func (b BlobURL) ToAppendBlobURL() AppendBlobURL {
|
||||
return NewAppendBlobURL(b.URL(), b.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// ToBlockBlobURL creates a BlockBlobURL using the source's URL and pipeline.
|
||||
func (b BlobURL) ToBlockBlobURL() BlockBlobURL {
|
||||
return NewBlockBlobURL(b.URL(), b.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// ToPageBlobURL creates a PageBlobURL using the source's URL and pipeline.
|
||||
func (b BlobURL) ToPageBlobURL() PageBlobURL {
|
||||
return NewPageBlobURL(b.URL(), b.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// StartCopy copies the data at the source URL to a blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/copy-blob.
|
||||
func (b BlobURL) StartCopy(ctx context.Context, source url.URL, metadata Metadata, srcac BlobAccessConditions, dstac BlobAccessConditions) (*BlobsCopyResponse, error) {
|
||||
srcIfModifiedSince, srcIfUnmodifiedSince, srcIfMatchETag, srcIfNoneMatchETag := srcac.HTTPAccessConditions.pointers()
|
||||
dstIfModifiedSince, dstIfUnmodifiedSince, dstIfMatchETag, dstIfNoneMatchETag := dstac.HTTPAccessConditions.pointers()
|
||||
srcLeaseID := srcac.LeaseAccessConditions.pointers()
|
||||
dstLeaseID := dstac.LeaseAccessConditions.pointers()
|
||||
|
||||
return b.blobClient.Copy(ctx, source.String(), nil, metadata,
|
||||
srcIfModifiedSince, srcIfUnmodifiedSince,
|
||||
srcIfMatchETag, srcIfNoneMatchETag,
|
||||
dstIfModifiedSince, dstIfUnmodifiedSince,
|
||||
dstIfMatchETag, dstIfNoneMatchETag,
|
||||
dstLeaseID, srcLeaseID, nil)
|
||||
}
|
||||
|
||||
// AbortCopy stops a pending copy that was previously started and leaves a destination blob with 0 length and metadata.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/abort-copy-blob.
|
||||
func (b BlobURL) AbortCopy(ctx context.Context, copyID string, ac LeaseAccessConditions) (*BlobsAbortCopyResponse, error) {
|
||||
return b.blobClient.AbortCopy(ctx, copyID, "abort", nil, ac.pointers(), nil)
|
||||
}
|
||||
|
||||
// BlobRange defines a range of bytes within a blob, starting at Offset and ending
|
||||
// at Offset+Count. Use a zero-value BlobRange to indicate the entire blob.
|
||||
type BlobRange struct {
|
||||
Offset int64
|
||||
Count int64
|
||||
}
|
||||
|
||||
func (dr *BlobRange) pointers() *string {
|
||||
if dr.Offset < 0 {
|
||||
panic("The blob's range Offset must be >= 0")
|
||||
}
|
||||
if dr.Count < 0 {
|
||||
panic("The blob's range Count must be >= 0")
|
||||
}
|
||||
if dr.Offset == 0 && dr.Count == 0 {
|
||||
return nil
|
||||
}
|
||||
endRange := ""
|
||||
if dr.Count > 0 {
|
||||
endRange = strconv.FormatInt((dr.Offset+dr.Count)-1, 10)
|
||||
}
|
||||
dataRange := fmt.Sprintf("bytes=%v-%s", dr.Offset, endRange)
|
||||
return &dataRange
|
||||
}
|
||||
|
||||
// GetBlob reads a range of bytes from a blob. The response also includes the blob's properties and metadata.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-blob.
|
||||
func (b BlobURL) GetBlob(ctx context.Context, blobRange BlobRange, ac BlobAccessConditions, rangeGetContentMD5 bool) (*GetResponse, error) {
|
||||
var xRangeGetContentMD5 *bool
|
||||
if rangeGetContentMD5 {
|
||||
xRangeGetContentMD5 = &rangeGetContentMD5
|
||||
}
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return b.blobClient.Get(ctx, nil, nil, blobRange.pointers(), ac.LeaseAccessConditions.pointers(), xRangeGetContentMD5,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// Delete marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection.
|
||||
// Note that deleting a blob also deletes all its snapshots.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/delete-blob.
|
||||
func (b BlobURL) Delete(ctx context.Context, deleteOptions DeleteSnapshotsOptionType, ac BlobAccessConditions) (*BlobsDeleteResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return b.blobClient.Delete(ctx, nil, nil, ac.LeaseAccessConditions.pointers(), deleteOptions,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// GetPropertiesAndMetadata returns the blob's metadata and properties.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-blob-properties.
|
||||
func (b BlobURL) GetPropertiesAndMetadata(ctx context.Context, ac BlobAccessConditions) (*BlobsGetPropertiesResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return b.blobClient.GetProperties(ctx, nil, nil, ac.LeaseAccessConditions.pointers(),
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
// NOTE: GetMetadata actually calls GetProperties since this returns a the properties AND the metadata
|
||||
}
|
||||
|
||||
// SetProperties changes a blob's HTTP header properties.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-blob-properties.
|
||||
func (b BlobURL) SetProperties(ctx context.Context, h BlobHTTPHeaders, ac BlobAccessConditions) (*BlobsSetPropertiesResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return b.blobClient.SetProperties(ctx, nil,
|
||||
&h.CacheControl, &h.ContentType, h.contentMD5Pointer(), &h.ContentEncoding, &h.ContentLanguage,
|
||||
ac.LeaseAccessConditions.pointers(), ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
|
||||
&h.ContentDisposition, nil, SequenceNumberActionNone, nil, nil)
|
||||
}
|
||||
|
||||
// SetMetadata changes a blob's metadata.
|
||||
// https://docs.microsoft.com/rest/api/storageservices/set-blob-metadata.
|
||||
func (b BlobURL) SetMetadata(ctx context.Context, metadata Metadata, ac BlobAccessConditions) (*BlobsSetMetadataResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return b.blobClient.SetMetadata(ctx, nil, metadata, ac.LeaseAccessConditions.pointers(),
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// CreateSnapshot creates a read-only snapshot of a blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/snapshot-blob.
|
||||
func (b BlobURL) CreateSnapshot(ctx context.Context, metadata Metadata, ac BlobAccessConditions) (*BlobsTakeSnapshotResponse, error) {
|
||||
// CreateSnapshot does NOT panic if the user tries to create a snapshot using a URL that already has a snapshot query parameter
|
||||
// because checking this would be a performance hit for a VERY unusual path and I don't think the common case should suffer this
|
||||
// performance hit.
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return b.blobClient.TakeSnapshot(ctx, nil, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, ac.LeaseAccessConditions.pointers(), nil)
|
||||
}
|
||||
|
||||
// AcquireLease acquires a lease on the blob for write and delete operations. The lease duration must be between
|
||||
// 15 to 60 seconds, or infinite (-1).
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob.
|
||||
func (b BlobURL) AcquireLease(ctx context.Context, proposedID string, duration int32, ac HTTPAccessConditions) (*BlobsLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
|
||||
return b.blobClient.Lease(ctx, LeaseActionAcquire, nil, nil, nil, &duration, &proposedID,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// RenewLease renews the blob's previously-acquired lease.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob.
|
||||
func (b BlobURL) RenewLease(ctx context.Context, leaseID string, ac HTTPAccessConditions) (*BlobsLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
|
||||
return b.blobClient.Lease(ctx, LeaseActionRenew, nil, &leaseID, nil, nil, nil,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// ReleaseLease releases the blob's previously-acquired lease.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob.
|
||||
func (b BlobURL) ReleaseLease(ctx context.Context, leaseID string, ac HTTPAccessConditions) (*BlobsLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
|
||||
return b.blobClient.Lease(ctx, LeaseActionRelease, nil, &leaseID, nil, nil, nil,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// BreakLease breaks the blob's previously-acquired lease (if it exists). Pass the LeaseBreakDefault (-1)
|
||||
// constant to break a fixed-duration lease when it expires or an infinite lease immediately.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob.
|
||||
func (b BlobURL) BreakLease(ctx context.Context, breakPeriodInSeconds int32, ac HTTPAccessConditions) (*BlobsLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
|
||||
return b.blobClient.Lease(ctx, LeaseActionBreak, nil, nil, leasePeriodPointer(breakPeriodInSeconds), nil, nil,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// ChangeLease changes the blob's lease ID.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob.
|
||||
func (b BlobURL) ChangeLease(ctx context.Context, leaseID string, proposedID string, ac HTTPAccessConditions) (*BlobsLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
|
||||
return b.blobClient.Lease(ctx, LeaseActionChange, nil, &leaseID, nil, nil, &proposedID,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// LeaseBreakNaturally tells ContainerURL's or BlobURL's BreakLease method to break the lease using service semantics.
|
||||
const LeaseBreakNaturally = -1
|
||||
|
||||
func leasePeriodPointer(period int32) (p *int32) {
|
||||
if period != LeaseBreakNaturally {
|
||||
p = &period
|
||||
}
|
||||
return nil
|
||||
}
|
92
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/url_block_blob.go
generated
vendored
92
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/url_block_blob.go
generated
vendored
|
@ -1,92 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
const (
|
||||
// BlockBlobMaxPutBlobBytes indicates the maximum number of bytes that can be sent in a call to PutBlob.
|
||||
BlockBlobMaxPutBlobBytes = 256 * 1024 * 1024 // 256MB
|
||||
|
||||
// BlockBlobMaxPutBlockBytes indicates the maximum number of bytes that can be sent in a call to PutBlock.
|
||||
BlockBlobMaxPutBlockBytes = 100 * 1024 * 1024 // 100MB
|
||||
|
||||
// BlockBlobMaxBlocks indicates the maximum number of blocks allowed in a block blob.
|
||||
BlockBlobMaxBlocks = 50000
|
||||
)
|
||||
|
||||
// BlockBlobURL defines a set of operations applicable to block blobs.
|
||||
type BlockBlobURL struct {
|
||||
BlobURL
|
||||
bbClient blockBlobsClient
|
||||
}
|
||||
|
||||
// NewBlockBlobURL creates a BlockBlobURL object using the specified URL and request policy pipeline.
|
||||
func NewBlockBlobURL(url url.URL, p pipeline.Pipeline) BlockBlobURL {
|
||||
if p == nil {
|
||||
panic("p can't be nil")
|
||||
}
|
||||
blobClient := newBlobsClient(url, p)
|
||||
bbClient := newBlockBlobsClient(url, p)
|
||||
return BlockBlobURL{BlobURL: BlobURL{blobClient: blobClient}, bbClient: bbClient}
|
||||
}
|
||||
|
||||
// WithPipeline creates a new BlockBlobURL object identical to the source but with the specific request policy pipeline.
|
||||
func (bb BlockBlobURL) WithPipeline(p pipeline.Pipeline) BlockBlobURL {
|
||||
return NewBlockBlobURL(bb.blobClient.URL(), p)
|
||||
}
|
||||
|
||||
// WithSnapshot creates a new BlockBlobURL object identical to the source but with the specified snapshot timestamp.
|
||||
// Pass time.Time{} to remove the snapshot returning a URL to the base blob.
|
||||
func (bb BlockBlobURL) WithSnapshot(snapshot time.Time) BlockBlobURL {
|
||||
p := NewBlobURLParts(bb.URL())
|
||||
p.Snapshot = snapshot
|
||||
return NewBlockBlobURL(p.URL(), bb.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// PutBlob creates a new block blob, or updates the content of an existing block blob.
|
||||
// Updating an existing block blob overwrites any existing metadata on the blob. Partial updates are not
|
||||
// supported with PutBlob; the content of the existing blob is overwritten with the new content. To
|
||||
// perform a partial update of a block blob's, use PutBlock and PutBlockList. Note that the http client
|
||||
// closes the body stream after the request is sent to the service.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-blob.
|
||||
func (bb BlockBlobURL) PutBlob(ctx context.Context, body io.ReadSeeker, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions) (*BlobsPutResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return bb.blobClient.Put(ctx, BlobBlockBlob, body, nil, nil,
|
||||
&h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.contentMD5Pointer(), &h.CacheControl,
|
||||
metadata, ac.LeaseAccessConditions.pointers(),
|
||||
&h.ContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil, nil, nil)
|
||||
}
|
||||
|
||||
// GetBlockList returns the list of blocks that have been uploaded as part of a block blob using the specified block list filter.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-block-list.
|
||||
func (bb BlockBlobURL) GetBlockList(ctx context.Context, listType BlockListType, ac LeaseAccessConditions) (*BlockList, error) {
|
||||
return bb.bbClient.GetBlockList(ctx, listType, nil, nil, ac.pointers(), nil)
|
||||
}
|
||||
|
||||
// PutBlock uploads the specified block to the block blob's "staging area" to be later committed by a call to PutBlockList.
|
||||
// Note that the http client closes the body stream after the request is sent to the service.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-block.
|
||||
func (bb BlockBlobURL) PutBlock(ctx context.Context, base64BlockID string, body io.ReadSeeker, ac LeaseAccessConditions) (*BlockBlobsPutBlockResponse, error) {
|
||||
return bb.bbClient.PutBlock(ctx, base64BlockID, body, nil, ac.pointers(), nil)
|
||||
}
|
||||
|
||||
// PutBlockList writes a blob by specifying the list of block IDs that make up the blob.
|
||||
// In order to be written as part of a blob, a block must have been successfully written
|
||||
// to the server in a prior PutBlock operation. You can call PutBlockList to update a blob
|
||||
// by uploading only those blocks that have changed, then committing the new and existing
|
||||
// blocks together. Any blocks not specified in the block list and permanently deleted.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-block-list.
|
||||
func (bb BlockBlobURL) PutBlockList(ctx context.Context, base64BlockIDs []string, h BlobHTTPHeaders,
|
||||
metadata Metadata, ac BlobAccessConditions) (*BlockBlobsPutBlockListResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return bb.bbClient.PutBlockList(ctx, BlockLookupList{Latest: base64BlockIDs}, nil,
|
||||
&h.CacheControl, &h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.contentMD5Pointer(),
|
||||
metadata, ac.LeaseAccessConditions.pointers(), &h.ContentDisposition,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
290
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/url_container.go
generated
vendored
290
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/url_container.go
generated
vendored
|
@ -1,290 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// A ContainerURL represents a URL to the Azure Storage container allowing you to manipulate its blobs.
|
||||
type ContainerURL struct {
|
||||
client containerClient
|
||||
}
|
||||
|
||||
// NewContainerURL creates a ContainerURL object using the specified URL and request policy pipeline.
|
||||
func NewContainerURL(url url.URL, p pipeline.Pipeline) ContainerURL {
|
||||
if p == nil {
|
||||
panic("p can't be nil")
|
||||
}
|
||||
client := newContainerClient(url, p)
|
||||
return ContainerURL{client: client}
|
||||
}
|
||||
|
||||
// URL returns the URL endpoint used by the ContainerURL object.
|
||||
func (c ContainerURL) URL() url.URL {
|
||||
return c.client.URL()
|
||||
}
|
||||
|
||||
// String returns the URL as a string.
|
||||
func (c ContainerURL) String() string {
|
||||
u := c.URL()
|
||||
return u.String()
|
||||
}
|
||||
|
||||
// WithPipeline creates a new ContainerURL object identical to the source but with the specified request policy pipeline.
|
||||
func (c ContainerURL) WithPipeline(p pipeline.Pipeline) ContainerURL {
|
||||
return NewContainerURL(c.URL(), p)
|
||||
}
|
||||
|
||||
// NewBlobURL creates a new BlobURL object by concatenating blobName to the end of
|
||||
// ContainerURL's URL. The new BlobURL uses the same request policy pipeline as the ContainerURL.
|
||||
// To change the pipeline, create the BlobURL and then call its WithPipeline method passing in the
|
||||
// desired pipeline object. Or, call this package's NewBlobURL instead of calling this object's
|
||||
// NewBlobURL method.
|
||||
func (c ContainerURL) NewBlobURL(blobName string) BlobURL {
|
||||
blobURL := appendToURLPath(c.URL(), blobName)
|
||||
return NewBlobURL(blobURL, c.client.Pipeline())
|
||||
}
|
||||
|
||||
// NewAppendBlobURL creates a new AppendBlobURL object by concatenating blobName to the end of
|
||||
// ContainerURL's URL. The new AppendBlobURL uses the same request policy pipeline as the ContainerURL.
|
||||
// To change the pipeline, create the AppendBlobURL and then call its WithPipeline method passing in the
|
||||
// desired pipeline object. Or, call this package's NewAppendBlobURL instead of calling this object's
|
||||
// NewAppendBlobURL method.
|
||||
func (c ContainerURL) NewAppendBlobURL(blobName string) AppendBlobURL {
|
||||
blobURL := appendToURLPath(c.URL(), blobName)
|
||||
return NewAppendBlobURL(blobURL, c.client.Pipeline())
|
||||
}
|
||||
|
||||
// NewBlockBlobURL creates a new BlockBlobURL object by concatenating blobName to the end of
|
||||
// ContainerURL's URL. The new BlockBlobURL uses the same request policy pipeline as the ContainerURL.
|
||||
// To change the pipeline, create the BlockBlobURL and then call its WithPipeline method passing in the
|
||||
// desired pipeline object. Or, call this package's NewBlockBlobURL instead of calling this object's
|
||||
// NewBlockBlobURL method.
|
||||
func (c ContainerURL) NewBlockBlobURL(blobName string) BlockBlobURL {
|
||||
blobURL := appendToURLPath(c.URL(), blobName)
|
||||
return NewBlockBlobURL(blobURL, c.client.Pipeline())
|
||||
}
|
||||
|
||||
// NewPageBlobURL creates a new PageBlobURL object by concatenating blobName to the end of
|
||||
// ContainerURL's URL. The new PageBlobURL uses the same request policy pipeline as the ContainerURL.
|
||||
// To change the pipeline, create the PageBlobURL and then call its WithPipeline method passing in the
|
||||
// desired pipeline object. Or, call this package's NewPageBlobURL instead of calling this object's
|
||||
// NewPageBlobURL method.
|
||||
func (c ContainerURL) NewPageBlobURL(blobName string) PageBlobURL {
|
||||
blobURL := appendToURLPath(c.URL(), blobName)
|
||||
return NewPageBlobURL(blobURL, c.client.Pipeline())
|
||||
}
|
||||
|
||||
// Create creates a new container within a storage account. If a container with the same name already exists, the operation fails.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/create-container.
|
||||
func (c ContainerURL) Create(ctx context.Context, metadata Metadata, publicAccessType PublicAccessType) (*ContainerCreateResponse, error) {
|
||||
return c.client.Create(ctx, nil, metadata, publicAccessType, nil)
|
||||
}
|
||||
|
||||
// Delete marks the specified container for deletion. The container and any blobs contained within it are later deleted during garbage collection.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/delete-container.
|
||||
func (c ContainerURL) Delete(ctx context.Context, ac ContainerAccessConditions) (*ContainerDeleteResponse, error) {
|
||||
if ac.IfMatch != ETagNone || ac.IfNoneMatch != ETagNone {
|
||||
panic("the IfMatch and IfNoneMatch access conditions must have their default values because they are ignored by the service")
|
||||
}
|
||||
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return c.client.Delete(ctx, nil, nil, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// GetPropertiesAndMetadata returns the container's metadata and system properties.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-container-metadata.
|
||||
func (c ContainerURL) GetPropertiesAndMetadata(ctx context.Context, ac LeaseAccessConditions) (*ContainerGetPropertiesResponse, error) {
|
||||
// NOTE: GetMetadata actually calls GetProperties internally because GetProperties returns the metadata AND the properties.
|
||||
// This allows us to not expose a GetProperties method at all simplifying the API.
|
||||
return c.client.GetProperties(ctx, nil, ac.pointers(), nil)
|
||||
}
|
||||
|
||||
// SetMetadata sets the container's metadata.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-container-metadata.
|
||||
func (c ContainerURL) SetMetadata(ctx context.Context, metadata Metadata, ac ContainerAccessConditions) (*ContainerSetMetadataResponse, error) {
|
||||
if !ac.IfUnmodifiedSince.IsZero() || ac.IfMatch != ETagNone || ac.IfNoneMatch != ETagNone {
|
||||
panic("the IfUnmodifiedSince, IfMatch, and IfNoneMatch must have their default values because they are ignored by the blob service")
|
||||
}
|
||||
ifModifiedSince, _, _, _ := ac.HTTPAccessConditions.pointers()
|
||||
return c.client.SetMetadata(ctx, nil, ac.LeaseAccessConditions.pointers(), metadata, ifModifiedSince, nil)
|
||||
}
|
||||
|
||||
// GetPermissions returns the container's permissions. The permissions indicate whether container's blobs may be accessed publicly.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-container-acl.
|
||||
func (c ContainerURL) GetPermissions(ctx context.Context, ac LeaseAccessConditions) (*SignedIdentifiers, error) {
|
||||
return c.client.GetACL(ctx, nil, ac.pointers(), nil)
|
||||
}
|
||||
|
||||
// The AccessPolicyPermission type simplifies creating the permissions string for a container's access policy.
|
||||
// Initialize an instance of this type and then call its String method to set AccessPolicy's Permission field.
|
||||
type AccessPolicyPermission struct {
|
||||
Read, Add, Create, Write, Delete, List bool
|
||||
}
|
||||
|
||||
// String produces the access policy permission string for an Azure Storage container.
|
||||
// Call this method to set AccessPolicy's Permission field.
|
||||
func (p AccessPolicyPermission) String() string {
|
||||
var b bytes.Buffer
|
||||
if p.Read {
|
||||
b.WriteRune('r')
|
||||
}
|
||||
if p.Add {
|
||||
b.WriteRune('a')
|
||||
}
|
||||
if p.Create {
|
||||
b.WriteRune('c')
|
||||
}
|
||||
if p.Write {
|
||||
b.WriteRune('w')
|
||||
}
|
||||
if p.Delete {
|
||||
b.WriteRune('d')
|
||||
}
|
||||
if p.List {
|
||||
b.WriteRune('l')
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Parse initializes the AccessPolicyPermission's fields from a string.
|
||||
func (p *AccessPolicyPermission) Parse(s string) error {
|
||||
*p = AccessPolicyPermission{} // Clear the flags
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 'r':
|
||||
p.Read = true
|
||||
case 'a':
|
||||
p.Add = true
|
||||
case 'c':
|
||||
p.Create = true
|
||||
case 'w':
|
||||
p.Write = true
|
||||
case 'd':
|
||||
p.Delete = true
|
||||
case 'l':
|
||||
p.List = true
|
||||
default:
|
||||
return fmt.Errorf("Invalid permission: '%v'", r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetPermissions sets the container's permissions. The permissions indicate whether blobs in a container may be accessed publicly.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-container-acl.
|
||||
func (c ContainerURL) SetPermissions(ctx context.Context, accessType PublicAccessType, permissions []SignedIdentifier,
|
||||
ac ContainerAccessConditions) (*ContainerSetACLResponse, error) {
|
||||
if ac.IfMatch != ETagNone || ac.IfNoneMatch != ETagNone {
|
||||
panic("the IfMatch and IfNoneMatch access conditions must have their default values because they are ignored by the service")
|
||||
}
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return c.client.SetACL(ctx, permissions, nil, nil, accessType, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// AcquireLease acquires a lease on the container for delete operations. The lease duration must be between 15 to 60 seconds, or infinite (-1).
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container.
|
||||
func (c ContainerURL) AcquireLease(ctx context.Context, proposedID string, duration int32, ac HTTPAccessConditions) (*ContainerLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers()
|
||||
return c.client.Lease(ctx, LeaseActionAcquire, nil, nil, nil, &duration, &proposedID,
|
||||
ifModifiedSince, ifUnmodifiedSince, nil)
|
||||
}
|
||||
|
||||
// RenewLease renews the container's previously-acquired lease.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container.
|
||||
func (c ContainerURL) RenewLease(ctx context.Context, leaseID string, ac HTTPAccessConditions) (*ContainerLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers()
|
||||
return c.client.Lease(ctx, LeaseActionRenew, nil, &leaseID, nil, nil, nil, ifModifiedSince, ifUnmodifiedSince, nil)
|
||||
}
|
||||
|
||||
// ReleaseLease releases the container's previously-acquired lease.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container.
|
||||
func (c ContainerURL) ReleaseLease(ctx context.Context, leaseID string, ac HTTPAccessConditions) (*ContainerLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers()
|
||||
return c.client.Lease(ctx, LeaseActionRelease, nil, &leaseID, nil, nil, nil, ifModifiedSince, ifUnmodifiedSince, nil)
|
||||
}
|
||||
|
||||
// BreakLease breaks the container's previously-acquired lease (if it exists).
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container.
|
||||
func (c ContainerURL) BreakLease(ctx context.Context, period int32, ac HTTPAccessConditions) (*ContainerLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers()
|
||||
return c.client.Lease(ctx, LeaseActionBreak, nil, nil, leasePeriodPointer(period), nil, nil, ifModifiedSince, ifUnmodifiedSince, nil)
|
||||
}
|
||||
|
||||
// ChangeLease changes the container's lease ID.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container.
|
||||
func (c ContainerURL) ChangeLease(ctx context.Context, leaseID string, proposedID string, ac HTTPAccessConditions) (*ContainerLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers()
|
||||
return c.client.Lease(ctx, LeaseActionChange, nil, &leaseID, nil, nil, &proposedID, ifModifiedSince, ifUnmodifiedSince, nil)
|
||||
}
|
||||
|
||||
// ListBlobs returns a single segment of blobs starting from the specified Marker. Use an empty
|
||||
// Marker to start enumeration from the beginning. Blob names are returned in lexicographic order.
|
||||
// After getting a segment, process it, and then call ListBlobs again (passing the the previously-returned
|
||||
// Marker) to get the next segment.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/list-blobs.
|
||||
func (c ContainerURL) ListBlobs(ctx context.Context, marker Marker, o ListBlobsOptions) (*ListBlobsResponse, error) {
|
||||
prefix, delimiter, include, maxResults := o.pointers()
|
||||
return c.client.ListBlobs(ctx, prefix, delimiter, marker.val, maxResults, include, nil, nil)
|
||||
}
|
||||
|
||||
// ListBlobsOptions defines options available when calling ListBlobs.
|
||||
type ListBlobsOptions struct {
|
||||
Details BlobListingDetails // No IncludeType header is produced if ""
|
||||
Prefix string // No Prefix header is produced if ""
|
||||
Delimiter string
|
||||
|
||||
// SetMaxResults sets the maximum desired results you want the service to return. Note, the
|
||||
// service may return fewer results than requested.
|
||||
// MaxResults=0 means no 'MaxResults' header specified.
|
||||
MaxResults int32
|
||||
}
|
||||
|
||||
func (o *ListBlobsOptions) pointers() (prefix *string, delimiter *string, include ListBlobsIncludeType, maxResults *int32) {
|
||||
if o.Prefix != "" {
|
||||
prefix = &o.Prefix
|
||||
}
|
||||
if o.Delimiter != "" {
|
||||
delimiter = &o.Delimiter
|
||||
}
|
||||
include = ListBlobsIncludeType(o.Details.string())
|
||||
if o.MaxResults != 0 {
|
||||
if o.MaxResults < 0 {
|
||||
panic("MaxResults must be >= 0")
|
||||
}
|
||||
maxResults = &o.MaxResults
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// BlobListingDetails indicates what additional information the service should return with each blob.
|
||||
type BlobListingDetails struct {
|
||||
Copy, Metadata, Snapshots, UncommittedBlobs bool
|
||||
}
|
||||
|
||||
// string produces the Include query parameter's value.
|
||||
func (d *BlobListingDetails) string() string {
|
||||
items := make([]string, 0, 4)
|
||||
// NOTE: Multiple strings MUST be appended in alphabetic order or signing the string for authentication fails!
|
||||
if d.Copy {
|
||||
items = append(items, string(ListBlobsIncludeCopy))
|
||||
}
|
||||
if d.Metadata {
|
||||
items = append(items, string(ListBlobsIncludeMetadata))
|
||||
}
|
||||
if d.Snapshots {
|
||||
items = append(items, string(ListBlobsIncludeSnapshots))
|
||||
}
|
||||
if d.UncommittedBlobs {
|
||||
items = append(items, string(ListBlobsIncludeUncommittedblobs))
|
||||
}
|
||||
if len(items) > 0 {
|
||||
return strings.Join(items, ",")
|
||||
}
|
||||
return string(ListBlobsIncludeNone)
|
||||
}
|
226
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/url_page_blob.go
generated
vendored
226
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/url_page_blob.go
generated
vendored
|
@ -1,226 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
const (
|
||||
// PageBlobPageBytes indicates the number of bytes in a page (512).
|
||||
PageBlobPageBytes = 512
|
||||
|
||||
// PageBlobMaxPutPagesBytes indicates the maximum number of bytes that can be sent in a call to PutPage.
|
||||
PageBlobMaxPutPagesBytes = 4 * 1024 * 1024 // 4MB
|
||||
)
|
||||
|
||||
// PageBlobURL defines a set of operations applicable to page blobs.
|
||||
type PageBlobURL struct {
|
||||
BlobURL
|
||||
pbClient pageBlobsClient
|
||||
}
|
||||
|
||||
// NewPageBlobURL creates a PageBlobURL object using the specified URL and request policy pipeline.
|
||||
func NewPageBlobURL(url url.URL, p pipeline.Pipeline) PageBlobURL {
|
||||
if p == nil {
|
||||
panic("p can't be nil")
|
||||
}
|
||||
blobClient := newBlobsClient(url, p)
|
||||
pbClient := newPageBlobsClient(url, p)
|
||||
return PageBlobURL{BlobURL: BlobURL{blobClient: blobClient}, pbClient: pbClient}
|
||||
}
|
||||
|
||||
// WithPipeline creates a new PageBlobURL object identical to the source but with the specific request policy pipeline.
|
||||
func (pb PageBlobURL) WithPipeline(p pipeline.Pipeline) PageBlobURL {
|
||||
return NewPageBlobURL(pb.blobClient.URL(), p)
|
||||
}
|
||||
|
||||
// WithSnapshot creates a new PageBlobURL object identical to the source but with the specified snapshot timestamp.
|
||||
// Pass time.Time{} to remove the snapshot returning a URL to the base blob.
|
||||
func (pb PageBlobURL) WithSnapshot(snapshot time.Time) PageBlobURL {
|
||||
p := NewBlobURLParts(pb.URL())
|
||||
p.Snapshot = snapshot
|
||||
return NewPageBlobURL(p.URL(), pb.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// Create creates a page blob of the specified length. Call PutPage to upload data data to a page blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-blob.
|
||||
func (pb PageBlobURL) Create(ctx context.Context, size int64, sequenceNumber int64, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions) (*BlobsPutResponse, error) {
|
||||
if sequenceNumber < 0 {
|
||||
panic("sequenceNumber must be greater than or equal to 0")
|
||||
}
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return pb.blobClient.Put(ctx, BlobPageBlob, nil, nil, nil,
|
||||
&h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.contentMD5Pointer(), &h.CacheControl,
|
||||
metadata, ac.LeaseAccessConditions.pointers(),
|
||||
&h.ContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, &size, &sequenceNumber, nil)
|
||||
}
|
||||
|
||||
// PutPages writes 1 or more pages to the page blob. The start and end offsets must be a multiple of 512.
|
||||
// Note that the http client closes the body stream after the request is sent to the service.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-page.
|
||||
func (pb PageBlobURL) PutPages(ctx context.Context, pr PageRange, body io.ReadSeeker, ac BlobAccessConditions) (*PageBlobsPutPageResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual := ac.PageBlobAccessConditions.pointers()
|
||||
return pb.pbClient.PutPage(ctx, PageWriteUpdate, body, nil, pr.pointers(), ac.LeaseAccessConditions.pointers(),
|
||||
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// ClearPages frees the specified pages from the page blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-page.
|
||||
func (pb PageBlobURL) ClearPages(ctx context.Context, pr PageRange, ac BlobAccessConditions) (*PageBlobsPutPageResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual := ac.PageBlobAccessConditions.pointers()
|
||||
return pb.pbClient.PutPage(ctx, PageWriteClear, nil, nil, pr.pointers(), ac.LeaseAccessConditions.pointers(),
|
||||
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan,
|
||||
ifSequenceNumberEqual, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// GetPageRanges returns the list of valid page ranges for a page blob or snapshot of a page blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-page-ranges.
|
||||
func (pb PageBlobURL) GetPageRanges(ctx context.Context, br BlobRange, ac BlobAccessConditions) (*PageList, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return pb.pbClient.GetPageRanges(ctx, nil, nil, nil, br.pointers(), ac.LeaseAccessConditions.pointers(),
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// GetPageRangesDiff gets the collection of page ranges that differ between a specified snapshot and this page blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-page-ranges.
|
||||
func (pb PageBlobURL) GetPageRangesDiff(ctx context.Context, br BlobRange, prevSnapshot time.Time, ac BlobAccessConditions) (*PageList, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return pb.pbClient.GetPageRanges(ctx, nil, nil, &prevSnapshot, br.pointers(),
|
||||
ac.LeaseAccessConditions.pointers(), ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// Resize resizes the page blob to the specified size (which must be a multiple of 512).
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-blob-properties.
|
||||
func (pb PageBlobURL) Resize(ctx context.Context, size int64, ac BlobAccessConditions) (*BlobsSetPropertiesResponse, error) {
|
||||
if size%PageBlobPageBytes != 0 {
|
||||
panic("Size must be a multiple of PageBlobPageBytes (512)")
|
||||
}
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return pb.blobClient.SetProperties(ctx, nil, nil, nil, nil, nil, nil, ac.LeaseAccessConditions.pointers(),
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil, &size, SequenceNumberActionNone, nil, nil)
|
||||
}
|
||||
|
||||
// SetSequenceNumber sets the page blob's sequence number.
|
||||
func (pb PageBlobURL) SetSequenceNumber(ctx context.Context, action SequenceNumberActionType, sequenceNumber int64,
|
||||
h BlobHTTPHeaders, ac BlobAccessConditions) (*BlobsSetPropertiesResponse, error) {
|
||||
if sequenceNumber < 0 {
|
||||
panic("sequenceNumber must be greater than or equal to 0")
|
||||
}
|
||||
sn := &sequenceNumber
|
||||
if action == SequenceNumberActionIncrement {
|
||||
sn = nil
|
||||
}
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch := ac.HTTPAccessConditions.pointers()
|
||||
return pb.blobClient.SetProperties(ctx, nil, &h.CacheControl, &h.ContentType, h.contentMD5Pointer(), &h.ContentEncoding, &h.ContentLanguage,
|
||||
ac.LeaseAccessConditions.pointers(),
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, &h.ContentDisposition, nil, action, sn, nil)
|
||||
}
|
||||
|
||||
// StartIncrementalCopy begins an operation to start an incremental copy from one page blob's snapshot to this page blob.
|
||||
// The snapshot is copied such that only the differential changes between the previously copied snapshot are transferred to the destination.
|
||||
// The copied snapshots are complete copies of the original snapshot and can be read or copied from as usual.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/incremental-copy-blob and
|
||||
// https://docs.microsoft.com/en-us/azure/virtual-machines/windows/incremental-snapshots.
|
||||
func (pb PageBlobURL) StartIncrementalCopy(ctx context.Context, source url.URL, snapshot time.Time, ac BlobAccessConditions) (*PageBlobsIncrementalCopyResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
qp := source.Query()
|
||||
qp.Set("snapshot", snapshot.Format(snapshotTimeFormat))
|
||||
source.RawQuery = qp.Encode()
|
||||
return pb.pbClient.IncrementalCopy(ctx, source.String(), nil, nil,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
func (pr PageRange) pointers() *string {
|
||||
if pr.Start < 0 {
|
||||
panic("PageRange's Start value must be greater than or equal to 0")
|
||||
}
|
||||
if pr.End <= 0 {
|
||||
panic("PageRange's End value must be greater than 0")
|
||||
}
|
||||
if pr.Start%512 != 0 {
|
||||
panic("PageRange's Start value must be a multiple of 512")
|
||||
}
|
||||
if pr.End%512 != 511 {
|
||||
panic("PageRange's End value must be 1 less than a multiple of 512")
|
||||
}
|
||||
if pr.End <= pr.Start {
|
||||
panic("PageRange's End value must be after the start")
|
||||
}
|
||||
endOffset := strconv.FormatInt(int64(pr.End), 10)
|
||||
asString := fmt.Sprintf("bytes=%v-%s", pr.Start, endOffset)
|
||||
return &asString
|
||||
}
|
||||
|
||||
// PageBlobAccessConditions identifies page blob-specific access conditions which you optionally set.
|
||||
type PageBlobAccessConditions struct {
|
||||
// IfSequenceNumberLessThan ensures that the page blob operation succeeds
|
||||
// only if the blob's sequence number is less than a value.
|
||||
// IfSequenceNumberLessThan=0 means no 'IfSequenceNumberLessThan' header specified.
|
||||
// IfSequenceNumberLessThan>0 means 'IfSequenceNumberLessThan' header specified with its value
|
||||
// IfSequenceNumberLessThan==-1 means 'IfSequenceNumberLessThan' header specified with a value of 0
|
||||
IfSequenceNumberLessThan int32
|
||||
|
||||
// IfSequenceNumberLessThanOrEqual ensures that the page blob operation succeeds
|
||||
// only if the blob's sequence number is less than or equal to a value.
|
||||
// IfSequenceNumberLessThanOrEqual=0 means no 'IfSequenceNumberLessThanOrEqual' header specified.
|
||||
// IfSequenceNumberLessThanOrEqual>0 means 'IfSequenceNumberLessThanOrEqual' header specified with its value
|
||||
// IfSequenceNumberLessThanOrEqual=-1 means 'IfSequenceNumberLessThanOrEqual' header specified with a value of 0
|
||||
IfSequenceNumberLessThanOrEqual int32
|
||||
|
||||
// IfSequenceNumberEqual ensures that the page blob operation succeeds
|
||||
// only if the blob's sequence number is equal to a value.
|
||||
// IfSequenceNumberEqual=0 means no 'IfSequenceNumberEqual' header specified.
|
||||
// IfSequenceNumberEqual>0 means 'IfSequenceNumberEqual' header specified with its value
|
||||
// IfSequenceNumberEqual=-1 means 'IfSequenceNumberEqual' header specified with a value of 0
|
||||
IfSequenceNumberEqual int32
|
||||
}
|
||||
|
||||
// pointers is for internal infrastructure. It returns the fields as pointers.
|
||||
func (ac PageBlobAccessConditions) pointers() (snltoe *int32, snlt *int32, sne *int32) {
|
||||
if ac.IfSequenceNumberLessThan < -1 {
|
||||
panic("Ifsequencenumberlessthan can't be less than -1")
|
||||
}
|
||||
if ac.IfSequenceNumberLessThanOrEqual < -1 {
|
||||
panic("IfSequenceNumberLessThanOrEqual can't be less than -1")
|
||||
}
|
||||
if ac.IfSequenceNumberEqual < -1 {
|
||||
panic("IfSequenceNumberEqual can't be less than -1")
|
||||
}
|
||||
|
||||
var zero int32 // Defaults to 0
|
||||
switch ac.IfSequenceNumberLessThan {
|
||||
case -1:
|
||||
snlt = &zero
|
||||
case 0:
|
||||
snlt = nil
|
||||
default:
|
||||
snlt = &ac.IfSequenceNumberLessThan
|
||||
}
|
||||
|
||||
switch ac.IfSequenceNumberLessThanOrEqual {
|
||||
case -1:
|
||||
snltoe = &zero
|
||||
case 0:
|
||||
snltoe = nil
|
||||
default:
|
||||
snltoe = &ac.IfSequenceNumberLessThanOrEqual
|
||||
}
|
||||
switch ac.IfSequenceNumberEqual {
|
||||
case -1:
|
||||
sne = &zero
|
||||
case 0:
|
||||
sne = nil
|
||||
default:
|
||||
sne = &ac.IfSequenceNumberEqual
|
||||
}
|
||||
return
|
||||
}
|
189
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/url_service.go
generated
vendored
189
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/url_service.go
generated
vendored
|
@ -1,189 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
const (
|
||||
// RootContainerName is the special Azure Storage name used to identify a storage account's root container.
|
||||
RootContainerName = "$root"
|
||||
)
|
||||
|
||||
// PipelineOptions is used to configure a request policy pipeline's retry policy and logging.
|
||||
type PipelineOptions struct {
|
||||
// Log configures the pipeline's logging infrastructure indicating what information is logged and where.
|
||||
Log pipeline.LogOptions
|
||||
|
||||
// Retry configures the built-in retry policy behavior.
|
||||
Retry RetryOptions
|
||||
|
||||
// RequestLog configures the built-in request logging policy.
|
||||
RequestLog RequestLogOptions
|
||||
|
||||
// Telemetry configures the built-in telemetry policy behavior.
|
||||
Telemetry TelemetryOptions
|
||||
}
|
||||
|
||||
// NewPipeline creates a Pipeline using the specified credentials and options.
|
||||
func NewPipeline(c Credential, o PipelineOptions) pipeline.Pipeline {
|
||||
if c == nil {
|
||||
panic("c can't be nil")
|
||||
}
|
||||
|
||||
// Closest to API goes first; closest to the wire goes last
|
||||
f := []pipeline.Factory{
|
||||
NewTelemetryPolicyFactory(o.Telemetry),
|
||||
NewUniqueRequestIDPolicyFactory(),
|
||||
NewRetryPolicyFactory(o.Retry),
|
||||
}
|
||||
|
||||
if _, ok := c.(*anonymousCredentialPolicyFactory); !ok {
|
||||
// For AnonymousCredential, we optimize out the policy factory since it doesn't do anything
|
||||
// NOTE: The credential's policy factory must appear close to the wire so it can sign any
|
||||
// changes made by other factories (like UniqueRequestIDPolicyFactory)
|
||||
f = append(f, c)
|
||||
}
|
||||
f = append(f,
|
||||
pipeline.MethodFactoryMarker(), // indicates at what stage in the pipeline the method factory is invoked
|
||||
NewRequestLogPolicyFactory(o.RequestLog))
|
||||
|
||||
return pipeline.NewPipeline(f, pipeline.Options{HTTPSender: nil, Log: o.Log})
|
||||
}
|
||||
|
||||
// A ServiceURL represents a URL to the Azure Storage Blob service allowing you to manipulate blob containers.
|
||||
type ServiceURL struct {
|
||||
client serviceClient
|
||||
}
|
||||
|
||||
// NewServiceURL creates a ServiceURL object using the specified URL and request policy pipeline.
|
||||
func NewServiceURL(primaryURL url.URL, p pipeline.Pipeline) ServiceURL {
|
||||
if p == nil {
|
||||
panic("p can't be nil")
|
||||
}
|
||||
client := newServiceClient(primaryURL, p)
|
||||
return ServiceURL{client: client}
|
||||
}
|
||||
|
||||
// URL returns the URL endpoint used by the ServiceURL object.
|
||||
func (s ServiceURL) URL() url.URL {
|
||||
return s.client.URL()
|
||||
}
|
||||
|
||||
// String returns the URL as a string.
|
||||
func (s ServiceURL) String() string {
|
||||
u := s.URL()
|
||||
return u.String()
|
||||
}
|
||||
|
||||
// WithPipeline creates a new ServiceURL object identical to the source but with the specified request policy pipeline.
|
||||
func (s ServiceURL) WithPipeline(p pipeline.Pipeline) ServiceURL {
|
||||
return NewServiceURL(s.URL(), p)
|
||||
}
|
||||
|
||||
// NewContainerURL creates a new ContainerURL object by concatenating containerName to the end of
|
||||
// ServiceURL's URL. The new ContainerURL uses the same request policy pipeline as the ServiceURL.
|
||||
// To change the pipeline, create the ContainerURL and then call its WithPipeline method passing in the
|
||||
// desired pipeline object. Or, call this package's NewContainerURL instead of calling this object's
|
||||
// NewContainerURL method.
|
||||
func (s ServiceURL) NewContainerURL(containerName string) ContainerURL {
|
||||
containerURL := appendToURLPath(s.URL(), containerName)
|
||||
return NewContainerURL(containerURL, s.client.Pipeline())
|
||||
}
|
||||
|
||||
// NewRootContainerURL creates a new ContainerURL object by concatenating $root (RootContainerName)
|
||||
// to the end of ServiceURL's URL. The new ContainerURL uses the same request policy pipeline as the
|
||||
// ServiceURL. To change the pipeline, create the ContainerURL and then call its WithPipeline method
|
||||
// passing in the desired pipeline object. Or, call NewContainerURL instead of calling the NewContainerURL method.
|
||||
func (s ServiceURL) NewRootContainerURL() ContainerURL {
|
||||
containerURL := appendToURLPath(s.URL(), RootContainerName)
|
||||
return NewContainerURL(containerURL, s.client.Pipeline())
|
||||
}
|
||||
|
||||
// appendToURLPath appends a string to the end of a URL's path (prefixing the string with a '/' if required)
|
||||
func appendToURLPath(u url.URL, name string) url.URL {
|
||||
// e.g. "https://ms.com/a/b/?k1=v1&k2=v2#f"
|
||||
// When you call url.Parse() this is what you'll get:
|
||||
// Scheme: "https"
|
||||
// Opaque: ""
|
||||
// User: nil
|
||||
// Host: "ms.com"
|
||||
// Path: "/a/b/" This should start with a / and it might or might not have a trailing slash
|
||||
// RawPath: ""
|
||||
// ForceQuery: false
|
||||
// RawQuery: "k1=v1&k2=v2"
|
||||
// Fragment: "f"
|
||||
if len(u.Path) == 0 || u.Path[len(u.Path)-1] != '/' {
|
||||
u.Path += "/" // Append "/" to end before appending name
|
||||
}
|
||||
u.Path += name
|
||||
return u
|
||||
}
|
||||
|
||||
// ListContainers returns a single segment of containers starting from the specified Marker. Use an empty
|
||||
// Marker to start enumeration from the beginning. Container names are returned in lexicographic order.
|
||||
// After getting a segment, process it, and then call ListContainers again (passing the the previously-returned
|
||||
// Marker) to get the next segment. For more information, see
|
||||
// https://docs.microsoft.com/rest/api/storageservices/list-containers2.
|
||||
func (s ServiceURL) ListContainers(ctx context.Context, marker Marker, o ListContainersOptions) (*ListContainersResponse, error) {
|
||||
prefix, include, maxResults := o.pointers()
|
||||
return s.client.ListContainers(ctx, prefix, marker.val, maxResults, include, nil, nil)
|
||||
}
|
||||
|
||||
// ListContainersOptions defines options available when calling ListContainers.
|
||||
type ListContainersOptions struct {
|
||||
Detail ListContainersDetail // No IncludeType header is produced if ""
|
||||
Prefix string // No Prefix header is produced if ""
|
||||
MaxResults int32 // 0 means unspecified
|
||||
// TODO: update swagger to generate this type?
|
||||
}
|
||||
|
||||
func (o *ListContainersOptions) pointers() (prefix *string, include ListContainersIncludeType, maxResults *int32) {
|
||||
if o.Prefix != "" {
|
||||
prefix = &o.Prefix
|
||||
}
|
||||
if o.MaxResults != 0 {
|
||||
if o.MaxResults < 0 {
|
||||
panic("MaxResults must be >= 0")
|
||||
}
|
||||
maxResults = &o.MaxResults
|
||||
}
|
||||
include = ListContainersIncludeType(o.Detail.string())
|
||||
return
|
||||
}
|
||||
|
||||
// ListContainersDetail indicates what additional information the service should return with each container.
|
||||
type ListContainersDetail struct {
|
||||
// Tells the service whether to return metadata for each container.
|
||||
Metadata bool
|
||||
}
|
||||
|
||||
// string produces the Include query parameter's value.
|
||||
func (d *ListContainersDetail) string() string {
|
||||
items := make([]string, 0, 1)
|
||||
// NOTE: Multiple strings MUST be appended in alphabetic order or signing the string for authentication fails!
|
||||
if d.Metadata {
|
||||
items = append(items, string(ListContainersIncludeMetadata))
|
||||
}
|
||||
if len(items) > 0 {
|
||||
return strings.Join(items, ",")
|
||||
}
|
||||
return string(ListContainersIncludeNone)
|
||||
}
|
||||
|
||||
/*
|
||||
func (bsu BlobServiceURL) GetProperties(ctx context.Context) (*StorageServiceProperties, error) {
|
||||
return bsu.client.GetProperties(ctx, nil, nil)
|
||||
}
|
||||
|
||||
func (bsu BlobServiceURL) SetProperties(ctx context.Context, properties StorageServiceProperties) (*ServiceSetPropertiesResponse, error) {
|
||||
return bsu.client.SetProperties(ctx, properties, nil, nil)
|
||||
}
|
||||
|
||||
func (bsu BlobServiceURL) GetStats(ctx context.Context) (*StorageServiceStats, error) {
|
||||
return bsu.client.GetStats(ctx, nil, nil)
|
||||
}
|
||||
*/
|
80
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/uuid.go
generated
vendored
80
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/uuid.go
generated
vendored
|
@ -1,80 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// The UUID reserved variants.
|
||||
const (
|
||||
reservedNCS byte = 0x80
|
||||
reservedRFC4122 byte = 0x40
|
||||
reservedMicrosoft byte = 0x20
|
||||
reservedFuture byte = 0x00
|
||||
)
|
||||
|
||||
// A UUID representation compliant with specification in RFC 4122 document.
|
||||
type uuid [16]byte
|
||||
|
||||
// NewUUID returns a new uuid using RFC 4122 algorithm.
|
||||
func newUUID() (u uuid) {
|
||||
u = uuid{}
|
||||
// Set all bits to randomly (or pseudo-randomly) chosen values.
|
||||
_, err := rand.Read(u[:])
|
||||
if err != nil {
|
||||
panic("ran.Read failed")
|
||||
}
|
||||
u[8] = (u[8] | reservedRFC4122) & 0x7F // u.setVariant(ReservedRFC4122)
|
||||
|
||||
var version byte = 4
|
||||
u[6] = (u[6] & 0xF) | (version << 4) // u.setVersion(4)
|
||||
return
|
||||
}
|
||||
|
||||
// String returns an unparsed version of the generated UUID sequence.
|
||||
func (u uuid) String() string {
|
||||
return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:])
|
||||
}
|
||||
|
||||
// ParseUUID parses a string formatted as "003020100-0504-0706-0809-0a0b0c0d0e0f"
|
||||
// or "{03020100-0504-0706-0809-0a0b0c0d0e0f}" into a UUID.
|
||||
func parseUUID(uuidStr string) uuid {
|
||||
char := func(hexString string) byte {
|
||||
i, _ := strconv.ParseUint(hexString, 16, 8)
|
||||
return byte(i)
|
||||
}
|
||||
if uuidStr[0] == '{' {
|
||||
uuidStr = uuidStr[1:] // Skip over the '{'
|
||||
}
|
||||
// 03020100 - 05 04 - 07 06 - 08 09 - 0a 0b 0c 0d 0e 0f
|
||||
// 1 11 1 11 11 1 12 22 2 22 22 22 33 33 33
|
||||
// 01234567 8 90 12 3 45 67 8 90 12 3 45 67 89 01 23 45
|
||||
uuidVal := uuid{
|
||||
char(uuidStr[0:2]),
|
||||
char(uuidStr[2:4]),
|
||||
char(uuidStr[4:6]),
|
||||
char(uuidStr[6:8]),
|
||||
|
||||
char(uuidStr[9:11]),
|
||||
char(uuidStr[11:13]),
|
||||
|
||||
char(uuidStr[14:16]),
|
||||
char(uuidStr[16:18]),
|
||||
|
||||
char(uuidStr[19:21]),
|
||||
char(uuidStr[21:23]),
|
||||
|
||||
char(uuidStr[24:26]),
|
||||
char(uuidStr[26:28]),
|
||||
char(uuidStr[28:30]),
|
||||
char(uuidStr[30:32]),
|
||||
char(uuidStr[32:34]),
|
||||
char(uuidStr[34:36]),
|
||||
}
|
||||
return uuidVal
|
||||
}
|
||||
|
||||
func (u uuid) bytes() []byte {
|
||||
return u[:]
|
||||
}
|
3
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/version.go
generated
vendored
3
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/version.go
generated
vendored
|
@ -1,3 +0,0 @@
|
|||
package azblob
|
||||
|
||||
const serviceLibVersion = "0.1"
|
89
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_doc.go
generated
vendored
89
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_doc.go
generated
vendored
|
@ -1,89 +0,0 @@
|
|||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
||||
// Use of this source code is governed by an MIT
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package azblob allows you to manipulate Azure Storage containers and blobs objects.
|
||||
|
||||
URL Types
|
||||
|
||||
The most common types you'll work with are the XxxURL types. The methods of these types make requests
|
||||
against the Azure Storage Service.
|
||||
|
||||
- ServiceURL's methods perform operations on a storage account.
|
||||
- ContainerURL's methods perform operations on an account's container.
|
||||
- BlockBlobURL's methods perform operations on a container's block blob.
|
||||
- AppendBlobURL's methods perform operations on a container's append blob.
|
||||
- PageBlobURL's methods perform operations on a container's page blob.
|
||||
- BlobURL's methods perform operations on a container's blob regardless of the blob's type.
|
||||
|
||||
Internally, each XxxURL object contains a URL and a request pipeline. The URL indicates the endpoint where each HTTP
|
||||
request is sent and the pipeline indicates how the outgoing HTTP request and incoming HTTP response is processed.
|
||||
The pipeline specifies things like retry policies, logging, deserializaiton of HTTP response payloads, and more.
|
||||
|
||||
Pipelines are threadsafe and may be shared by multiple XxxURL objects. When you create a ServiceURL, you pass
|
||||
an initial pipeline. When you call ServiceURL's NewContainerURL method, the new ContainerURL object has its own
|
||||
URL but it shares the same pipeline as the parent ServiceURL object.
|
||||
|
||||
To work with a blob, call one of ContainerURL's 4 NewXxxBlobURL methods depending on how you want to treat the blob.
|
||||
To treat the blob as a block blob, append blob, or page blob, call NewBlockBlobURL, NewAppendBlobURL, or NewPageBlobURL
|
||||
respectively. These three types are all identical except for the methods they expose; each type exposes the methods
|
||||
relevant to the type of blob represented. If you're not sure how you want to treat a blob, you can call NewBlobURL;
|
||||
this returns an object whose methods are relevant to any kind of blob. When you call ContainerURL's NewXxxBlobURL,
|
||||
the new XxxBlobURL object has its own URL but it shares the same pipeline as the parent ContainerURL object. You
|
||||
can easily switch between blob types (method sets) by calling a ToXxxBlobURL method.
|
||||
|
||||
If you'd like to use a different pipeline with a ServiceURL, ContainerURL, or XxxBlobURL object, then call the XxxURL
|
||||
object's WithPipeline method passing in the desired pipeline. The WithPipeline methods create a new XxxURL object
|
||||
with the same URL as the original but with the specified pipeline.
|
||||
|
||||
Note that XxxURL objects use little memory, are goroutine-safe, and many objects share the same pipeline. This means that
|
||||
XxxURL objects share a lot of system resources making them very efficient.
|
||||
|
||||
All of XxxURL's methods that make HTTP requests return rich error handling information so you can discern network failures,
|
||||
transient failures, timeout failures, service failures, etc. See the StorageError interface for more information and an
|
||||
example of how to do deal with errors.
|
||||
|
||||
URL and Shared Access Signature Manipulation
|
||||
|
||||
The library includes a BlobURLParts type for deconstructing and reconstructing URLs. And you can use the there are types
|
||||
for generating and parsing Shared Access Signature (SAS)
|
||||
- Use the AccountSASSignatureValues type to create a SAS for a storage account
|
||||
- Use the BlobSASSignatureValues type to create a SAS for a container or blob.
|
||||
- Use the SASQueryParameters type to turn signature values in to query parameres or to parse query parameters.
|
||||
|
||||
To generate a SAS, you must use the SharedKeyCredential type.
|
||||
|
||||
Credentials
|
||||
|
||||
When creating a request pipeline, you must specify one of this package's credential types.
|
||||
- Call the NewAnonymousCredential function for requests that contain a Shared Access Signature (SAS) or for requests to public resources.
|
||||
- Call the NewSharedKeyCredential function (with an account name & key) to access any and all account resources. You must also use this
|
||||
to generate Shared Access Signatures.
|
||||
|
||||
HTTP Request Policy Factories
|
||||
|
||||
This package defines several request policy factories for use with the pipeline package.
|
||||
Most applications will not use these factories directly; instead, the NewPipeline
|
||||
function creates the these factories, initializes them (via the PipelineOptions type)
|
||||
and returns a pipeline object for use by the XxxURL objects.
|
||||
|
||||
However, for advanced scenarios, developers can access these policy factory directly
|
||||
and even create their own and then construct their own pipeline in order to affect HTTP
|
||||
requests and responses performed by the XxxURL objects. For example, developers can
|
||||
introduce their own logging, random failures, request recording & playback for fast
|
||||
testing, HTTP request pacing, alternate retry mechanisms, metering, metrics, etc. The
|
||||
possibilities are endless!
|
||||
|
||||
Below are the request pipeline policy factory functions that are provided with this
|
||||
package:
|
||||
- NewRetryPolicyFactory Enables rich retry semantics for failed HTTP requests
|
||||
- NewRequestLogPolicyFactory Enables rich logging support for HTTP requests/responses & failures
|
||||
- NewTelemetryPolicyFactory Enables simple modification of the HTTP request's User-Agent header so each request reports the SDK version & language/runtime making the requests
|
||||
- NewUniqueRequestIDPolicyFactory Adds a x-ms-client-request-id header with a unique UUID value to an HTTP request to help with diagnosing failures
|
||||
|
||||
Also, note that all the NewXxxCredential functions return request policy factory objects which get injected into the pipeline.
|
||||
*/
|
||||
package azblob
|
||||
|
||||
// TokenCredential Use this to access resources using Role-Based Access Control (RBAC).
|
1028
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_examples_test.go
generated
vendored
1028
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_examples_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
204
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_policy_retry_test.go
generated
vendored
204
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_policy_retry_test.go
generated
vendored
|
@ -1,204 +0,0 @@
|
|||
package azblob_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
chk "gopkg.in/check.v1"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"github.com/Azure/azure-storage-blob-go/2016-05-31/azblob"
|
||||
)
|
||||
|
||||
// For testing docs, see: https://labix.org/gocheck
|
||||
// To test a specific test: go test -check.f MyTestSuite
|
||||
|
||||
type retryTestScenario int32
|
||||
|
||||
const (
|
||||
// Retry until success. Max reties hit. Operation time out prevents additional retries
|
||||
retryTestScenarioRetryUntilSuccess retryTestScenario = 1
|
||||
retryTestScenarioRetryUntilOperationCancel retryTestScenario = 2
|
||||
retryTestScenarioRetryUntilMaxRetries retryTestScenario = 3
|
||||
)
|
||||
|
||||
func (s *aztestsSuite) TestRetryTestScenarioUntilSuccess(c *chk.C) {
|
||||
testRetryTestScenario(c, retryTestScenarioRetryUntilSuccess)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestRetryTestScenarioUntilOperationCancel(c *chk.C) {
|
||||
testRetryTestScenario(c, retryTestScenarioRetryUntilOperationCancel)
|
||||
}
|
||||
func (s *aztestsSuite) TestRetryTestScenarioUntilMaxRetries(c *chk.C) {
|
||||
testRetryTestScenario(c, retryTestScenarioRetryUntilMaxRetries)
|
||||
}
|
||||
func newRetryTestPolicyFactory(c *chk.C, scenario retryTestScenario, maxRetries int32, cancel context.CancelFunc) *retryTestPolicyFactory {
|
||||
return &retryTestPolicyFactory{c: c, scenario: scenario, maxRetries: maxRetries, cancel: cancel}
|
||||
}
|
||||
|
||||
type retryTestPolicyFactory struct {
|
||||
c *chk.C
|
||||
scenario retryTestScenario
|
||||
maxRetries int32
|
||||
cancel context.CancelFunc
|
||||
try int32
|
||||
}
|
||||
|
||||
func (f *retryTestPolicyFactory) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
f.try = 0 // Reset this for each test
|
||||
return &retryTestPolicy{factory: f, next: next}
|
||||
}
|
||||
|
||||
type retryTestPolicy struct {
|
||||
next pipeline.Policy
|
||||
factory *retryTestPolicyFactory
|
||||
}
|
||||
|
||||
type retryError struct {
|
||||
temporary, timeout bool
|
||||
}
|
||||
|
||||
func (e *retryError) Temporary() bool { return e.temporary }
|
||||
func (e *retryError) Timeout() bool { return e.timeout }
|
||||
func (e *retryError) Error() string {
|
||||
return fmt.Sprintf("Temporary=%t, Timeout=%t", e.Temporary(), e.Timeout())
|
||||
}
|
||||
|
||||
type httpResponse struct {
|
||||
response *http.Response
|
||||
}
|
||||
|
||||
func (r *httpResponse) Response() *http.Response { return r.response }
|
||||
|
||||
func (p *retryTestPolicy) Do(ctx context.Context, request pipeline.Request) (response pipeline.Response, err error) {
|
||||
c := p.factory.c
|
||||
p.factory.try++ // Increment the try
|
||||
c.Assert(p.factory.try <= p.factory.maxRetries, chk.Equals, true) // Ensure # of tries < MaxRetries
|
||||
req := request.Request
|
||||
|
||||
// Validate the expected pre-conditions for each try
|
||||
expectedHost := "PrimaryDC"
|
||||
if p.factory.try%2 == 0 {
|
||||
if p.factory.scenario != retryTestScenarioRetryUntilSuccess || p.factory.try <= 4 {
|
||||
expectedHost = "SecondaryDC"
|
||||
}
|
||||
}
|
||||
c.Assert(req.URL.Host, chk.Equals, expectedHost) // Ensure we got the expected primary/secondary DC
|
||||
|
||||
// Ensure that any headers & query parameters this method adds (later) are removed/reset for each try
|
||||
c.Assert(req.Header.Get("TestHeader"), chk.Equals, "") // Ensure our "TestHeader" is not in the HTTP request
|
||||
values := req.URL.Query()
|
||||
c.Assert(len(values["TestQueryParam"]), chk.Equals, 0) // TestQueryParam shouldn't be in the HTTP request
|
||||
|
||||
if seeker, ok := req.Body.(io.ReadSeeker); !ok {
|
||||
c.Fail() // Body must be an io.ReadSeeker
|
||||
} else {
|
||||
pos, err := seeker.Seek(0, io.SeekCurrent)
|
||||
c.Assert(err, chk.IsNil) // Ensure that body was seekable
|
||||
c.Assert(pos, chk.Equals, int64(0)) // Ensure body seeked back to position 0
|
||||
}
|
||||
|
||||
// Add a query param & header; these not be here on the next try
|
||||
values["TestQueryParam"] = []string{"TestQueryParamValue"}
|
||||
req.Header.Set("TestHeader", "TestValue") // Add a header this not exist with each try
|
||||
b := []byte{0}
|
||||
n, err := req.Body.Read(b)
|
||||
c.Assert(n, chk.Equals, 1) // Read failed
|
||||
|
||||
switch p.factory.scenario {
|
||||
case retryTestScenarioRetryUntilSuccess:
|
||||
switch p.factory.try {
|
||||
case 1:
|
||||
if deadline, ok := ctx.Deadline(); ok {
|
||||
time.Sleep(time.Until(deadline) + time.Second) // Let the context timeout expire
|
||||
}
|
||||
err = ctx.Err()
|
||||
case 2:
|
||||
err = &retryError{temporary: true}
|
||||
case 3:
|
||||
err = &retryError{timeout: true}
|
||||
case 4:
|
||||
response = &httpResponse{response: &http.Response{StatusCode: http.StatusNotFound}}
|
||||
case 5:
|
||||
err = &retryError{temporary: true} // These attempts all fail but we're making sure we never see the secondary DC again
|
||||
case 6:
|
||||
response = &httpResponse{response: &http.Response{StatusCode: http.StatusOK}} // Stop retries with valid response
|
||||
default:
|
||||
c.Fail() // Retries should have stopped so we shouldn't get here
|
||||
}
|
||||
case retryTestScenarioRetryUntilOperationCancel:
|
||||
switch p.factory.try {
|
||||
case 1:
|
||||
p.factory.cancel()
|
||||
err = context.Canceled
|
||||
default:
|
||||
c.Fail() // Retries should have stopped so we shouldn't get here
|
||||
}
|
||||
case retryTestScenarioRetryUntilMaxRetries:
|
||||
err = &retryError{temporary: true} // Keep retrying until maxRetries is hit
|
||||
}
|
||||
return response, err // Return the response & err
|
||||
}
|
||||
|
||||
func testRetryTestScenario(c *chk.C, scenario retryTestScenario) {
|
||||
u, _ := url.Parse("http://PrimaryDC")
|
||||
retryOptions := azblob.RetryOptions{
|
||||
Policy: azblob.RetryPolicyExponential,
|
||||
MaxTries: 6,
|
||||
TryTimeout: 2 * time.Second,
|
||||
RetryDelay: 1 * time.Second,
|
||||
MaxRetryDelay: 4 * time.Second,
|
||||
RetryReadsFromSecondaryHost: "SecondaryDC",
|
||||
}
|
||||
ctx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(ctx, 64 /*2^MaxTries(6)*/ *retryOptions.TryTimeout)
|
||||
retrytestPolicyFactory := newRetryTestPolicyFactory(c, scenario, retryOptions.MaxTries, cancel)
|
||||
factories := [...]pipeline.Factory{
|
||||
azblob.NewRetryPolicyFactory(retryOptions),
|
||||
retrytestPolicyFactory,
|
||||
}
|
||||
p := pipeline.NewPipeline(factories[:], pipeline.Options{})
|
||||
request, err := pipeline.NewRequest(http.MethodGet, *u, strings.NewReader("TestData"))
|
||||
response, err := p.Do(ctx, nil, request)
|
||||
switch scenario {
|
||||
case retryTestScenarioRetryUntilSuccess:
|
||||
if err != nil || response == nil || response.Response() == nil || response.Response().StatusCode != http.StatusOK {
|
||||
c.Fail() // Operation didn't run to success
|
||||
}
|
||||
case retryTestScenarioRetryUntilMaxRetries:
|
||||
c.Assert(err, chk.NotNil) // Ensure we ended with an error
|
||||
c.Assert(response, chk.IsNil) // Ensure we ended without a valid response
|
||||
c.Assert(retrytestPolicyFactory.try, chk.Equals, retryOptions.MaxTries) // Ensure the operation ends with the exact right number of tries
|
||||
case retryTestScenarioRetryUntilOperationCancel:
|
||||
c.Assert(err, chk.Equals, context.Canceled) // Ensure we ended due to cancellation
|
||||
c.Assert(response, chk.IsNil) // Ensure we ended without a valid response
|
||||
c.Assert(retrytestPolicyFactory.try <= retryOptions.MaxTries, chk.Equals, true) // Ensure we didn't end due to reaching max tries
|
||||
}
|
||||
cancel()
|
||||
}
|
||||
|
||||
/*
|
||||
Fail primary; retry should be on secondary URL - maybe do this twice
|
||||
Fail secondary; and never see primary again
|
||||
|
||||
Make sure any mutations are lost on each retry
|
||||
Make sure body is reset on each retry
|
||||
|
||||
Timeout a try; should retry (unless no more)
|
||||
timeout an operation; should not retry
|
||||
check timeout query param; should be try timeout
|
||||
|
||||
Return Temporary() = true; should retry (unless max)
|
||||
Return Timeout() true; should retry (unless max)
|
||||
|
||||
Secondary try returns 404; no more tries against secondary
|
||||
|
||||
error where Temporary() and Timeout() return false; no retry
|
||||
error where Temporary() & Timeout don't exist; no retry
|
||||
no error; no retry; return success, nil
|
||||
*/
|
5498
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_test.go
generated
vendored
5498
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
|
@ -1,41 +0,0 @@
|
|||
package azblob_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-storage-blob-go/2016-05-31/azblob"
|
||||
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
|
||||
)
|
||||
|
||||
type AppendBlobURLSuite struct{}
|
||||
|
||||
var _ = chk.Suite(&AppendBlobURLSuite{})
|
||||
|
||||
func (b *AppendBlobURLSuite) TestAppendBlock(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blob := container.NewAppendBlobURL(generateBlobName())
|
||||
|
||||
resp, err := blob.Create(context.Background(), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.StatusCode(), chk.Equals, 201)
|
||||
|
||||
appendResp, err := blob.AppendBlock(context.Background(), getReaderToRandomBytes(1024), azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(appendResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(appendResp.BlobAppendOffset(), chk.Equals, "0")
|
||||
c.Assert(appendResp.BlobCommittedBlockCount(), chk.Equals, "1")
|
||||
c.Assert(appendResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(appendResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(appendResp.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
c.Assert(appendResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(appendResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(appendResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
appendResp, err = blob.AppendBlock(context.Background(), getReaderToRandomBytes(1024), azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(appendResp.BlobAppendOffset(), chk.Equals, "1024")
|
||||
c.Assert(appendResp.BlobCommittedBlockCount(), chk.Equals, "2")
|
||||
}
|
364
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_url_blob_test.go
generated
vendored
364
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_url_blob_test.go
generated
vendored
|
@ -1,364 +0,0 @@
|
|||
package azblob_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-storage-blob-go/2016-05-31/azblob"
|
||||
|
||||
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
|
||||
)
|
||||
|
||||
type BlobURLSuite struct{}
|
||||
|
||||
var _ = chk.Suite(&BlobURLSuite{})
|
||||
|
||||
func getReaderToRandomBytes(n int) *bytes.Reader {
|
||||
r, _ := getRandomDataAndReader(n)
|
||||
return r
|
||||
}
|
||||
|
||||
func getRandomDataAndReader(n int) (*bytes.Reader, []byte) {
|
||||
data := make([]byte, n, n)
|
||||
for i := 0; i < n; i++ {
|
||||
data[i] = byte(i)
|
||||
}
|
||||
return bytes.NewReader(data), data
|
||||
}
|
||||
|
||||
func (b *BlobURLSuite) TestCreateDelete(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blob := container.NewBlockBlobURL(generateBlobName())
|
||||
|
||||
putResp, err := blob.PutBlob(context.Background(), nil, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(putResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(putResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(putResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(putResp.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
c.Assert(putResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(putResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(putResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
delResp, err := blob.Delete(context.Background(), azblob.DeleteSnapshotsOptionNone, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(delResp.Response().StatusCode, chk.Equals, 202)
|
||||
c.Assert(delResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(delResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(delResp.Date().IsZero(), chk.Equals, false)
|
||||
}
|
||||
|
||||
func (b *BlobURLSuite) TestGetSetProperties(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blob, _ := createNewBlockBlob(c, container)
|
||||
|
||||
properties := azblob.BlobHTTPHeaders{
|
||||
ContentType: "mytype",
|
||||
ContentLanguage: "martian",
|
||||
}
|
||||
setResp, err := blob.SetProperties(context.Background(), properties, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(setResp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(setResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(setResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(setResp.BlobSequenceNumber(), chk.Equals, "")
|
||||
c.Assert(setResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(setResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(setResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
/*getResp, err := blob.GetProperties(context.Background(), BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(getResp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(getResp.ContentType(), chk.Equals, properties.ContentType)
|
||||
c.Assert(getResp.ContentLanguage(), chk.Equals, properties.ContentLanguage)
|
||||
verifyDateResp(c, getResp.LastModified, false)
|
||||
c.Assert(getResp.BlobType(), chk.Not(chk.Equals), "")
|
||||
verifyDateResp(c, getResp.CopyCompletionTime, true)
|
||||
c.Assert(getResp.CopyStatusDescription(), chk.Equals, "")
|
||||
c.Assert(getResp.CopyID(), chk.Equals, "")
|
||||
c.Assert(getResp.CopyProgress(), chk.Equals, "")
|
||||
c.Assert(getResp.CopySource(), chk.Equals, "")
|
||||
c.Assert(getResp.CopyStatus().IsZero(), chk.Equals, true)
|
||||
c.Assert(getResp.IsIncrementalCopy(), chk.Equals, "")
|
||||
c.Assert(getResp.LeaseDuration().IsZero(), chk.Equals, true)
|
||||
c.Assert(getResp.LeaseState(), chk.Equals, LeaseStateAvailable)
|
||||
c.Assert(getResp.LeaseStatus(), chk.Equals, LeaseStatusUnlocked)
|
||||
c.Assert(getResp.ContentLength(), chk.Not(chk.Equals), "")
|
||||
c.Assert(getResp.ETag(), chk.Not(chk.Equals), ETagNone)
|
||||
c.Assert(getResp.ContentMD5(), chk.Equals, "")
|
||||
c.Assert(getResp.ContentEncoding(), chk.Equals, "")
|
||||
c.Assert(getResp.ContentDisposition(), chk.Equals, "")
|
||||
c.Assert(getResp.CacheControl(), chk.Equals, "")
|
||||
c.Assert(getResp.BlobSequenceNumber(), chk.Equals, "")
|
||||
c.Assert(getResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(getResp.Version(), chk.Not(chk.Equals), "")
|
||||
verifyDateResp(c, getResp.Date, false)
|
||||
c.Assert(getResp.AcceptRanges(), chk.Equals, "bytes")
|
||||
c.Assert(getResp.BlobCommittedBlockCount(), chk.Equals, "")
|
||||
*/
|
||||
}
|
||||
|
||||
func (b *BlobURLSuite) TestGetSetMetadata(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blob, _ := createNewBlockBlob(c, container)
|
||||
|
||||
metadata := azblob.Metadata{
|
||||
"foo": "foovalue",
|
||||
"bar": "barvalue",
|
||||
}
|
||||
setResp, err := blob.SetMetadata(context.Background(), metadata, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(setResp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(setResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(setResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(setResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(setResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
getResp, err := blob.GetPropertiesAndMetadata(context.Background(), azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(getResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(getResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(getResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(getResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(getResp.Date().IsZero(), chk.Equals, false)
|
||||
md := getResp.NewMetadata()
|
||||
c.Assert(md, chk.DeepEquals, metadata)
|
||||
}
|
||||
|
||||
func (b *BlobURLSuite) TestCopy(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
sourceBlob, _ := createNewBlockBlob(c, container)
|
||||
_, err := sourceBlob.PutBlob(context.Background(), getReaderToRandomBytes(2048), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
destBlob, _ := createNewBlockBlob(c, container)
|
||||
copyResp, err := destBlob.StartCopy(context.Background(), sourceBlob.URL(), nil, azblob.BlobAccessConditions{}, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(copyResp.Response().StatusCode, chk.Equals, 202)
|
||||
c.Assert(copyResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(copyResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(copyResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(copyResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(copyResp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(copyResp.CopyID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(copyResp.CopyStatus(), chk.Not(chk.Equals), "")
|
||||
|
||||
abortResp, err := destBlob.AbortCopy(context.Background(), copyResp.CopyID(), azblob.LeaseAccessConditions{})
|
||||
// small copy completes before we have time to abort so check for failure case
|
||||
c.Assert(err, chk.NotNil)
|
||||
c.Assert(abortResp, chk.IsNil)
|
||||
se, ok := err.(azblob.StorageError)
|
||||
c.Assert(ok, chk.Equals, true)
|
||||
c.Assert(se.Response().StatusCode, chk.Equals, http.StatusConflict)
|
||||
}
|
||||
|
||||
func (b *BlobURLSuite) TestSnapshot(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blob, _ := createNewBlockBlob(c, container)
|
||||
|
||||
resp, err := blob.CreateSnapshot(context.Background(), nil, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(resp.Snapshot().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
blobs, err := container.ListBlobs(context.Background(), azblob.Marker{}, azblob.ListBlobsOptions{Details: azblob.BlobListingDetails{Snapshots: true}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(blobs.Blobs.Blob, chk.HasLen, 2)
|
||||
|
||||
_, err = blob.Delete(context.Background(), azblob.DeleteSnapshotsOptionOnly, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
blobs, err = container.ListBlobs(context.Background(), azblob.Marker{}, azblob.ListBlobsOptions{Details: azblob.BlobListingDetails{Snapshots: true}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(blobs.Blobs.Blob, chk.HasLen, 1)
|
||||
}
|
||||
|
||||
// Copied from policy_unique_request_id.go
|
||||
type uuid [16]byte
|
||||
|
||||
// The UUID reserved variants.
|
||||
const (
|
||||
reservedNCS byte = 0x80
|
||||
reservedRFC4122 byte = 0x40
|
||||
reservedMicrosoft byte = 0x20
|
||||
reservedFuture byte = 0x00
|
||||
)
|
||||
|
||||
func newUUID() (u uuid) {
|
||||
u = uuid{}
|
||||
// Set all bits to randomly (or pseudo-randomly) chosen values.
|
||||
_, err := rand.Read(u[:])
|
||||
if err != nil {
|
||||
panic("ran.Read failed")
|
||||
}
|
||||
u[8] = (u[8] | reservedRFC4122) & 0x7F // u.setVariant(ReservedRFC4122)
|
||||
|
||||
var version byte = 4
|
||||
u[6] = (u[6] & 0xF) | (version << 4) // u.setVersion(4)
|
||||
return
|
||||
}
|
||||
|
||||
func (u uuid) String() string {
|
||||
return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:])
|
||||
}
|
||||
|
||||
func (b *BlobURLSuite) TestLeaseAcquireRelease(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blob, _ := createNewBlockBlob(c, container)
|
||||
|
||||
resp, err := blob.AcquireLease(context.Background(), "", 15, azblob.HTTPAccessConditions{})
|
||||
leaseID := resp.LeaseID()
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.LeaseID(), chk.Equals, leaseID)
|
||||
c.Assert(resp.LeaseTime(), chk.Equals, int32(-1))
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
resp, err = blob.ReleaseLease(context.Background(), leaseID, azblob.HTTPAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.LeaseID(), chk.Equals, "")
|
||||
c.Assert(resp.LeaseTime(), chk.Equals, int32(-1))
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
}
|
||||
|
||||
func (b *BlobURLSuite) TestLeaseRenewChangeBreak(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blob, _ := createNewBlockBlob(c, container)
|
||||
|
||||
resp, err := blob.AcquireLease(context.Background(), newUUID().String(), 15, azblob.HTTPAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
leaseID := resp.LeaseID()
|
||||
|
||||
resp, err = blob.ChangeLease(context.Background(), leaseID, newUUID().String(), azblob.HTTPAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
newID := resp.LeaseID()
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.LeaseID(), chk.Equals, newID)
|
||||
c.Assert(resp.LeaseTime(), chk.Equals, int32(-1))
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
resp, err = blob.RenewLease(context.Background(), newID, azblob.HTTPAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.LeaseID(), chk.Equals, newID)
|
||||
c.Assert(resp.LeaseTime(), chk.Equals, int32(-1))
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
resp, err = blob.BreakLease(context.Background(), 5, azblob.HTTPAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 202)
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.LeaseID(), chk.Equals, "")
|
||||
c.Assert(resp.LeaseTime(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
resp, err = blob.ReleaseLease(context.Background(), newID, azblob.HTTPAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
}
|
||||
|
||||
func (b *BlobURLSuite) TestGetBlobRange(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blob, _ := createNewBlockBlob(c, container)
|
||||
contentR, contentD := getRandomDataAndReader(2048)
|
||||
_, err := blob.PutBlob(context.Background(), contentR, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blob.GetBlob(context.Background(), azblob.BlobRange{Offset: 0, Count: 1024}, azblob.BlobAccessConditions{}, false)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.ContentLength(), chk.Equals, int64(1024))
|
||||
|
||||
download, err := ioutil.ReadAll(resp.Response().Body)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(download, chk.DeepEquals, contentD[:1024])
|
||||
|
||||
resp, err = blob.GetBlob(context.Background(), azblob.BlobRange{Offset: 1024}, azblob.BlobAccessConditions{}, false)
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.ContentLength(), chk.Equals, int64(1024))
|
||||
|
||||
download, err = ioutil.ReadAll(resp.Response().Body)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(download, chk.DeepEquals, contentD[1024:])
|
||||
|
||||
c.Assert(resp.AcceptRanges(), chk.Equals, "bytes")
|
||||
c.Assert(resp.BlobCommittedBlockCount(), chk.Equals, "")
|
||||
c.Assert(resp.BlobContentMD5(), chk.Not(chk.Equals), [md5.Size]byte{})
|
||||
c.Assert(resp.BlobSequenceNumber(), chk.Equals, "")
|
||||
c.Assert(resp.BlobType(), chk.Equals, azblob.BlobBlockBlob)
|
||||
c.Assert(resp.CacheControl(), chk.Equals, "")
|
||||
c.Assert(resp.ContentDisposition(), chk.Equals, "")
|
||||
c.Assert(resp.ContentEncoding(), chk.Equals, "")
|
||||
c.Assert(resp.ContentMD5(), chk.Equals, [md5.Size]byte{})
|
||||
c.Assert(resp.ContentRange(), chk.Equals, "bytes 1024-2047/2048")
|
||||
c.Assert(resp.ContentType(), chk.Equals, "application/octet-stream")
|
||||
c.Assert(resp.CopyCompletionTime().IsZero(), chk.Equals, true)
|
||||
c.Assert(resp.CopyID(), chk.Equals, "")
|
||||
c.Assert(resp.CopyProgress(), chk.Equals, "")
|
||||
c.Assert(resp.CopySource(), chk.Equals, "")
|
||||
c.Assert(resp.CopyStatus(), chk.Equals, azblob.CopyStatusNone)
|
||||
c.Assert(resp.CopyStatusDescription(), chk.Equals, "")
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.LeaseDuration(), chk.Equals, azblob.LeaseDurationNone)
|
||||
c.Assert(resp.LeaseState(), chk.Equals, azblob.LeaseStateAvailable)
|
||||
c.Assert(resp.LeaseStatus(), chk.Equals, azblob.LeaseStatusUnlocked)
|
||||
c.Assert(resp.NewMetadata(), chk.DeepEquals, azblob.Metadata{})
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 206)
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
package azblob_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
|
||||
"github.com/Azure/azure-storage-blob-go/2016-05-31/azblob"
|
||||
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
|
||||
)
|
||||
|
||||
type BlockBlobURLSuite struct{}
|
||||
|
||||
var _ = chk.Suite(&BlockBlobURLSuite{})
|
||||
|
||||
func (b *BlockBlobURLSuite) TestPutGetBlocks(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blob := container.NewBlockBlobURL(generateBlobName())
|
||||
|
||||
blockID := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%6d", 0)))
|
||||
|
||||
putResp, err := blob.PutBlock(context.Background(), blockID, getReaderToRandomBytes(1024), azblob.LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(putResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(putResp.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
c.Assert(putResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(putResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(putResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
blockList, err := blob.GetBlockList(context.Background(), azblob.BlockListAll, azblob.LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(blockList.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(blockList.LastModified().IsZero(), chk.Equals, true)
|
||||
c.Assert(blockList.ETag(), chk.Equals, azblob.ETagNone)
|
||||
c.Assert(blockList.ContentType(), chk.Not(chk.Equals), "")
|
||||
c.Assert(blockList.BlobContentLength(), chk.Equals, int64(-1))
|
||||
c.Assert(blockList.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(blockList.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(blockList.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(blockList.CommittedBlocks, chk.HasLen, 0)
|
||||
c.Assert(blockList.UncommittedBlocks, chk.HasLen, 1)
|
||||
|
||||
listResp, err := blob.PutBlockList(context.Background(), []string{blockID}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(listResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(listResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(listResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(listResp.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
c.Assert(listResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(listResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(listResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
blockList, err = blob.GetBlockList(context.Background(), azblob.BlockListAll, azblob.LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(blockList.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(blockList.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(blockList.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(blockList.ContentType(), chk.Not(chk.Equals), "")
|
||||
c.Assert(blockList.BlobContentLength(), chk.Equals, int64(1024))
|
||||
c.Assert(blockList.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(blockList.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(blockList.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(blockList.CommittedBlocks, chk.HasLen, 1)
|
||||
c.Assert(blockList.UncommittedBlocks, chk.HasLen, 0)
|
||||
}
|
335
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_url_container_test.go
generated
vendored
335
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_url_container_test.go
generated
vendored
|
@ -1,335 +0,0 @@
|
|||
package azblob_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-storage-blob-go/2016-05-31/azblob"
|
||||
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
|
||||
)
|
||||
|
||||
type ContainerURLSuite struct{}
|
||||
|
||||
var _ = chk.Suite(&ContainerURLSuite{})
|
||||
|
||||
func delContainer(c *chk.C, container azblob.ContainerURL) {
|
||||
resp, err := container.Delete(context.Background(), azblob.ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 202)
|
||||
}
|
||||
|
||||
func (s *ContainerURLSuite) TestCreateDelete(c *chk.C) {
|
||||
containerName := generateContainerName()
|
||||
sa := getBSU()
|
||||
container := sa.NewContainerURL(containerName)
|
||||
|
||||
cResp, err := container.Create(context.Background(), nil, azblob.PublicAccessNone)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(cResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(cResp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(cResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(cResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(cResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(cResp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
containers, err := sa.ListContainers(context.Background(), azblob.Marker{}, azblob.ListContainersOptions{Prefix: containerPrefix})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(containers.Containers, chk.HasLen, 1)
|
||||
c.Assert(containers.Containers[0].Name, chk.Equals, containerName)
|
||||
|
||||
dResp, err := container.Delete(context.Background(), azblob.ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(dResp.Response().StatusCode, chk.Equals, 202)
|
||||
c.Assert(dResp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(dResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(dResp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
containers, err = sa.ListContainers(context.Background(), azblob.Marker{}, azblob.ListContainersOptions{Prefix: containerPrefix})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(containers.Containers, chk.HasLen, 0)
|
||||
}
|
||||
|
||||
/*func (s *ContainerURLSuite) TestGetProperties(c *chk.C) {
|
||||
container := getContainer(c)
|
||||
defer delContainer(c, container)
|
||||
|
||||
props, err := container.GetProperties(context.Background(), LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(props.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(props.BlobPublicAccess().IsZero(), chk.Equals, true)
|
||||
c.Assert(props.ETag(), chk.Not(chk.Equals), ETagNone)
|
||||
verifyDateResp(c, props.LastModified, false)
|
||||
}*/
|
||||
|
||||
func (s *ContainerURLSuite) TestGetSetPermissions(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
now := time.Now().UTC().Truncate(10000 * time.Millisecond) // Enough resolution
|
||||
permissions := []azblob.SignedIdentifier{{
|
||||
ID: "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=",
|
||||
AccessPolicy: azblob.AccessPolicy{
|
||||
Start: now,
|
||||
Expiry: now.Add(5 * time.Minute).UTC(),
|
||||
Permission: "rw",
|
||||
},
|
||||
}}
|
||||
sResp, err := container.SetPermissions(context.Background(), azblob.PublicAccessNone, permissions, azblob.ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(sResp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(sResp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(sResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(sResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(sResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(sResp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
gResp, err := container.GetPermissions(context.Background(), azblob.LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(gResp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(gResp.BlobPublicAccess(), chk.Equals, azblob.PublicAccessNone)
|
||||
c.Assert(gResp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(gResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(gResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(gResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(gResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(gResp.Value, chk.HasLen, 1)
|
||||
c.Assert(gResp.Value[0], chk.DeepEquals, permissions[0])
|
||||
}
|
||||
|
||||
func (s *ContainerURLSuite) TestGetSetMetadata(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
// TODO: add test case ensuring that we get back case-sensitive keys
|
||||
md := azblob.Metadata{
|
||||
"foo": "FooValuE",
|
||||
"bar": "bArvaLue",
|
||||
}
|
||||
sResp, err := container.SetMetadata(context.Background(), md, azblob.ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(sResp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(sResp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(sResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(sResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(sResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(sResp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
gResp, err := container.GetPropertiesAndMetadata(context.Background(), azblob.LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(gResp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(gResp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(gResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(gResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(gResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(gResp.Version(), chk.Not(chk.Equals), "")
|
||||
nmd := gResp.NewMetadata()
|
||||
c.Assert(nmd, chk.DeepEquals, md)
|
||||
}
|
||||
|
||||
func (s *ContainerURLSuite) TestListBlobs(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blobs, err := container.ListBlobs(context.Background(), azblob.Marker{}, azblob.ListBlobsOptions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(blobs.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(blobs.ContentType(), chk.Not(chk.Equals), "")
|
||||
c.Assert(blobs.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(blobs.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(blobs.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(blobs.Blobs.Blob, chk.HasLen, 0)
|
||||
c.Assert(blobs.ServiceEndpoint, chk.NotNil)
|
||||
c.Assert(blobs.ContainerName, chk.NotNil)
|
||||
c.Assert(blobs.Prefix, chk.Equals, "")
|
||||
c.Assert(blobs.Marker, chk.Equals, "")
|
||||
c.Assert(blobs.MaxResults, chk.Equals, int32(0))
|
||||
c.Assert(blobs.Delimiter, chk.Equals, "")
|
||||
|
||||
blob := container.NewBlockBlobURL(generateBlobName())
|
||||
|
||||
_, err = blob.PutBlob(context.Background(), nil, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
blobs, err = container.ListBlobs(context.Background(), azblob.Marker{}, azblob.ListBlobsOptions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(blobs.Blobs.BlobPrefix, chk.HasLen, 0)
|
||||
c.Assert(blobs.Blobs.Blob, chk.HasLen, 1)
|
||||
c.Assert(blobs.Blobs.Blob[0].Name, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Snapshot.IsZero(), chk.Equals, true)
|
||||
c.Assert(blobs.Blobs.Blob[0].Metadata, chk.HasLen, 0)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.LastModified, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.Etag, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.ContentLength, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.ContentType, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.ContentEncoding, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.ContentLanguage, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.ContentMD5, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.ContentDisposition, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.CacheControl, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.BlobSequenceNumber, chk.IsNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.BlobType, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.LeaseStatus, chk.Equals, azblob.LeaseStatusUnlocked)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.LeaseState, chk.Equals, azblob.LeaseStateAvailable)
|
||||
c.Assert(string(blobs.Blobs.Blob[0].Properties.LeaseDuration), chk.Equals, "")
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.CopyID, chk.IsNil)
|
||||
c.Assert(string(blobs.Blobs.Blob[0].Properties.CopyStatus), chk.Equals, "")
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.CopySource, chk.IsNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.CopyProgress, chk.IsNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.CopyCompletionTime, chk.IsNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.CopyStatusDescription, chk.IsNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.ServerEncrypted, chk.NotNil)
|
||||
c.Assert(blobs.Blobs.Blob[0].Properties.IncrementalCopy, chk.IsNil)
|
||||
}
|
||||
|
||||
func (s *ContainerURLSuite) TestLeaseAcquireRelease(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
resp, err := container.AcquireLease(context.Background(), "", 15, azblob.HTTPAccessConditions{})
|
||||
leaseID := resp.LeaseID()
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.LeaseID(), chk.Equals, leaseID)
|
||||
c.Assert(resp.LeaseTime(), chk.Equals, int32(-1))
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
resp, err = container.ReleaseLease(context.Background(), leaseID, azblob.HTTPAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.LeaseID(), chk.Equals, "")
|
||||
c.Assert(resp.LeaseTime(), chk.Equals, int32(-1))
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
}
|
||||
|
||||
func (s *ContainerURLSuite) TestLeaseRenewChangeBreak(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
resp, err := container.AcquireLease(context.Background(), "", 15, azblob.HTTPAccessConditions{})
|
||||
leaseID := resp.LeaseID()
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
newID := newUUID().String()
|
||||
resp, err = container.ChangeLease(context.Background(), leaseID, newID, azblob.HTTPAccessConditions{})
|
||||
newID = resp.LeaseID()
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.LeaseID(), chk.Equals, newID)
|
||||
c.Assert(resp.LeaseTime(), chk.Equals, int32(-1))
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
resp, err = container.RenewLease(context.Background(), newID, azblob.HTTPAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.LeaseID(), chk.Equals, newID)
|
||||
c.Assert(resp.LeaseTime(), chk.Equals, int32(-1))
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
resp, err = container.BreakLease(context.Background(), 5, azblob.HTTPAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 202)
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.LeaseID(), chk.Equals, "")
|
||||
c.Assert(resp.LeaseTime(), chk.Not(chk.Equals), int32(-1))
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
resp, err = container.ReleaseLease(context.Background(), newID, azblob.HTTPAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
}
|
||||
|
||||
func (s *ContainerURLSuite) TestListBlobsPaged(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
|
||||
const numBlobs = 4
|
||||
const maxResultsPerPage = 2
|
||||
|
||||
blobs := make([]azblob.BlockBlobURL, numBlobs)
|
||||
for i := 0; i < numBlobs; i++ {
|
||||
blobs[i], _ = createNewBlockBlob(c, container)
|
||||
}
|
||||
|
||||
defer delContainer(c, container)
|
||||
|
||||
marker := azblob.Marker{}
|
||||
iterations := numBlobs / maxResultsPerPage
|
||||
|
||||
for i := 0; i < iterations; i++ {
|
||||
resp, err := container.ListBlobs(context.Background(), marker, azblob.ListBlobsOptions{MaxResults: maxResultsPerPage})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Blobs.Blob, chk.HasLen, maxResultsPerPage)
|
||||
|
||||
hasMore := i < iterations-1
|
||||
c.Assert(resp.NextMarker.NotDone(), chk.Equals, hasMore)
|
||||
marker = resp.NextMarker
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ContainerURLSuite) TestSetMetadataCondition(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
time.Sleep(time.Second * 3)
|
||||
currTime := time.Now().UTC()
|
||||
rResp, err := container.SetMetadata(context.Background(), azblob.Metadata{"foo": "bar"},
|
||||
azblob.ContainerAccessConditions{HTTPAccessConditions: azblob.HTTPAccessConditions{IfModifiedSince: currTime}})
|
||||
c.Assert(err, chk.NotNil)
|
||||
c.Assert(rResp, chk.IsNil)
|
||||
se, ok := err.(azblob.StorageError)
|
||||
c.Assert(ok, chk.Equals, true)
|
||||
c.Assert(se.Response().StatusCode, chk.Equals, http.StatusPreconditionFailed)
|
||||
gResp, err := container.GetPropertiesAndMetadata(context.Background(), azblob.LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
md := gResp.NewMetadata()
|
||||
c.Assert(md, chk.HasLen, 0)
|
||||
}
|
||||
|
||||
func (s *ContainerURLSuite) TestListBlobsWithPrefix(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
prefixes := []string{
|
||||
"one/",
|
||||
"one/",
|
||||
"one/",
|
||||
"two/",
|
||||
"three/",
|
||||
"three/",
|
||||
}
|
||||
|
||||
for _, prefix := range prefixes {
|
||||
createBlockBlobWithPrefix(c, container, prefix)
|
||||
}
|
||||
|
||||
blobs, err := container.ListBlobs(context.Background(), azblob.Marker{}, azblob.ListBlobsOptions{Delimiter: "/"})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(blobs.Blobs.BlobPrefix, chk.HasLen, 3)
|
||||
c.Assert(blobs.Blobs.Blob, chk.HasLen, 0)
|
||||
}
|
142
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_url_page_blob_test.go
generated
vendored
142
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_url_page_blob_test.go
generated
vendored
|
@ -1,142 +0,0 @@
|
|||
package azblob_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-storage-blob-go/2016-05-31/azblob"
|
||||
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
|
||||
)
|
||||
|
||||
type PageBlobURLSuite struct{}
|
||||
|
||||
var _ = chk.Suite(&PageBlobURLSuite{})
|
||||
|
||||
func (b *PageBlobURLSuite) TestPutGetPages(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blob, _ := createNewPageBlob(c, container)
|
||||
|
||||
pageRange := azblob.PageRange{Start: 0, End: 1023}
|
||||
putResp, err := blob.PutPages(context.Background(), pageRange, getReaderToRandomBytes(1024), azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(putResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(putResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(putResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(putResp.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
c.Assert(putResp.BlobSequenceNumber(), chk.Equals, int32(0))
|
||||
c.Assert(putResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(putResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(putResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
pageList, err := blob.GetPageRanges(context.Background(), azblob.BlobRange{Offset: 0, Count: 1023}, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(pageList.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(pageList.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(pageList.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(pageList.BlobContentLength(), chk.Equals, int64(512*10))
|
||||
c.Assert(pageList.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(pageList.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(pageList.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(pageList.PageRange, chk.HasLen, 1)
|
||||
c.Assert(pageList.PageRange[0], chk.DeepEquals, pageRange)
|
||||
}
|
||||
|
||||
func (b *PageBlobURLSuite) TestClearDiffPages(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blob, _ := createNewPageBlob(c, container)
|
||||
_, err := blob.PutPages(context.Background(), azblob.PageRange{Start: 0, End: 2047}, getReaderToRandomBytes(2048), azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
snapshotResp, err := blob.CreateSnapshot(context.Background(), nil, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blob.PutPages(context.Background(), azblob.PageRange{Start: 2048, End: 4095}, getReaderToRandomBytes(2048), azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
pageList, err := blob.GetPageRangesDiff(context.Background(), azblob.BlobRange{Offset: 0, Count: 4095}, snapshotResp.Snapshot(), azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(pageList.PageRange, chk.HasLen, 1)
|
||||
c.Assert(pageList.PageRange[0].Start, chk.Equals, int32(2048))
|
||||
c.Assert(pageList.PageRange[0].End, chk.Equals, int32(4095))
|
||||
|
||||
clearResp, err := blob.ClearPages(context.Background(), azblob.PageRange{Start: 2048, End: 4095}, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(clearResp.Response().StatusCode, chk.Equals, 201)
|
||||
|
||||
pageList, err = blob.GetPageRangesDiff(context.Background(), azblob.BlobRange{Offset: 0, Count: 4095}, snapshotResp.Snapshot(), azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(pageList.PageRange, chk.HasLen, 0)
|
||||
}
|
||||
|
||||
func (b *PageBlobURLSuite) TestIncrementalCopy(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
_, err := container.SetPermissions(context.Background(), azblob.PublicAccessBlob, nil, azblob.ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
srcBlob, _ := createNewPageBlob(c, container)
|
||||
_, err = srcBlob.PutPages(context.Background(), azblob.PageRange{Start: 0, End: 1023}, getReaderToRandomBytes(1024), azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
snapshotResp, err := srcBlob.CreateSnapshot(context.Background(), nil, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
dstBlob := container.NewPageBlobURL(generateBlobName())
|
||||
|
||||
resp, err := dstBlob.StartIncrementalCopy(context.Background(), srcBlob.URL(), snapshotResp.Snapshot(), azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 202)
|
||||
c.Assert(resp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Date().IsZero(), chk.Equals, false)
|
||||
c.Assert(resp.CopyID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.CopyStatus(), chk.Equals, azblob.CopyStatusPending)
|
||||
|
||||
waitForIncrementalCopy(c, dstBlob, resp)
|
||||
}
|
||||
|
||||
func (b *PageBlobURLSuite) TestResizePageBlob(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
defer delContainer(c, container)
|
||||
|
||||
blob, _ := createNewPageBlob(c, container)
|
||||
resp, err := blob.Resize(context.Background(), 2048, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
|
||||
resp, err = blob.Resize(context.Background(), 8192, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
|
||||
resp2, err := blob.GetPropertiesAndMetadata(ctx, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp2.ContentLength(), chk.Equals, int64(8192))
|
||||
}
|
||||
|
||||
func (b *PageBlobURLSuite) TestPageSequenceNumbers(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
container, _ := createNewContainer(c, bsu)
|
||||
blob, _ := createNewPageBlob(c, container)
|
||||
|
||||
defer delContainer(c, container)
|
||||
|
||||
resp, err := blob.SetSequenceNumber(context.Background(), azblob.SequenceNumberActionIncrement, 0, azblob.BlobHTTPHeaders{}, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
|
||||
resp, err = blob.SetSequenceNumber(context.Background(), azblob.SequenceNumberActionMax, 7, azblob.BlobHTTPHeaders{}, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
|
||||
resp, err = blob.SetSequenceNumber(context.Background(), azblob.SequenceNumberActionUpdate, 11, azblob.BlobHTTPHeaders{}, azblob.BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
}
|
109
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_url_service_test.go
generated
vendored
109
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zt_url_service_test.go
generated
vendored
|
@ -1,109 +0,0 @@
|
|||
package azblob_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-storage-blob-go/2016-05-31/azblob"
|
||||
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
|
||||
)
|
||||
|
||||
type StorageAccountSuite struct{}
|
||||
|
||||
var _ = chk.Suite(&StorageAccountSuite{})
|
||||
|
||||
/*func (s *StorageAccountSuite) TestGetSetProperties(c *chk.C) {
|
||||
sa := getStorageAccount(c)
|
||||
setProps := StorageServiceProperties{}
|
||||
resp, err := sa.SetProperties(context.Background(), setProps)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 202)
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
|
||||
props, err := sa.GetProperties(context.Background())
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(props.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(props.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(props.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(props.Logging, chk.NotNil)
|
||||
c.Assert(props.HourMetrics, chk.NotNil)
|
||||
c.Assert(props.MinuteMetrics, chk.NotNil)
|
||||
c.Assert(props.Cors, chk.HasLen, 0)
|
||||
c.Assert(props.DefaultServiceVersion, chk.IsNil) // TODO: this seems like a bug
|
||||
}
|
||||
|
||||
func (s *StorageAccountSuite) TestGetStatus(c *chk.C) {
|
||||
sa := getStorageAccount(c)
|
||||
if !strings.Contains(sa.URL().Path, "-secondary") {
|
||||
c.Skip("only applicable on secondary storage accounts")
|
||||
}
|
||||
stats, err := sa.GetStats(context.Background())
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(stats, chk.NotNil)
|
||||
}*/
|
||||
|
||||
func (s *StorageAccountSuite) TestListContainers(c *chk.C) {
|
||||
sa := getBSU()
|
||||
resp, err := sa.ListContainers(context.Background(), azblob.Marker{}, azblob.ListContainersOptions{Prefix: containerPrefix})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(resp.Containers, chk.HasLen, 0)
|
||||
c.Assert(resp.ServiceEndpoint, chk.NotNil)
|
||||
|
||||
container, _ := createNewContainer(c, sa)
|
||||
defer delContainer(c, container)
|
||||
|
||||
md := azblob.Metadata{
|
||||
"foo": "foovalue",
|
||||
"bar": "barvalue",
|
||||
}
|
||||
_, err = container.SetMetadata(context.Background(), md, azblob.ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err = sa.ListContainers(context.Background(), azblob.Marker{}, azblob.ListContainersOptions{Detail: azblob.ListContainersDetail{Metadata: true}, Prefix: containerPrefix})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Containers, chk.HasLen, 1)
|
||||
c.Assert(resp.Containers[0].Name, chk.NotNil)
|
||||
c.Assert(resp.Containers[0].Properties, chk.NotNil)
|
||||
c.Assert(resp.Containers[0].Properties.LastModified, chk.NotNil)
|
||||
c.Assert(resp.Containers[0].Properties.Etag, chk.NotNil)
|
||||
c.Assert(resp.Containers[0].Properties.LeaseStatus, chk.Equals, azblob.LeaseStatusUnlocked)
|
||||
c.Assert(resp.Containers[0].Properties.LeaseState, chk.Equals, azblob.LeaseStateAvailable)
|
||||
c.Assert(string(resp.Containers[0].Properties.LeaseDuration), chk.Equals, "")
|
||||
c.Assert(string(resp.Containers[0].Properties.PublicAccess), chk.Equals, "blob")
|
||||
c.Assert(resp.Containers[0].Metadata, chk.DeepEquals, md)
|
||||
}
|
||||
|
||||
func (s *StorageAccountSuite) TestListContainersPaged(c *chk.C) {
|
||||
sa := getBSU()
|
||||
|
||||
const numContainers = 4
|
||||
const maxResultsPerPage = 2
|
||||
const pagedContainersPrefix = "azblobspagedtest"
|
||||
|
||||
containers := make([]azblob.ContainerURL, numContainers)
|
||||
for i := 0; i < numContainers; i++ {
|
||||
containers[i], _ = createNewContainerWithSuffix(c, sa, pagedContainersPrefix)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
for i := range containers {
|
||||
delContainer(c, containers[i])
|
||||
}
|
||||
}()
|
||||
|
||||
marker := azblob.Marker{}
|
||||
iterations := numContainers / maxResultsPerPage
|
||||
|
||||
for i := 0; i < iterations; i++ {
|
||||
resp, err := sa.ListContainers(context.Background(), marker, azblob.ListContainersOptions{MaxResults: maxResultsPerPage, Prefix: containerPrefix + pagedContainersPrefix})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Containers, chk.HasLen, maxResultsPerPage)
|
||||
|
||||
hasMore := i < iterations-1
|
||||
c.Assert(resp.NextMarker.NotDone(), chk.Equals, hasMore)
|
||||
marker = resp.NextMarker
|
||||
}
|
||||
}
|
113
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_append_blobs.go
generated
vendored
113
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_append_blobs.go
generated
vendored
|
@ -1,113 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// appendBlobsClient is the client for the AppendBlobs methods of the Azblob service.
|
||||
type appendBlobsClient struct {
|
||||
managementClient
|
||||
}
|
||||
|
||||
// newAppendBlobsClient creates an instance of the appendBlobsClient client.
|
||||
func newAppendBlobsClient(url url.URL, p pipeline.Pipeline) appendBlobsClient {
|
||||
return appendBlobsClient{newManagementClient(url, p)}
|
||||
}
|
||||
|
||||
// AppendBlock the Append Block operation commits a new block of data to the end of an existing append blob. The Append
|
||||
// Block operation is permitted only if the blob was created with x-ms-blob-type set to AppendBlob. Append Block is
|
||||
// supported only on version 2015-02-21 version or later.
|
||||
//
|
||||
// body is initial data body will be closed upon successful return. Callers should ensure closure when receiving an
|
||||
// error.timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the container's
|
||||
// lease is active and matches this ID. maxSize is optional conditional header. The max length in bytes permitted for
|
||||
// the append blob. If the Append Block operation would cause the blob to exceed that limit or if the blob size is
|
||||
// already greater than the value specified in this header, the request will fail with MaxBlobSizeConditionNotMet error
|
||||
// (HTTP status code 412 - Precondition Failed). appendPosition is optional conditional header, used only for the
|
||||
// Append Block operation. A number indicating the byte offset to compare. Append Block will succeed only if the append
|
||||
// position is equal to this number. If it is not, the request will fail with the AppendPositionConditionNotMet error
|
||||
// (HTTP status code 412 - Precondition Failed). ifModifiedSince is specify this header value to operate only on a blob
|
||||
// if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate
|
||||
// only on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value to
|
||||
// operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a
|
||||
// matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded
|
||||
// in the analytics logs when storage analytics logging is enabled.
|
||||
func (client appendBlobsClient) AppendBlock(ctx context.Context, body io.ReadSeeker, timeout *int32, leaseID *string, maxSize *int32, appendPosition *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*AppendBlobsAppendBlockResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: body,
|
||||
constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}},
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.appendBlockPreparer(body, timeout, leaseID, maxSize, appendPosition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.appendBlockResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*AppendBlobsAppendBlockResponse), err
|
||||
}
|
||||
|
||||
// appendBlockPreparer prepares the AppendBlock request.
|
||||
func (client appendBlobsClient) appendBlockPreparer(body io.ReadSeeker, timeout *int32, leaseID *string, maxSize *int32, appendPosition *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("PUT", client.url, body)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("comp", "appendblock")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
if maxSize != nil {
|
||||
req.Header.Set("x-ms-blob-condition-maxsize", fmt.Sprintf("%v", *maxSize))
|
||||
}
|
||||
if appendPosition != nil {
|
||||
req.Header.Set("x-ms-blob-condition-appendpos", fmt.Sprintf("%v", *appendPosition))
|
||||
}
|
||||
if ifModifiedSince != nil {
|
||||
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifUnmodifiedSince != nil {
|
||||
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifMatches != nil {
|
||||
req.Header.Set("If-Match", string(*ifMatches))
|
||||
}
|
||||
if ifNoneMatch != nil {
|
||||
req.Header.Set("If-None-Match", string(*ifNoneMatch))
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// appendBlockResponder handles the response to the AppendBlock request.
|
||||
func (client appendBlobsClient) appendBlockResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK, http.StatusCreated)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &AppendBlobsAppendBlockResponse{rawResponse: resp.Response()}, err
|
||||
}
|
1022
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_blobs.go
generated
vendored
1022
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_blobs.go
generated
vendored
File diff suppressed because it is too large
Load diff
295
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_block_blobs.go
generated
vendored
295
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_block_blobs.go
generated
vendored
|
@ -1,295 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// blockBlobsClient is the client for the BlockBlobs methods of the Azblob service.
|
||||
type blockBlobsClient struct {
|
||||
managementClient
|
||||
}
|
||||
|
||||
// newBlockBlobsClient creates an instance of the blockBlobsClient client.
|
||||
func newBlockBlobsClient(url url.URL, p pipeline.Pipeline) blockBlobsClient {
|
||||
return blockBlobsClient{newManagementClient(url, p)}
|
||||
}
|
||||
|
||||
// GetBlockList the Get Block List operation retrieves the list of blocks that have been uploaded as part of a block
|
||||
// blob
|
||||
//
|
||||
// listType is specifies whether to return the list of committed blocks, the list of uncommitted blocks, or both lists
|
||||
// together. snapshot is the snapshot parameter is an opaque DateTime value that, when present, specifies the blob
|
||||
// snapshot to retrieve. For more information on working with blob snapshots, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating
|
||||
// a Snapshot of a Blob.</a> timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the container's
|
||||
// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character
|
||||
// limit that is recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client blockBlobsClient) GetBlockList(ctx context.Context, listType BlockListType, snapshot *time.Time, timeout *int32, leaseID *string, requestID *string) (*BlockList, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.getBlockListPreparer(listType, snapshot, timeout, leaseID, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getBlockListResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*BlockList), err
|
||||
}
|
||||
|
||||
// getBlockListPreparer prepares the GetBlockList request.
|
||||
func (client blockBlobsClient) getBlockListPreparer(listType BlockListType, snapshot *time.Time, timeout *int32, leaseID *string, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("GET", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if snapshot != nil {
|
||||
params.Set("snapshot", (*snapshot).Format(rfc3339Format))
|
||||
}
|
||||
params.Set("blocklisttype", fmt.Sprintf("%v", listType))
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("comp", "blocklist")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// getBlockListResponder handles the response to the GetBlockList request.
|
||||
func (client blockBlobsClient) getBlockListResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &BlockList{rawResponse: resp.Response()}
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
defer resp.Response().Body.Close()
|
||||
b, err := ioutil.ReadAll(resp.Response().Body)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to read response body")
|
||||
}
|
||||
if len(b) > 0 {
|
||||
err = xml.Unmarshal(b, result)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body")
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// PutBlock the Put Block operation creates a new block to be committed as part of a blob
|
||||
//
|
||||
// blockID is a valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or
|
||||
// equal to 64 bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the
|
||||
// same size for each block. body is initial data body will be closed upon successful return. Callers should ensure
|
||||
// closure when receiving an error.timeout is the timeout parameter is expressed in seconds. For more information, see
|
||||
// <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the container's
|
||||
// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character
|
||||
// limit that is recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client blockBlobsClient) PutBlock(ctx context.Context, blockID string, body io.ReadSeeker, timeout *int32, leaseID *string, requestID *string) (*BlockBlobsPutBlockResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: body,
|
||||
constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}},
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.putBlockPreparer(blockID, body, timeout, leaseID, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.putBlockResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*BlockBlobsPutBlockResponse), err
|
||||
}
|
||||
|
||||
// putBlockPreparer prepares the PutBlock request.
|
||||
func (client blockBlobsClient) putBlockPreparer(blockID string, body io.ReadSeeker, timeout *int32, leaseID *string, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("PUT", client.url, body)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
params.Set("blockid", blockID)
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("comp", "block")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// putBlockResponder handles the response to the PutBlock request.
|
||||
func (client blockBlobsClient) putBlockResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK, http.StatusCreated)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &BlockBlobsPutBlockResponse{rawResponse: resp.Response()}, err
|
||||
}
|
||||
|
||||
// PutBlockList the Put Block List operation writes a blob by specifying the list of block IDs that make up the blob.
|
||||
// In order to be written as part of a blob, a block must have been successfully written to the server in a prior Put
|
||||
// Block operation. You can call Put Block List to update a blob by uploading only those blocks that have changed, then
|
||||
// committing the new and existing blocks together. You can do this by specifying whether to commit a block from the
|
||||
// committed block list or from the uncommitted block list, or to commit the most recently uploaded version of the
|
||||
// block, whichever list it may belong to.
|
||||
//
|
||||
// timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> blobCacheControl is optional. Sets the blob's cache control. If specified,
|
||||
// this property is stored with the blob and returned with a read request. blobContentType is optional. Sets the blob's
|
||||
// content type. If specified, this property is stored with the blob and returned with a read request.
|
||||
// blobContentEncoding is optional. Sets the blob's content encoding. If specified, this property is stored with the
|
||||
// blob and returned with a read request. blobContentLanguage is optional. Set the blob's content language. If
|
||||
// specified, this property is stored with the blob and returned with a read request. blobContentMD5 is optional. An
|
||||
// MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were
|
||||
// validated when each was uploaded. metadata is optional. Specifies a user-defined name-value pair associated with the
|
||||
// blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the
|
||||
// destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified
|
||||
// metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19,
|
||||
// metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and
|
||||
// Metadata for more information. leaseID is if specified, the operation only succeeds if the container's lease is
|
||||
// active and matches this ID. blobContentDisposition is optional. Sets the blob's Content-Disposition header.
|
||||
// ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the specified
|
||||
// date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified
|
||||
// since the specified date/time. ifMatches is specify an ETag value to operate only on blobs with a matching value.
|
||||
// ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. requestID is provides a
|
||||
// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage
|
||||
// analytics logging is enabled.
|
||||
func (client blockBlobsClient) PutBlockList(ctx context.Context, blocks BlockLookupList, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlockBlobsPutBlockListResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}},
|
||||
{targetValue: metadata,
|
||||
constraints: []constraint{{target: "metadata", name: null, rule: false,
|
||||
chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.putBlockListPreparer(blocks, timeout, blobCacheControl, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.putBlockListResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*BlockBlobsPutBlockListResponse), err
|
||||
}
|
||||
|
||||
// putBlockListPreparer prepares the PutBlockList request.
|
||||
func (client blockBlobsClient) putBlockListPreparer(blocks BlockLookupList, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("PUT", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("comp", "blocklist")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if blobCacheControl != nil {
|
||||
req.Header.Set("x-ms-blob-cache-control", *blobCacheControl)
|
||||
}
|
||||
if blobContentType != nil {
|
||||
req.Header.Set("x-ms-blob-content-type", *blobContentType)
|
||||
}
|
||||
if blobContentEncoding != nil {
|
||||
req.Header.Set("x-ms-blob-content-encoding", *blobContentEncoding)
|
||||
}
|
||||
if blobContentLanguage != nil {
|
||||
req.Header.Set("x-ms-blob-content-language", *blobContentLanguage)
|
||||
}
|
||||
if blobContentMD5 != nil {
|
||||
req.Header.Set("x-ms-blob-content-md5", *blobContentMD5)
|
||||
}
|
||||
if metadata != nil {
|
||||
for k, v := range metadata {
|
||||
req.Header.Set("x-ms-meta-"+k, v)
|
||||
}
|
||||
}
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
if blobContentDisposition != nil {
|
||||
req.Header.Set("x-ms-blob-content-disposition", *blobContentDisposition)
|
||||
}
|
||||
if ifModifiedSince != nil {
|
||||
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifUnmodifiedSince != nil {
|
||||
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifMatches != nil {
|
||||
req.Header.Set("If-Match", string(*ifMatches))
|
||||
}
|
||||
if ifNoneMatch != nil {
|
||||
req.Header.Set("If-None-Match", string(*ifNoneMatch))
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
b, err := xml.Marshal(blocks)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to marshal request body")
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/xml")
|
||||
err = req.SetBody(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to set request body")
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// putBlockListResponder handles the response to the PutBlockList request.
|
||||
func (client blockBlobsClient) putBlockListResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK, http.StatusCreated)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &BlockBlobsPutBlockListResponse{rawResponse: resp.Response()}, err
|
||||
}
|
38
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_client.go
generated
vendored
38
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_client.go
generated
vendored
|
@ -1,38 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const (
|
||||
// ServiceVersion specifies the version of the operations used in this package.
|
||||
ServiceVersion = "2016-05-31"
|
||||
)
|
||||
|
||||
// managementClient is the base client for Azblob.
|
||||
type managementClient struct {
|
||||
url url.URL
|
||||
p pipeline.Pipeline
|
||||
}
|
||||
|
||||
// newManagementClient creates an instance of the managementClient client.
|
||||
func newManagementClient(url url.URL, p pipeline.Pipeline) managementClient {
|
||||
return managementClient{
|
||||
url: url,
|
||||
p: p,
|
||||
}
|
||||
}
|
||||
|
||||
// URL returns a copy of the URL for this client.
|
||||
func (mc managementClient) URL() url.URL {
|
||||
return mc.url
|
||||
}
|
||||
|
||||
// Pipeline returns the pipeline for this client.
|
||||
func (mc managementClient) Pipeline() pipeline.Pipeline {
|
||||
return mc.p
|
||||
}
|
702
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_container.go
generated
vendored
702
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_container.go
generated
vendored
|
@ -1,702 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// containerClient is the client for the Container methods of the Azblob service.
|
||||
type containerClient struct {
|
||||
managementClient
|
||||
}
|
||||
|
||||
// newContainerClient creates an instance of the containerClient client.
|
||||
func newContainerClient(url url.URL, p pipeline.Pipeline) containerClient {
|
||||
return containerClient{newManagementClient(url, p)}
|
||||
}
|
||||
|
||||
// Create creates a new container under the specified account. If the container with the same name already exists, the
|
||||
// operation fails
|
||||
//
|
||||
// timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> metadata is optional. Specifies a user-defined name-value pair associated
|
||||
// with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or
|
||||
// file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with
|
||||
// the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version
|
||||
// 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing
|
||||
// Containers, Blobs, and Metadata for more information. access is specifies whether data in the container may be
|
||||
// accessed publicly and the level of access requestID is provides a client-generated, opaque value with a 1 KB
|
||||
// character limit that is recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client containerClient) Create(ctx context.Context, timeout *int32, metadata map[string]string, access PublicAccessType, requestID *string) (*ContainerCreateResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}},
|
||||
{targetValue: metadata,
|
||||
constraints: []constraint{{target: "metadata", name: null, rule: false,
|
||||
chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.createPreparer(timeout, metadata, access, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.createResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*ContainerCreateResponse), err
|
||||
}
|
||||
|
||||
// createPreparer prepares the Create request.
|
||||
func (client containerClient) createPreparer(timeout *int32, metadata map[string]string, access PublicAccessType, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("PUT", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("restype", "container")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if metadata != nil {
|
||||
for k, v := range metadata {
|
||||
req.Header.Set("x-ms-meta-"+k, v)
|
||||
}
|
||||
}
|
||||
if access != PublicAccessNone {
|
||||
req.Header.Set("x-ms-blob-public-access", fmt.Sprintf("%v", access))
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// createResponder handles the response to the Create request.
|
||||
func (client containerClient) createResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK, http.StatusCreated)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ContainerCreateResponse{rawResponse: resp.Response()}, err
|
||||
}
|
||||
|
||||
// Delete operation marks the specified container for deletion. The container and any blobs contained within it are
|
||||
// later deleted during garbage collection
|
||||
//
|
||||
// timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the container's
|
||||
// lease is active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it
|
||||
// has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a
|
||||
// blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value to operate only
|
||||
// on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching
|
||||
// value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the
|
||||
// analytics logs when storage analytics logging is enabled.
|
||||
func (client containerClient) Delete(ctx context.Context, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*ContainerDeleteResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.deletePreparer(timeout, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.deleteResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*ContainerDeleteResponse), err
|
||||
}
|
||||
|
||||
// deletePreparer prepares the Delete request.
|
||||
func (client containerClient) deletePreparer(timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("DELETE", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("restype", "container")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
if ifModifiedSince != nil {
|
||||
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifUnmodifiedSince != nil {
|
||||
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifMatches != nil {
|
||||
req.Header.Set("If-Match", string(*ifMatches))
|
||||
}
|
||||
if ifNoneMatch != nil {
|
||||
req.Header.Set("If-None-Match", string(*ifNoneMatch))
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// deleteResponder handles the response to the Delete request.
|
||||
func (client containerClient) deleteResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK, http.StatusAccepted)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ContainerDeleteResponse{rawResponse: resp.Response()}, err
|
||||
}
|
||||
|
||||
// GetACL sends the get acl request.
|
||||
//
|
||||
// timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the container's
|
||||
// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character
|
||||
// limit that is recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client containerClient) GetACL(ctx context.Context, timeout *int32, leaseID *string, requestID *string) (*SignedIdentifiers, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.getACLPreparer(timeout, leaseID, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getACLResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*SignedIdentifiers), err
|
||||
}
|
||||
|
||||
// getACLPreparer prepares the GetACL request.
|
||||
func (client containerClient) getACLPreparer(timeout *int32, leaseID *string, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("GET", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("restype", "container")
|
||||
params.Set("comp", "acl")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// getACLResponder handles the response to the GetACL request.
|
||||
func (client containerClient) getACLResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &SignedIdentifiers{rawResponse: resp.Response()}
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
defer resp.Response().Body.Close()
|
||||
b, err := ioutil.ReadAll(resp.Response().Body)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to read response body")
|
||||
}
|
||||
if len(b) > 0 {
|
||||
err = xml.Unmarshal(b, result)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body")
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetMetadata returns all user-defined metadata for the container
|
||||
//
|
||||
// timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the container's
|
||||
// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character
|
||||
// limit that is recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client containerClient) GetMetadata(ctx context.Context, timeout *int32, leaseID *string, requestID *string) (*ContainerGetMetadataResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.getMetadataPreparer(timeout, leaseID, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getMetadataResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*ContainerGetMetadataResponse), err
|
||||
}
|
||||
|
||||
// getMetadataPreparer prepares the GetMetadata request.
|
||||
func (client containerClient) getMetadataPreparer(timeout *int32, leaseID *string, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("GET", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("restype", "container")
|
||||
params.Set("comp", "metadata")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// getMetadataResponder handles the response to the GetMetadata request.
|
||||
func (client containerClient) getMetadataResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ContainerGetMetadataResponse{rawResponse: resp.Response()}, err
|
||||
}
|
||||
|
||||
// GetProperties returns all user-defined metadata and system properties for the specified container. The data returned
|
||||
// does not include the container's list of blobs
|
||||
//
|
||||
// timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the container's
|
||||
// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character
|
||||
// limit that is recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client containerClient) GetProperties(ctx context.Context, timeout *int32, leaseID *string, requestID *string) (*ContainerGetPropertiesResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.getPropertiesPreparer(timeout, leaseID, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getPropertiesResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*ContainerGetPropertiesResponse), err
|
||||
}
|
||||
|
||||
// getPropertiesPreparer prepares the GetProperties request.
|
||||
func (client containerClient) getPropertiesPreparer(timeout *int32, leaseID *string, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("GET", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("restype", "container")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// getPropertiesResponder handles the response to the GetProperties request.
|
||||
func (client containerClient) getPropertiesResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ContainerGetPropertiesResponse{rawResponse: resp.Response()}, err
|
||||
}
|
||||
|
||||
// Lease establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60
|
||||
// seconds, or can be infinite
|
||||
//
|
||||
// action is describes what lease action to take. timeout is the timeout parameter is expressed in seconds. For more
|
||||
// information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the container's
|
||||
// lease is active and matches this ID. breakPeriod is for a break operation, proposed duration the lease should
|
||||
// continue before it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter than the
|
||||
// time remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be available
|
||||
// before the break period has expired, but the lease may be held for longer than the break period. If this header does
|
||||
// not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an
|
||||
// infinite lease breaks immediately. duration is specifies the duration of the lease, in seconds, or negative one (-1)
|
||||
// for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration cannot be
|
||||
// changed using renew or change. proposedLeaseID is proposed lease ID, in a GUID string format. The Blob service
|
||||
// returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String)
|
||||
// for a list of valid GUID string formats. ifModifiedSince is specify this header value to operate only on a blob if
|
||||
// it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only
|
||||
// on a blob if it has not been modified since the specified date/time. requestID is provides a client-generated,
|
||||
// opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is
|
||||
// enabled.
|
||||
func (client containerClient) Lease(ctx context.Context, action LeaseActionType, timeout *int32, leaseID *string, breakPeriod *int32, duration *int32, proposedLeaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (*ContainerLeaseResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.leasePreparer(action, timeout, leaseID, breakPeriod, duration, proposedLeaseID, ifModifiedSince, ifUnmodifiedSince, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.leaseResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*ContainerLeaseResponse), err
|
||||
}
|
||||
|
||||
// leasePreparer prepares the Lease request.
|
||||
func (client containerClient) leasePreparer(action LeaseActionType, timeout *int32, leaseID *string, breakPeriod *int32, duration *int32, proposedLeaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("PUT", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("comp", "lease")
|
||||
params.Set("restype", "container")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
req.Header.Set("x-ms-lease-action", fmt.Sprintf("%v", action))
|
||||
if breakPeriod != nil {
|
||||
req.Header.Set("x-ms-lease-break-period", fmt.Sprintf("%v", *breakPeriod))
|
||||
}
|
||||
if duration != nil {
|
||||
req.Header.Set("x-ms-lease-duration", fmt.Sprintf("%v", *duration))
|
||||
}
|
||||
if proposedLeaseID != nil {
|
||||
req.Header.Set("x-ms-proposed-lease-id", *proposedLeaseID)
|
||||
}
|
||||
if ifModifiedSince != nil {
|
||||
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifUnmodifiedSince != nil {
|
||||
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// leaseResponder handles the response to the Lease request.
|
||||
func (client containerClient) leaseResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK, http.StatusCreated, http.StatusAccepted)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ContainerLeaseResponse{rawResponse: resp.Response()}, err
|
||||
}
|
||||
|
||||
// ListBlobs the List Blobs operation returns a list of the blobs under the specified container
|
||||
//
|
||||
// prefix is filters the results to return only containers whose name begins with the specified prefix. delimiter is
|
||||
// when the request includes this parameter, the operation returns a BlobPrefix element in the response body that acts
|
||||
// as a placeholder for all blobs whose names begin with the same substring up to the appearance of the delimiter
|
||||
// character. The delimiter may be a single character or a string. marker is a string value that identifies the portion
|
||||
// of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value
|
||||
// within the response body if the listing operation did not return all containers remaining to be listed with the
|
||||
// current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request
|
||||
// the next page of list items. The marker value is opaque to the client. maxresults is specifies the maximum number of
|
||||
// containers to return. If the request does not specify maxresults, or specifies a value greater than 5000, the server
|
||||
// will return up to 5000 items. Note that if the listing operation crosses a partition boundary, then the service will
|
||||
// return a continuation token for retrieving the remainder of the results. For this reason, it is possible that the
|
||||
// service will return fewer results than specified by maxresults, or than the default of 5000. include is include this
|
||||
// parameter to specify one or more datasets to include in the response. timeout is the timeout parameter is expressed
|
||||
// in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> requestID is provides a client-generated, opaque value with a 1 KB
|
||||
// character limit that is recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client containerClient) ListBlobs(ctx context.Context, prefix *string, delimiter *string, marker *string, maxresults *int32, include ListBlobsIncludeType, timeout *int32, requestID *string) (*ListBlobsResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: maxresults,
|
||||
constraints: []constraint{{target: "maxresults", name: null, rule: false,
|
||||
chain: []constraint{{target: "maxresults", name: inclusiveMinimum, rule: 1, chain: nil}}}}},
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.listBlobsPreparer(prefix, delimiter, marker, maxresults, include, timeout, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.listBlobsResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*ListBlobsResponse), err
|
||||
}
|
||||
|
||||
// listBlobsPreparer prepares the ListBlobs request.
|
||||
func (client containerClient) listBlobsPreparer(prefix *string, delimiter *string, marker *string, maxresults *int32, include ListBlobsIncludeType, timeout *int32, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("GET", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if prefix != nil {
|
||||
params.Set("prefix", *prefix)
|
||||
}
|
||||
if delimiter != nil {
|
||||
params.Set("delimiter", *delimiter)
|
||||
}
|
||||
if marker != nil {
|
||||
params.Set("marker", *marker)
|
||||
}
|
||||
if maxresults != nil {
|
||||
params.Set("maxresults", fmt.Sprintf("%v", *maxresults))
|
||||
}
|
||||
if include != ListBlobsIncludeNone {
|
||||
params.Set("include", fmt.Sprintf("%v", include))
|
||||
}
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("restype", "container")
|
||||
params.Set("comp", "list")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// listBlobsResponder handles the response to the ListBlobs request.
|
||||
func (client containerClient) listBlobsResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ListBlobsResponse{rawResponse: resp.Response()}
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
defer resp.Response().Body.Close()
|
||||
b, err := ioutil.ReadAll(resp.Response().Body)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to read response body")
|
||||
}
|
||||
if len(b) > 0 {
|
||||
err = xml.Unmarshal(b, result)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body")
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SetACL sends the set acl request.
|
||||
//
|
||||
// containerACL is the acls for the container timeout is the timeout parameter is expressed in seconds. For more
|
||||
// information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the container's
|
||||
// lease is active and matches this ID. access is specifies whether data in the container may be accessed publicly and
|
||||
// the level of access ifModifiedSince is specify this header value to operate only on a blob if it has been modified
|
||||
// since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has
|
||||
// not been modified since the specified date/time. ifMatches is specify an ETag value to operate only on blobs with a
|
||||
// matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. requestID is
|
||||
// provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when
|
||||
// storage analytics logging is enabled.
|
||||
func (client containerClient) SetACL(ctx context.Context, containerACL []SignedIdentifier, timeout *int32, leaseID *string, access PublicAccessType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*ContainerSetACLResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.setACLPreparer(containerACL, timeout, leaseID, access, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.setACLResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*ContainerSetACLResponse), err
|
||||
}
|
||||
|
||||
// setACLPreparer prepares the SetACL request.
|
||||
func (client containerClient) setACLPreparer(containerACL []SignedIdentifier, timeout *int32, leaseID *string, access PublicAccessType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("PUT", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("restype", "container")
|
||||
params.Set("comp", "acl")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
if access != PublicAccessNone {
|
||||
req.Header.Set("x-ms-blob-public-access", fmt.Sprintf("%v", access))
|
||||
}
|
||||
if ifModifiedSince != nil {
|
||||
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifUnmodifiedSince != nil {
|
||||
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifMatches != nil {
|
||||
req.Header.Set("If-Match", string(*ifMatches))
|
||||
}
|
||||
if ifNoneMatch != nil {
|
||||
req.Header.Set("If-None-Match", string(*ifNoneMatch))
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
b, err := xml.Marshal(SignedIdentifiers{Value: containerACL})
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to marshal request body")
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/xml")
|
||||
err = req.SetBody(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to set request body")
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// setACLResponder handles the response to the SetACL request.
|
||||
func (client containerClient) setACLResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ContainerSetACLResponse{rawResponse: resp.Response()}, err
|
||||
}
|
||||
|
||||
// SetMetadata operation sets one or more user-defined name-value pairs for the specified container.
|
||||
//
|
||||
// timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the container's
|
||||
// lease is active and matches this ID. metadata is optional. Specifies a user-defined name-value pair associated with
|
||||
// the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to
|
||||
// the destination blob. If one or more name-value pairs are specified, the destination blob is created with the
|
||||
// specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version
|
||||
// 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing
|
||||
// Containers, Blobs, and Metadata for more information. ifModifiedSince is specify this header value to operate only
|
||||
// on a blob if it has been modified since the specified date/time. requestID is provides a client-generated, opaque
|
||||
// value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client containerClient) SetMetadata(ctx context.Context, timeout *int32, leaseID *string, metadata map[string]string, ifModifiedSince *time.Time, requestID *string) (*ContainerSetMetadataResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}},
|
||||
{targetValue: metadata,
|
||||
constraints: []constraint{{target: "metadata", name: null, rule: false,
|
||||
chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.setMetadataPreparer(timeout, leaseID, metadata, ifModifiedSince, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.setMetadataResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*ContainerSetMetadataResponse), err
|
||||
}
|
||||
|
||||
// setMetadataPreparer prepares the SetMetadata request.
|
||||
func (client containerClient) setMetadataPreparer(timeout *int32, leaseID *string, metadata map[string]string, ifModifiedSince *time.Time, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("PUT", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("restype", "container")
|
||||
params.Set("comp", "metadata")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
if metadata != nil {
|
||||
for k, v := range metadata {
|
||||
req.Header.Set("x-ms-meta-"+k, v)
|
||||
}
|
||||
}
|
||||
if ifModifiedSince != nil {
|
||||
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// setMetadataResponder handles the response to the SetMetadata request.
|
||||
func (client containerClient) setMetadataResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ContainerSetMetadataResponse{rawResponse: resp.Response()}, err
|
||||
}
|
201
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_marshalling.go
generated
vendored
201
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_marshalling.go
generated
vendored
|
@ -1,201 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"reflect"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
rfc3339Format = "2006-01-02T15:04:05.0000000Z07:00"
|
||||
)
|
||||
|
||||
// used to convert times from UTC to GMT before sending across the wire
|
||||
var gmt = time.FixedZone("GMT", 0)
|
||||
|
||||
// internal type used for marshalling time in RFC1123 format
|
||||
type timeRFC1123 struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface for timeRFC1123.
|
||||
func (t timeRFC1123) MarshalText() ([]byte, error) {
|
||||
return []byte(t.Format(time.RFC1123)), nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface for timeRFC1123.
|
||||
func (t *timeRFC1123) UnmarshalText(data []byte) (err error) {
|
||||
t.Time, err = time.Parse(time.RFC1123, string(data))
|
||||
return
|
||||
}
|
||||
|
||||
// internal type used for marshalling time in RFC3339 format
|
||||
type timeRFC3339 struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface for timeRFC3339.
|
||||
func (t timeRFC3339) MarshalText() ([]byte, error) {
|
||||
return []byte(t.Format(rfc3339Format)), nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface for timeRFC3339.
|
||||
func (t *timeRFC3339) UnmarshalText(data []byte) (err error) {
|
||||
t.Time, err = time.Parse(rfc3339Format, string(data))
|
||||
return
|
||||
}
|
||||
|
||||
// internal type used for marshalling
|
||||
type accessPolicy struct {
|
||||
Start timeRFC3339 `xml:"Start"`
|
||||
Expiry timeRFC3339 `xml:"Expiry"`
|
||||
Permission string `xml:"Permission"`
|
||||
}
|
||||
|
||||
// MarshalXML implements the xml.Marshaler interface for AccessPolicy.
|
||||
func (ap AccessPolicy) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if reflect.TypeOf((*AccessPolicy)(nil)).Elem().Size() != reflect.TypeOf((*accessPolicy)(nil)).Elem().Size() {
|
||||
panic("size mismatch between AccessPolicy and accessPolicy")
|
||||
}
|
||||
ap2 := (*accessPolicy)(unsafe.Pointer(&ap))
|
||||
return e.EncodeElement(*ap2, start)
|
||||
}
|
||||
|
||||
// UnmarshalXML implements the xml.Unmarshaler interface for AccessPolicy.
|
||||
func (ap *AccessPolicy) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
if reflect.TypeOf((*AccessPolicy)(nil)).Elem().Size() != reflect.TypeOf((*accessPolicy)(nil)).Elem().Size() {
|
||||
panic("size mismatch between AccessPolicy and accessPolicy")
|
||||
}
|
||||
ap2 := (*accessPolicy)(unsafe.Pointer(ap))
|
||||
err := d.DecodeElement(ap2, &start)
|
||||
if err != nil {
|
||||
ap = (*AccessPolicy)(unsafe.Pointer(ap2))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// internal type used for marshalling
|
||||
type blobProperties struct {
|
||||
LastModified timeRFC1123 `xml:"Last-Modified"`
|
||||
Etag ETag `xml:"Etag"`
|
||||
ContentLength *int64 `xml:"Content-Length"`
|
||||
ContentType *string `xml:"Content-Type"`
|
||||
ContentEncoding *string `xml:"Content-Encoding"`
|
||||
ContentLanguage *string `xml:"Content-Language"`
|
||||
ContentMD5 *string `xml:"Content-MD5"`
|
||||
ContentDisposition *string `xml:"Content-Disposition"`
|
||||
CacheControl *string `xml:"Cache-Control"`
|
||||
BlobSequenceNumber *int32 `xml:"x-ms-blob-sequence-number"`
|
||||
BlobType BlobType `xml:"BlobType"`
|
||||
LeaseStatus LeaseStatusType `xml:"LeaseStatus"`
|
||||
LeaseState LeaseStateType `xml:"LeaseState"`
|
||||
LeaseDuration LeaseDurationType `xml:"LeaseDuration"`
|
||||
CopyID *string `xml:"CopyId"`
|
||||
CopyStatus CopyStatusType `xml:"CopyStatus"`
|
||||
CopySource *string `xml:"CopySource"`
|
||||
CopyProgress *string `xml:"CopyProgress"`
|
||||
CopyCompletionTime *timeRFC1123 `xml:"CopyCompletionTime"`
|
||||
CopyStatusDescription *string `xml:"CopyStatusDescription"`
|
||||
ServerEncrypted *bool `xml:"ServerEncrypted"`
|
||||
IncrementalCopy *bool `xml:"IncrementalCopy"`
|
||||
}
|
||||
|
||||
// MarshalXML implements the xml.Marshaler interface for BlobProperties.
|
||||
func (bp BlobProperties) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if reflect.TypeOf((*BlobProperties)(nil)).Elem().Size() != reflect.TypeOf((*blobProperties)(nil)).Elem().Size() {
|
||||
panic("size mismatch between BlobProperties and blobProperties")
|
||||
}
|
||||
bp2 := (*blobProperties)(unsafe.Pointer(&bp))
|
||||
return e.EncodeElement(*bp2, start)
|
||||
}
|
||||
|
||||
// UnmarshalXML implements the xml.Unmarshaler interface for BlobProperties.
|
||||
func (bp *BlobProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
if reflect.TypeOf((*BlobProperties)(nil)).Elem().Size() != reflect.TypeOf((*blobProperties)(nil)).Elem().Size() {
|
||||
panic("size mismatch between BlobProperties and blobProperties")
|
||||
}
|
||||
bp2 := (*blobProperties)(unsafe.Pointer(bp))
|
||||
return d.DecodeElement(bp2, &start)
|
||||
}
|
||||
|
||||
// internal type used for marshalling
|
||||
type blob struct {
|
||||
Name string `xml:"Name"`
|
||||
Snapshot timeRFC3339 `xml:"Snapshot"`
|
||||
Properties BlobProperties `xml:"Properties"`
|
||||
Metadata Metadata `xml:"Metadata"`
|
||||
}
|
||||
|
||||
// MarshalXML implements the xml.Marshaler interface for Blob.
|
||||
func (b Blob) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if reflect.TypeOf((*Blob)(nil)).Elem().Size() != reflect.TypeOf((*blob)(nil)).Elem().Size() {
|
||||
panic("size mismatch between Blob and blob")
|
||||
}
|
||||
b2 := (*blob)(unsafe.Pointer(&b))
|
||||
return e.EncodeElement(*b2, start)
|
||||
}
|
||||
|
||||
// UnmarshalXML implements the xml.Unmarshaler interface for Blob.
|
||||
func (b *Blob) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
if reflect.TypeOf((*Blob)(nil)).Elem().Size() != reflect.TypeOf((*blob)(nil)).Elem().Size() {
|
||||
panic("size mismatch between Blob and blob")
|
||||
}
|
||||
b2 := (*blob)(unsafe.Pointer(b))
|
||||
return d.DecodeElement(b2, &start)
|
||||
}
|
||||
|
||||
// internal type used for marshalling
|
||||
type containerProperties struct {
|
||||
LastModified timeRFC1123 `xml:"Last-Modified"`
|
||||
Etag ETag `xml:"Etag"`
|
||||
LeaseStatus LeaseStatusType `xml:"LeaseStatus"`
|
||||
LeaseState LeaseStateType `xml:"LeaseState"`
|
||||
LeaseDuration LeaseDurationType `xml:"LeaseDuration"`
|
||||
PublicAccess PublicAccessType `xml:"PublicAccess"`
|
||||
}
|
||||
|
||||
// MarshalXML implements the xml.Marshaler interface for ContainerProperties.
|
||||
func (cp ContainerProperties) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if reflect.TypeOf((*ContainerProperties)(nil)).Elem().Size() != reflect.TypeOf((*containerProperties)(nil)).Elem().Size() {
|
||||
panic("size mismatch between ContainerProperties and containerProperties")
|
||||
}
|
||||
cp2 := (*containerProperties)(unsafe.Pointer(&cp))
|
||||
return e.EncodeElement(*cp2, start)
|
||||
}
|
||||
|
||||
// UnmarshalXML implements the xml.Unmarshaler interface for ContainerProperties.
|
||||
func (cp *ContainerProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
if reflect.TypeOf((*ContainerProperties)(nil)).Elem().Size() != reflect.TypeOf((*containerProperties)(nil)).Elem().Size() {
|
||||
panic("size mismatch between ContainerProperties and containerProperties")
|
||||
}
|
||||
cp2 := (*containerProperties)(unsafe.Pointer(cp))
|
||||
return d.DecodeElement(cp2, &start)
|
||||
}
|
||||
|
||||
// internal type used for marshalling
|
||||
type geoReplication struct {
|
||||
Status GeoReplicationStatusType `xml:"Status"`
|
||||
LastSyncTime timeRFC1123 `xml:"LastSyncTime"`
|
||||
}
|
||||
|
||||
// MarshalXML implements the xml.Marshaler interface for GeoReplication.
|
||||
func (gr GeoReplication) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
if reflect.TypeOf((*GeoReplication)(nil)).Elem().Size() != reflect.TypeOf((*geoReplication)(nil)).Elem().Size() {
|
||||
panic("size mismatch between GeoReplication and geoReplication")
|
||||
}
|
||||
gr2 := (*geoReplication)(unsafe.Pointer(&gr))
|
||||
return e.EncodeElement(*gr2, start)
|
||||
}
|
||||
|
||||
// UnmarshalXML implements the xml.Unmarshaler interface for GeoReplication.
|
||||
func (gr *GeoReplication) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
if reflect.TypeOf((*GeoReplication)(nil)).Elem().Size() != reflect.TypeOf((*geoReplication)(nil)).Elem().Size() {
|
||||
panic("size mismatch between GeoReplication and geoReplication")
|
||||
}
|
||||
gr2 := (*geoReplication)(unsafe.Pointer(gr))
|
||||
return d.DecodeElement(gr2, &start)
|
||||
}
|
2701
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_models.go
generated
vendored
2701
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_models.go
generated
vendored
File diff suppressed because it is too large
Load diff
314
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_page_blobs.go
generated
vendored
314
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_page_blobs.go
generated
vendored
|
@ -1,314 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// pageBlobsClient is the client for the PageBlobs methods of the Azblob service.
|
||||
type pageBlobsClient struct {
|
||||
managementClient
|
||||
}
|
||||
|
||||
// newPageBlobsClient creates an instance of the pageBlobsClient client.
|
||||
func newPageBlobsClient(url url.URL, p pipeline.Pipeline) pageBlobsClient {
|
||||
return pageBlobsClient{newManagementClient(url, p)}
|
||||
}
|
||||
|
||||
// GetPageRanges the Get Page Ranges operation returns the list of valid page ranges for a page blob or snapshot of a
|
||||
// page blob
|
||||
//
|
||||
// snapshot is the snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to
|
||||
// retrieve. For more information on working with blob snapshots, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating
|
||||
// a Snapshot of a Blob.</a> timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> prevsnapshot is optional in version 2015-07-08 and newer. The prevsnapshot
|
||||
// parameter is a DateTime value that specifies that the response will contain only pages that were changed between
|
||||
// target blob and previous snapshot. Changed pages include both updated and cleared pages. The target blob may be a
|
||||
// snapshot, as long as the snapshot specified by prevsnapshot is the older of the two. Note that incremental snapshots
|
||||
// are currently supported only for blobs created on or after January 1, 2016. rangeParameter is return only the bytes
|
||||
// of the blob in the specified range. leaseID is if specified, the operation only succeeds if the container's lease is
|
||||
// active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it has been
|
||||
// modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if
|
||||
// it has not been modified since the specified date/time. ifMatches is specify an ETag value to operate only on blobs
|
||||
// with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value.
|
||||
// requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics
|
||||
// logs when storage analytics logging is enabled.
|
||||
func (client pageBlobsClient) GetPageRanges(ctx context.Context, snapshot *time.Time, timeout *int32, prevsnapshot *time.Time, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageList, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.getPageRangesPreparer(snapshot, timeout, prevsnapshot, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getPageRangesResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*PageList), err
|
||||
}
|
||||
|
||||
// getPageRangesPreparer prepares the GetPageRanges request.
|
||||
func (client pageBlobsClient) getPageRangesPreparer(snapshot *time.Time, timeout *int32, prevsnapshot *time.Time, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("GET", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if snapshot != nil {
|
||||
params.Set("snapshot", (*snapshot).Format(rfc3339Format))
|
||||
}
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
if prevsnapshot != nil {
|
||||
params.Set("prevsnapshot", (*prevsnapshot).Format(rfc3339Format))
|
||||
}
|
||||
params.Set("comp", "pagelist")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if rangeParameter != nil {
|
||||
req.Header.Set("x-ms-range", *rangeParameter)
|
||||
}
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
if ifModifiedSince != nil {
|
||||
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifUnmodifiedSince != nil {
|
||||
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifMatches != nil {
|
||||
req.Header.Set("If-Match", string(*ifMatches))
|
||||
}
|
||||
if ifNoneMatch != nil {
|
||||
req.Header.Set("If-None-Match", string(*ifNoneMatch))
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// getPageRangesResponder handles the response to the GetPageRanges request.
|
||||
func (client pageBlobsClient) getPageRangesResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &PageList{rawResponse: resp.Response()}
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
defer resp.Response().Body.Close()
|
||||
b, err := ioutil.ReadAll(resp.Response().Body)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to read response body")
|
||||
}
|
||||
if len(b) > 0 {
|
||||
err = xml.Unmarshal(b, result)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body")
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// IncrementalCopy the Incremental Copy Blob operation copies a snapshot of the source page blob to a destination page
|
||||
// blob. The snapshot is copied such that only the differential changes between the previously copied snapshot are
|
||||
// transferred to the destination. The copied snapshots are complete copies of the original snapshot and can be read or
|
||||
// copied from as usual. This API is supported since REST version 2016-05-31.
|
||||
//
|
||||
// copySource is specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that
|
||||
// specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob
|
||||
// must either be public or must be authenticated via a shared access signature. timeout is the timeout parameter is
|
||||
// expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> metadata is optional. Specifies a user-defined name-value pair associated
|
||||
// with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or
|
||||
// file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with
|
||||
// the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version
|
||||
// 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing
|
||||
// Containers, Blobs, and Metadata for more information. ifModifiedSince is specify this header value to operate only
|
||||
// on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to
|
||||
// operate only on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value
|
||||
// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs
|
||||
// without a matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is
|
||||
// recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client pageBlobsClient) IncrementalCopy(ctx context.Context, copySource string, timeout *int32, metadata map[string]string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobsIncrementalCopyResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}},
|
||||
{targetValue: metadata,
|
||||
constraints: []constraint{{target: "metadata", name: null, rule: false,
|
||||
chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.incrementalCopyPreparer(copySource, timeout, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.incrementalCopyResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*PageBlobsIncrementalCopyResponse), err
|
||||
}
|
||||
|
||||
// incrementalCopyPreparer prepares the IncrementalCopy request.
|
||||
func (client pageBlobsClient) incrementalCopyPreparer(copySource string, timeout *int32, metadata map[string]string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("PUT", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("comp", "incrementalcopy")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if metadata != nil {
|
||||
for k, v := range metadata {
|
||||
req.Header.Set("x-ms-meta-"+k, v)
|
||||
}
|
||||
}
|
||||
if ifModifiedSince != nil {
|
||||
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifUnmodifiedSince != nil {
|
||||
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifMatches != nil {
|
||||
req.Header.Set("If-Match", string(*ifMatches))
|
||||
}
|
||||
if ifNoneMatch != nil {
|
||||
req.Header.Set("If-None-Match", string(*ifNoneMatch))
|
||||
}
|
||||
req.Header.Set("x-ms-copy-source", copySource)
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// incrementalCopyResponder handles the response to the IncrementalCopy request.
|
||||
func (client pageBlobsClient) incrementalCopyResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK, http.StatusAccepted)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &PageBlobsIncrementalCopyResponse{rawResponse: resp.Response()}, err
|
||||
}
|
||||
|
||||
// PutPage the Put Page operation writes a range of pages to a page blob
|
||||
//
|
||||
// pageWrite is required. You may specify one of the following options:
|
||||
// - Update: Writes the bytes specified by the request body into the specified range. The Range and Content-Length
|
||||
// headers must match to perform the update.
|
||||
// - Clear: Clears the specified range and releases the space used in storage for that range. To clear a range, set the
|
||||
// Content-Length header to zero, and the Range header to a value that indicates the range to clear, up to maximum blob
|
||||
// size. optionalbody is initial data optionalbody will be closed upon successful return. Callers should ensure closure
|
||||
// when receiving an error.timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> rangeParameter is return only the bytes of the blob in the specified
|
||||
// range. leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID.
|
||||
// ifSequenceNumberLessThanOrEqualTo is specify this header value to operate only on a blob if it has a sequence number
|
||||
// less than or equal to the specified. ifSequenceNumberLessThan is specify this header value to operate only on a blob
|
||||
// if it has a sequence number less than the specified. ifSequenceNumberEqualTo is specify this header value to operate
|
||||
// only on a blob if it has the specified sequence number. ifModifiedSince is specify this header value to operate only
|
||||
// on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to
|
||||
// operate only on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value
|
||||
// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs
|
||||
// without a matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is
|
||||
// recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client pageBlobsClient) PutPage(ctx context.Context, pageWrite PageWriteType, body io.ReadSeeker, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int32, ifSequenceNumberLessThan *int32, ifSequenceNumberEqualTo *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobsPutPageResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.putPagePreparer(pageWrite, body, timeout, rangeParameter, leaseID, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.putPageResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*PageBlobsPutPageResponse), err
|
||||
}
|
||||
|
||||
// putPagePreparer prepares the PutPage request.
|
||||
func (client pageBlobsClient) putPagePreparer(pageWrite PageWriteType, body io.ReadSeeker, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int32, ifSequenceNumberLessThan *int32, ifSequenceNumberEqualTo *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("PUT", client.url, body)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("comp", "page")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
if rangeParameter != nil {
|
||||
req.Header.Set("x-ms-range", *rangeParameter)
|
||||
}
|
||||
req.Header.Set("x-ms-page-write", fmt.Sprintf("%v", pageWrite))
|
||||
if leaseID != nil {
|
||||
req.Header.Set("x-ms-lease-id", *leaseID)
|
||||
}
|
||||
if ifSequenceNumberLessThanOrEqualTo != nil {
|
||||
req.Header.Set("x-ms-if-sequence-number-le", fmt.Sprintf("%v", *ifSequenceNumberLessThanOrEqualTo))
|
||||
}
|
||||
if ifSequenceNumberLessThan != nil {
|
||||
req.Header.Set("x-ms-if-sequence-number-lt", fmt.Sprintf("%v", *ifSequenceNumberLessThan))
|
||||
}
|
||||
if ifSequenceNumberEqualTo != nil {
|
||||
req.Header.Set("x-ms-if-sequence-number-eq", fmt.Sprintf("%v", *ifSequenceNumberEqualTo))
|
||||
}
|
||||
if ifModifiedSince != nil {
|
||||
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifUnmodifiedSince != nil {
|
||||
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
|
||||
}
|
||||
if ifMatches != nil {
|
||||
req.Header.Set("If-Match", string(*ifMatches))
|
||||
}
|
||||
if ifNoneMatch != nil {
|
||||
req.Header.Set("If-None-Match", string(*ifNoneMatch))
|
||||
}
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// putPageResponder handles the response to the PutPage request.
|
||||
func (client pageBlobsClient) putPageResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK, http.StatusCreated)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &PageBlobsPutPageResponse{rawResponse: resp.Response()}, err
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
type responder func(resp pipeline.Response) (result pipeline.Response, err error)
|
||||
|
||||
// ResponderPolicyFactory is a Factory capable of creating a responder pipeline.
|
||||
type responderPolicyFactory struct {
|
||||
responder responder
|
||||
}
|
||||
|
||||
// New creates a responder policy factory.
|
||||
func (arpf responderPolicyFactory) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
return responderPolicy{next: next, responder: arpf.responder}
|
||||
}
|
||||
|
||||
type responderPolicy struct {
|
||||
next pipeline.Policy
|
||||
responder responder
|
||||
}
|
||||
|
||||
// Do sends the request to the service and validates/deserializes the HTTP response.
|
||||
func (arp responderPolicy) Do(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
|
||||
resp, err := arp.next.Do(ctx, request)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
return arp.responder(resp)
|
||||
}
|
||||
|
||||
// validateResponse checks an HTTP response's status code against a legal set of codes.
|
||||
// If the response code is not legal, then validateResponse reads all of the response's body
|
||||
// (containing error information) and returns a response error.
|
||||
func validateResponse(resp pipeline.Response, successStatusCodes ...int) error {
|
||||
if resp == nil {
|
||||
return NewResponseError(nil, nil, "nil response")
|
||||
}
|
||||
responseCode := resp.Response().StatusCode
|
||||
for _, i := range successStatusCodes {
|
||||
if i == responseCode {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// only close the body in the failure case. in the
|
||||
// success case responders will close the body as required.
|
||||
defer resp.Response().Body.Close()
|
||||
b, err := ioutil.ReadAll(resp.Response().Body)
|
||||
if err != nil {
|
||||
return NewResponseError(err, resp.Response(), "failed to read response body")
|
||||
}
|
||||
// the service code, description and details will be populated during unmarshalling
|
||||
responseError := NewResponseError(nil, resp.Response(), resp.Response().Status)
|
||||
if len(b) > 0 {
|
||||
if err = xml.Unmarshal(b, &responseError); err != nil {
|
||||
return NewResponseError(err, resp.Response(), "failed to unmarshal response body")
|
||||
}
|
||||
}
|
||||
return responseError
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// if you want to provide custom error handling set this variable to your constructor function
|
||||
var responseErrorFactory func(cause error, response *http.Response, description string) error
|
||||
|
||||
// ResponseError identifies a responder-generated network or response parsing error.
|
||||
type ResponseError interface {
|
||||
// Error exposes the Error(), Temporary() and Timeout() methods.
|
||||
net.Error // Includes the Go error interface
|
||||
|
||||
// Response returns the HTTP response. You may examine this but you should not modify it.
|
||||
Response() *http.Response
|
||||
}
|
||||
|
||||
// NewResponseError creates an error object that implements the error interface.
|
||||
func NewResponseError(cause error, response *http.Response, description string) error {
|
||||
if responseErrorFactory != nil {
|
||||
return responseErrorFactory(cause, response, description)
|
||||
}
|
||||
return &responseError{
|
||||
ErrorNode: pipeline.ErrorNode{}.Initialize(cause, 3),
|
||||
response: response,
|
||||
description: description,
|
||||
}
|
||||
}
|
||||
|
||||
// responseError is the internal struct that implements the public ResponseError interface.
|
||||
type responseError struct {
|
||||
pipeline.ErrorNode // This is embedded so that responseError "inherits" Error, Temporary, Timeout, and Cause
|
||||
response *http.Response
|
||||
description string
|
||||
}
|
||||
|
||||
// Error implements the error interface's Error method to return a string representation of the error.
|
||||
func (e *responseError) Error() string {
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "===== RESPONSE ERROR (Code=%v) =====\n", e.response.StatusCode)
|
||||
fmt.Fprintf(b, "Status=%s, Description: %s\n", e.response.Status, e.description)
|
||||
s := b.String()
|
||||
return e.ErrorNode.Error(s)
|
||||
}
|
||||
|
||||
// Response implements the ResponseError interface's method to return the HTTP response.
|
||||
func (e *responseError) Response() *http.Response {
|
||||
return e.response
|
||||
}
|
||||
|
||||
// RFC7807 PROBLEM ------------------------------------------------------------------------------------
|
||||
// RFC7807Problem ... This type can be publicly embedded in another type that wants to add additional members.
|
||||
/*type RFC7807Problem struct {
|
||||
// Mandatory: A (relative) URI reference identifying the problem type (it MAY refer to human-readable documentation).
|
||||
typeURI string // Should default to "about:blank"
|
||||
// Optional: Short, human-readable summary (maybe localized).
|
||||
title string
|
||||
// Optional: HTTP status code generated by the origin server
|
||||
status int
|
||||
// Optional: Human-readable explanation for this problem occurrence.
|
||||
// Should help client correct the problem. Clients should NOT parse this string.
|
||||
detail string
|
||||
// Optional: A (relative) URI identifying this specific problem occurrence (it may or may not be dereferenced).
|
||||
instance string
|
||||
}
|
||||
// NewRFC7807Problem ...
|
||||
func NewRFC7807Problem(typeURI string, status int, titleFormat string, a ...interface{}) error {
|
||||
return &RFC7807Problem{
|
||||
typeURI: typeURI,
|
||||
status: status,
|
||||
title: fmt.Sprintf(titleFormat, a...),
|
||||
}
|
||||
}
|
||||
// Error returns the error information as a string.
|
||||
func (e *RFC7807Problem) Error() string {
|
||||
return e.title
|
||||
}
|
||||
// TypeURI ...
|
||||
func (e *RFC7807Problem) TypeURI() string {
|
||||
if e.typeURI == "" {
|
||||
e.typeURI = "about:blank"
|
||||
}
|
||||
return e.typeURI
|
||||
}
|
||||
// Members ...
|
||||
func (e *RFC7807Problem) Members() (status int, title, detail, instance string) {
|
||||
return e.status, e.title, e.detail, e.instance
|
||||
}*/
|
353
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_service.go
generated
vendored
353
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_service.go
generated
vendored
|
@ -1,353 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// serviceClient is the client for the Service methods of the Azblob service.
|
||||
type serviceClient struct {
|
||||
managementClient
|
||||
}
|
||||
|
||||
// newServiceClient creates an instance of the serviceClient client.
|
||||
func newServiceClient(url url.URL, p pipeline.Pipeline) serviceClient {
|
||||
return serviceClient{newManagementClient(url, p)}
|
||||
}
|
||||
|
||||
// GetProperties gets the properties of a storage account's Blob service, including properties for Storage Analytics
|
||||
// and CORS (Cross-Origin Resource Sharing) rules.
|
||||
//
|
||||
// timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> requestID is provides a client-generated, opaque value with a 1 KB
|
||||
// character limit that is recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client serviceClient) GetProperties(ctx context.Context, timeout *int32, requestID *string) (*StorageServiceProperties, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.getPropertiesPreparer(timeout, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getPropertiesResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*StorageServiceProperties), err
|
||||
}
|
||||
|
||||
// getPropertiesPreparer prepares the GetProperties request.
|
||||
func (client serviceClient) getPropertiesPreparer(timeout *int32, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("GET", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("restype", "service")
|
||||
params.Set("comp", "properties")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// getPropertiesResponder handles the response to the GetProperties request.
|
||||
func (client serviceClient) getPropertiesResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &StorageServiceProperties{rawResponse: resp.Response()}
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
defer resp.Response().Body.Close()
|
||||
b, err := ioutil.ReadAll(resp.Response().Body)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to read response body")
|
||||
}
|
||||
if len(b) > 0 {
|
||||
err = xml.Unmarshal(b, result)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body")
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetStats retrieves statistics related to replication for the Blob service. It is only available on the secondary
|
||||
// location endpoint when read-access geo-redundant replication is enabled for the storage account.
|
||||
//
|
||||
// timeout is the timeout parameter is expressed in seconds. For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> requestID is provides a client-generated, opaque value with a 1 KB
|
||||
// character limit that is recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client serviceClient) GetStats(ctx context.Context, timeout *int32, requestID *string) (*StorageServiceStats, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.getStatsPreparer(timeout, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getStatsResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*StorageServiceStats), err
|
||||
}
|
||||
|
||||
// getStatsPreparer prepares the GetStats request.
|
||||
func (client serviceClient) getStatsPreparer(timeout *int32, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("GET", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("restype", "service")
|
||||
params.Set("comp", "stats")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// getStatsResponder handles the response to the GetStats request.
|
||||
func (client serviceClient) getStatsResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &StorageServiceStats{rawResponse: resp.Response()}
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
defer resp.Response().Body.Close()
|
||||
b, err := ioutil.ReadAll(resp.Response().Body)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to read response body")
|
||||
}
|
||||
if len(b) > 0 {
|
||||
err = xml.Unmarshal(b, result)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body")
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ListContainers the List Containers operation returns a list of the containers under the specified account
|
||||
//
|
||||
// prefix is filters the results to return only containers whose name begins with the specified prefix. marker is a
|
||||
// string value that identifies the portion of the list of containers to be returned with the next listing operation.
|
||||
// The operation returns the NextMarker value within the response body if the listing operation did not return all
|
||||
// containers remaining to be listed with the current page. The NextMarker value can be used as the value for the
|
||||
// marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the
|
||||
// client. maxresults is specifies the maximum number of containers to return. If the request does not specify
|
||||
// maxresults, or specifies a value greater than 5000, the server will return up to 5000 items. Note that if the
|
||||
// listing operation crosses a partition boundary, then the service will return a continuation token for retrieving the
|
||||
// remainder of the results. For this reason, it is possible that the service will return fewer results than specified
|
||||
// by maxresults, or than the default of 5000. include is include this parameter to specify that the container's
|
||||
// metadata be returned as part of the response body. timeout is the timeout parameter is expressed in seconds. For
|
||||
// more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> requestID is provides a client-generated, opaque value with a 1 KB
|
||||
// character limit that is recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client serviceClient) ListContainers(ctx context.Context, prefix *string, marker *string, maxresults *int32, include ListContainersIncludeType, timeout *int32, requestID *string) (*ListContainersResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: maxresults,
|
||||
constraints: []constraint{{target: "maxresults", name: null, rule: false,
|
||||
chain: []constraint{{target: "maxresults", name: inclusiveMinimum, rule: 1, chain: nil}}}}},
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.listContainersPreparer(prefix, marker, maxresults, include, timeout, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.listContainersResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*ListContainersResponse), err
|
||||
}
|
||||
|
||||
// listContainersPreparer prepares the ListContainers request.
|
||||
func (client serviceClient) listContainersPreparer(prefix *string, marker *string, maxresults *int32, include ListContainersIncludeType, timeout *int32, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("GET", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if prefix != nil {
|
||||
params.Set("prefix", *prefix)
|
||||
}
|
||||
if marker != nil {
|
||||
params.Set("marker", *marker)
|
||||
}
|
||||
if maxresults != nil {
|
||||
params.Set("maxresults", fmt.Sprintf("%v", *maxresults))
|
||||
}
|
||||
if include != ListContainersIncludeNone {
|
||||
params.Set("include", fmt.Sprintf("%v", include))
|
||||
}
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("comp", "list")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// listContainersResponder handles the response to the ListContainers request.
|
||||
func (client serviceClient) listContainersResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ListContainersResponse{rawResponse: resp.Response()}
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
defer resp.Response().Body.Close()
|
||||
b, err := ioutil.ReadAll(resp.Response().Body)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to read response body")
|
||||
}
|
||||
if len(b) > 0 {
|
||||
err = xml.Unmarshal(b, result)
|
||||
if err != nil {
|
||||
return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body")
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SetProperties sets properties for a storage account's Blob service endpoint, including properties for Storage
|
||||
// Analytics and CORS (Cross-Origin Resource Sharing) rules
|
||||
//
|
||||
// storageServiceProperties is the StorageService properties. timeout is the timeout parameter is expressed in seconds.
|
||||
// For more information, see <a
|
||||
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
|
||||
// Timeouts for Blob Service Operations.</a> requestID is provides a client-generated, opaque value with a 1 KB
|
||||
// character limit that is recorded in the analytics logs when storage analytics logging is enabled.
|
||||
func (client serviceClient) SetProperties(ctx context.Context, storageServiceProperties StorageServiceProperties, timeout *int32, requestID *string) (*ServiceSetPropertiesResponse, error) {
|
||||
if err := validate([]validation{
|
||||
{targetValue: storageServiceProperties,
|
||||
constraints: []constraint{{target: "storageServiceProperties.Logging", name: null, rule: true,
|
||||
chain: []constraint{{target: "storageServiceProperties.Logging.Version", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.Logging.Delete", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.Logging.Read", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.Logging.Write", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.Logging.RetentionPolicy", name: null, rule: true,
|
||||
chain: []constraint{{target: "storageServiceProperties.Logging.RetentionPolicy.Enabled", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.Logging.RetentionPolicy.Days", name: null, rule: true,
|
||||
chain: []constraint{{target: "storageServiceProperties.Logging.RetentionPolicy.Days", name: inclusiveMinimum, rule: 1, chain: nil}}},
|
||||
}},
|
||||
}},
|
||||
{target: "storageServiceProperties.HourMetrics", name: null, rule: true,
|
||||
chain: []constraint{{target: "storageServiceProperties.HourMetrics.Version", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.HourMetrics.Enabled", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.HourMetrics.IncludeAPIs", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.HourMetrics.RetentionPolicy", name: null, rule: true,
|
||||
chain: []constraint{{target: "storageServiceProperties.HourMetrics.RetentionPolicy.Enabled", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.HourMetrics.RetentionPolicy.Days", name: null, rule: true,
|
||||
chain: []constraint{{target: "storageServiceProperties.HourMetrics.RetentionPolicy.Days", name: inclusiveMinimum, rule: 1, chain: nil}}},
|
||||
}},
|
||||
}},
|
||||
{target: "storageServiceProperties.MinuteMetrics", name: null, rule: true,
|
||||
chain: []constraint{{target: "storageServiceProperties.MinuteMetrics.Version", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.MinuteMetrics.Enabled", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.MinuteMetrics.IncludeAPIs", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.MinuteMetrics.RetentionPolicy", name: null, rule: true,
|
||||
chain: []constraint{{target: "storageServiceProperties.MinuteMetrics.RetentionPolicy.Enabled", name: null, rule: true, chain: nil},
|
||||
{target: "storageServiceProperties.MinuteMetrics.RetentionPolicy.Days", name: null, rule: true,
|
||||
chain: []constraint{{target: "storageServiceProperties.MinuteMetrics.RetentionPolicy.Days", name: inclusiveMinimum, rule: 1, chain: nil}}},
|
||||
}},
|
||||
}},
|
||||
{target: "storageServiceProperties.DefaultServiceVersion", name: null, rule: true, chain: nil}}},
|
||||
{targetValue: timeout,
|
||||
constraints: []constraint{{target: "timeout", name: null, rule: false,
|
||||
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := client.setPropertiesPreparer(storageServiceProperties, timeout, requestID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.setPropertiesResponder}, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.(*ServiceSetPropertiesResponse), err
|
||||
}
|
||||
|
||||
// setPropertiesPreparer prepares the SetProperties request.
|
||||
func (client serviceClient) setPropertiesPreparer(storageServiceProperties StorageServiceProperties, timeout *int32, requestID *string) (pipeline.Request, error) {
|
||||
req, err := pipeline.NewRequest("PUT", client.url, nil)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to create request")
|
||||
}
|
||||
params := req.URL.Query()
|
||||
if timeout != nil {
|
||||
params.Set("timeout", fmt.Sprintf("%v", *timeout))
|
||||
}
|
||||
params.Set("restype", "service")
|
||||
params.Set("comp", "properties")
|
||||
req.URL.RawQuery = params.Encode()
|
||||
req.Header.Set("x-ms-version", ServiceVersion)
|
||||
if requestID != nil {
|
||||
req.Header.Set("x-ms-client-request-id", *requestID)
|
||||
}
|
||||
b, err := xml.Marshal(storageServiceProperties)
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to marshal request body")
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/xml")
|
||||
err = req.SetBody(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return req, pipeline.NewError(err, "failed to set request body")
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// setPropertiesResponder handles the response to the SetProperties request.
|
||||
func (client serviceClient) setPropertiesResponder(resp pipeline.Response) (pipeline.Response, error) {
|
||||
err := validateResponse(resp, http.StatusOK, http.StatusAccepted)
|
||||
if resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ServiceSetPropertiesResponse{rawResponse: resp.Response()}, err
|
||||
}
|
367
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_validation.go
generated
vendored
367
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_validation.go
generated
vendored
|
@ -1,367 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Constraint stores constraint name, target field name
|
||||
// Rule and chain validations.
|
||||
type constraint struct {
|
||||
// Target field name for validation.
|
||||
target string
|
||||
|
||||
// Constraint name e.g. minLength, MaxLength, Pattern, etc.
|
||||
name string
|
||||
|
||||
// Rule for constraint e.g. greater than 10, less than 5 etc.
|
||||
rule interface{}
|
||||
|
||||
// Chain validations for struct type
|
||||
chain []constraint
|
||||
}
|
||||
|
||||
// Validation stores parameter-wise validation.
|
||||
type validation struct {
|
||||
targetValue interface{}
|
||||
constraints []constraint
|
||||
}
|
||||
|
||||
// Constraint list
|
||||
const (
|
||||
empty = "Empty"
|
||||
null = "Null"
|
||||
readOnly = "ReadOnly"
|
||||
pattern = "Pattern"
|
||||
maxLength = "MaxLength"
|
||||
minLength = "MinLength"
|
||||
maxItems = "MaxItems"
|
||||
minItems = "MinItems"
|
||||
multipleOf = "MultipleOf"
|
||||
uniqueItems = "UniqueItems"
|
||||
inclusiveMaximum = "InclusiveMaximum"
|
||||
exclusiveMaximum = "ExclusiveMaximum"
|
||||
exclusiveMinimum = "ExclusiveMinimum"
|
||||
inclusiveMinimum = "InclusiveMinimum"
|
||||
)
|
||||
|
||||
// Validate method validates constraints on parameter
|
||||
// passed in validation array.
|
||||
func validate(m []validation) error {
|
||||
for _, item := range m {
|
||||
v := reflect.ValueOf(item.targetValue)
|
||||
for _, constraint := range item.constraints {
|
||||
var err error
|
||||
switch v.Kind() {
|
||||
case reflect.Ptr:
|
||||
err = validatePtr(v, constraint)
|
||||
case reflect.String:
|
||||
err = validateString(v, constraint)
|
||||
case reflect.Struct:
|
||||
err = validateStruct(v, constraint)
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
err = validateInt(v, constraint)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
err = validateFloat(v, constraint)
|
||||
case reflect.Array, reflect.Slice, reflect.Map:
|
||||
err = validateArrayMap(v, constraint)
|
||||
default:
|
||||
err = createError(v, constraint, fmt.Sprintf("unknown type %v", v.Kind()))
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateStruct(x reflect.Value, v constraint, name ...string) error {
|
||||
//Get field name from target name which is in format a.b.c
|
||||
s := strings.Split(v.target, ".")
|
||||
f := x.FieldByName(s[len(s)-1])
|
||||
if isZero(f) {
|
||||
return createError(x, v, fmt.Sprintf("field %q doesn't exist", v.target))
|
||||
}
|
||||
err := validate([]validation{
|
||||
{
|
||||
targetValue: getInterfaceValue(f),
|
||||
constraints: []constraint{v},
|
||||
},
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func validatePtr(x reflect.Value, v constraint) error {
|
||||
if v.name == readOnly {
|
||||
if !x.IsNil() {
|
||||
return createError(x.Elem(), v, "readonly parameter; must send as nil or empty in request")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if x.IsNil() {
|
||||
return checkNil(x, v)
|
||||
}
|
||||
if v.chain != nil {
|
||||
return validate([]validation{
|
||||
{
|
||||
targetValue: getInterfaceValue(x.Elem()),
|
||||
constraints: v.chain,
|
||||
},
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateInt(x reflect.Value, v constraint) error {
|
||||
i := x.Int()
|
||||
r, ok := v.rule.(int)
|
||||
if !ok {
|
||||
return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.name, v.rule))
|
||||
}
|
||||
switch v.name {
|
||||
case multipleOf:
|
||||
if i%int64(r) != 0 {
|
||||
return createError(x, v, fmt.Sprintf("value must be a multiple of %v", r))
|
||||
}
|
||||
case exclusiveMinimum:
|
||||
if i <= int64(r) {
|
||||
return createError(x, v, fmt.Sprintf("value must be greater than %v", r))
|
||||
}
|
||||
case exclusiveMaximum:
|
||||
if i >= int64(r) {
|
||||
return createError(x, v, fmt.Sprintf("value must be less than %v", r))
|
||||
}
|
||||
case inclusiveMinimum:
|
||||
if i < int64(r) {
|
||||
return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r))
|
||||
}
|
||||
case inclusiveMaximum:
|
||||
if i > int64(r) {
|
||||
return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r))
|
||||
}
|
||||
default:
|
||||
return createError(x, v, fmt.Sprintf("constraint %v is not applicable for type integer", v.name))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateFloat(x reflect.Value, v constraint) error {
|
||||
f := x.Float()
|
||||
r, ok := v.rule.(float64)
|
||||
if !ok {
|
||||
return createError(x, v, fmt.Sprintf("rule must be float value for %v constraint; got: %v", v.name, v.rule))
|
||||
}
|
||||
switch v.name {
|
||||
case exclusiveMinimum:
|
||||
if f <= r {
|
||||
return createError(x, v, fmt.Sprintf("value must be greater than %v", r))
|
||||
}
|
||||
case exclusiveMaximum:
|
||||
if f >= r {
|
||||
return createError(x, v, fmt.Sprintf("value must be less than %v", r))
|
||||
}
|
||||
case inclusiveMinimum:
|
||||
if f < r {
|
||||
return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r))
|
||||
}
|
||||
case inclusiveMaximum:
|
||||
if f > r {
|
||||
return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r))
|
||||
}
|
||||
default:
|
||||
return createError(x, v, fmt.Sprintf("constraint %s is not applicable for type float", v.name))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateString(x reflect.Value, v constraint) error {
|
||||
s := x.String()
|
||||
switch v.name {
|
||||
case empty:
|
||||
if len(s) == 0 {
|
||||
return checkEmpty(x, v)
|
||||
}
|
||||
case pattern:
|
||||
reg, err := regexp.Compile(v.rule.(string))
|
||||
if err != nil {
|
||||
return createError(x, v, err.Error())
|
||||
}
|
||||
if !reg.MatchString(s) {
|
||||
return createError(x, v, fmt.Sprintf("value doesn't match pattern %v", v.rule))
|
||||
}
|
||||
case maxLength:
|
||||
if _, ok := v.rule.(int); !ok {
|
||||
return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.name, v.rule))
|
||||
}
|
||||
if len(s) > v.rule.(int) {
|
||||
return createError(x, v, fmt.Sprintf("value length must be less than %v", v.rule))
|
||||
}
|
||||
case minLength:
|
||||
if _, ok := v.rule.(int); !ok {
|
||||
return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.name, v.rule))
|
||||
}
|
||||
if len(s) < v.rule.(int) {
|
||||
return createError(x, v, fmt.Sprintf("value length must be greater than %v", v.rule))
|
||||
}
|
||||
case readOnly:
|
||||
if len(s) > 0 {
|
||||
return createError(reflect.ValueOf(s), v, "readonly parameter; must send as nil or empty in request")
|
||||
}
|
||||
default:
|
||||
return createError(x, v, fmt.Sprintf("constraint %s is not applicable to string type", v.name))
|
||||
}
|
||||
if v.chain != nil {
|
||||
return validate([]validation{
|
||||
{
|
||||
targetValue: getInterfaceValue(x),
|
||||
constraints: v.chain,
|
||||
},
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateArrayMap(x reflect.Value, v constraint) error {
|
||||
switch v.name {
|
||||
case null:
|
||||
if x.IsNil() {
|
||||
return checkNil(x, v)
|
||||
}
|
||||
case empty:
|
||||
if x.IsNil() || x.Len() == 0 {
|
||||
return checkEmpty(x, v)
|
||||
}
|
||||
case maxItems:
|
||||
if _, ok := v.rule.(int); !ok {
|
||||
return createError(x, v, fmt.Sprintf("rule must be integer for %v constraint; got: %v", v.name, v.rule))
|
||||
}
|
||||
if x.Len() > v.rule.(int) {
|
||||
return createError(x, v, fmt.Sprintf("maximum item limit is %v; got: %v", v.rule, x.Len()))
|
||||
}
|
||||
case minItems:
|
||||
if _, ok := v.rule.(int); !ok {
|
||||
return createError(x, v, fmt.Sprintf("rule must be integer for %v constraint; got: %v", v.name, v.rule))
|
||||
}
|
||||
if x.Len() < v.rule.(int) {
|
||||
return createError(x, v, fmt.Sprintf("minimum item limit is %v; got: %v", v.rule, x.Len()))
|
||||
}
|
||||
case uniqueItems:
|
||||
if x.Kind() == reflect.Array || x.Kind() == reflect.Slice {
|
||||
if !checkForUniqueInArray(x) {
|
||||
return createError(x, v, fmt.Sprintf("all items in parameter %q must be unique; got:%v", v.target, x))
|
||||
}
|
||||
} else if x.Kind() == reflect.Map {
|
||||
if !checkForUniqueInMap(x) {
|
||||
return createError(x, v, fmt.Sprintf("all items in parameter %q must be unique; got:%v", v.target, x))
|
||||
}
|
||||
} else {
|
||||
return createError(x, v, fmt.Sprintf("type must be array, slice or map for constraint %v; got: %v", v.name, x.Kind()))
|
||||
}
|
||||
case readOnly:
|
||||
if x.Len() != 0 {
|
||||
return createError(x, v, "readonly parameter; must send as nil or empty in request")
|
||||
}
|
||||
case pattern:
|
||||
reg, err := regexp.Compile(v.rule.(string))
|
||||
if err != nil {
|
||||
return createError(x, v, err.Error())
|
||||
}
|
||||
keys := x.MapKeys()
|
||||
for _, k := range keys {
|
||||
if !reg.MatchString(k.String()) {
|
||||
return createError(k, v, fmt.Sprintf("map key doesn't match pattern %v", v.rule))
|
||||
}
|
||||
}
|
||||
default:
|
||||
return createError(x, v, fmt.Sprintf("constraint %v is not applicable to array, slice and map type", v.name))
|
||||
}
|
||||
if v.chain != nil {
|
||||
return validate([]validation{
|
||||
{
|
||||
targetValue: getInterfaceValue(x),
|
||||
constraints: v.chain,
|
||||
},
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkNil(x reflect.Value, v constraint) error {
|
||||
if _, ok := v.rule.(bool); !ok {
|
||||
return createError(x, v, fmt.Sprintf("rule must be bool value for %v constraint; got: %v", v.name, v.rule))
|
||||
}
|
||||
if v.rule.(bool) {
|
||||
return createError(x, v, "value can not be null; required parameter")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkEmpty(x reflect.Value, v constraint) error {
|
||||
if _, ok := v.rule.(bool); !ok {
|
||||
return createError(x, v, fmt.Sprintf("rule must be bool value for %v constraint; got: %v", v.name, v.rule))
|
||||
}
|
||||
if v.rule.(bool) {
|
||||
return createError(x, v, "value can not be null or empty; required parameter")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkForUniqueInArray(x reflect.Value) bool {
|
||||
if x == reflect.Zero(reflect.TypeOf(x)) || x.Len() == 0 {
|
||||
return false
|
||||
}
|
||||
arrOfInterface := make([]interface{}, x.Len())
|
||||
for i := 0; i < x.Len(); i++ {
|
||||
arrOfInterface[i] = x.Index(i).Interface()
|
||||
}
|
||||
m := make(map[interface{}]bool)
|
||||
for _, val := range arrOfInterface {
|
||||
if m[val] {
|
||||
return false
|
||||
}
|
||||
m[val] = true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func checkForUniqueInMap(x reflect.Value) bool {
|
||||
if x == reflect.Zero(reflect.TypeOf(x)) || x.Len() == 0 {
|
||||
return false
|
||||
}
|
||||
mapOfInterface := make(map[interface{}]interface{}, x.Len())
|
||||
keys := x.MapKeys()
|
||||
for _, k := range keys {
|
||||
mapOfInterface[k.Interface()] = x.MapIndex(k).Interface()
|
||||
}
|
||||
m := make(map[interface{}]bool)
|
||||
for _, val := range mapOfInterface {
|
||||
if m[val] {
|
||||
return false
|
||||
}
|
||||
m[val] = true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func getInterfaceValue(x reflect.Value) interface{} {
|
||||
if x.Kind() == reflect.Invalid {
|
||||
return nil
|
||||
}
|
||||
return x.Interface()
|
||||
}
|
||||
|
||||
func isZero(x interface{}) bool {
|
||||
return x == reflect.Zero(reflect.TypeOf(x)).Interface()
|
||||
}
|
||||
|
||||
func createError(x reflect.Value, v constraint, message string) error {
|
||||
return pipeline.NewError(nil, fmt.Sprintf("validation failed: parameter=%s constraint=%s value=%#v details: %s",
|
||||
v.target, v.name, getInterfaceValue(x), message))
|
||||
}
|
14
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_version.go
generated
vendored
14
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_generated_version.go
generated
vendored
|
@ -1,14 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
// UserAgent returns the UserAgent string to use when sending http.Requests.
|
||||
func UserAgent() string {
|
||||
return "Azure-SDK-For-Go/0.0.0 arm-azblob/2016-05-31"
|
||||
}
|
||||
|
||||
// Version returns the semantic version (see http://semver.org) of the client.
|
||||
func Version() string {
|
||||
return "0.0.0"
|
||||
}
|
114
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_response_helpers.go
generated
vendored
114
vendor/github.com/Azure/azure-storage-blob-go/2016-05-31/azblob/zz_response_helpers.go
generated
vendored
|
@ -1,114 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BlobHTTPHeaders contains read/writeable blob properties.
|
||||
type BlobHTTPHeaders struct {
|
||||
ContentType string
|
||||
ContentMD5 [md5.Size]byte
|
||||
ContentEncoding string
|
||||
ContentLanguage string
|
||||
ContentDisposition string
|
||||
CacheControl string
|
||||
}
|
||||
|
||||
func (h BlobHTTPHeaders) contentMD5Pointer() *string {
|
||||
if h.ContentMD5 == [md5.Size]byte{} {
|
||||
return nil
|
||||
}
|
||||
str := base64.StdEncoding.EncodeToString(h.ContentMD5[:])
|
||||
return &str
|
||||
}
|
||||
|
||||
// NewHTTPHeaders returns the user-modifiable properties for this blob.
|
||||
func (gr GetResponse) NewHTTPHeaders() BlobHTTPHeaders {
|
||||
return BlobHTTPHeaders{
|
||||
ContentType: gr.ContentType(),
|
||||
ContentEncoding: gr.ContentEncoding(),
|
||||
ContentLanguage: gr.ContentLanguage(),
|
||||
ContentDisposition: gr.ContentDisposition(),
|
||||
CacheControl: gr.CacheControl(),
|
||||
ContentMD5: gr.ContentMD5(),
|
||||
}
|
||||
}
|
||||
|
||||
// NewHTTPHeaders returns the user-modifiable properties for this blob.
|
||||
func (bgpr BlobsGetPropertiesResponse) NewHTTPHeaders() BlobHTTPHeaders {
|
||||
return BlobHTTPHeaders{
|
||||
ContentType: bgpr.ContentType(),
|
||||
ContentEncoding: bgpr.ContentEncoding(),
|
||||
ContentLanguage: bgpr.ContentLanguage(),
|
||||
ContentDisposition: bgpr.ContentDisposition(),
|
||||
CacheControl: bgpr.CacheControl(),
|
||||
ContentMD5: bgpr.ContentMD5(),
|
||||
}
|
||||
}
|
||||
|
||||
func md5StringToMD5(md5String string) (hash [md5.Size]byte) {
|
||||
if md5String == "" {
|
||||
return
|
||||
}
|
||||
md5Slice, err := base64.StdEncoding.DecodeString(md5String)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
copy(hash[:], md5Slice)
|
||||
return
|
||||
}
|
||||
|
||||
// ContentMD5 returns the value for header Content-MD5.
|
||||
func (ababr AppendBlobsAppendBlockResponse) ContentMD5() [md5.Size]byte {
|
||||
return md5StringToMD5(ababr.rawResponse.Header.Get("Content-MD5"))
|
||||
}
|
||||
|
||||
// ContentMD5 returns the value for header Content-MD5.
|
||||
func (bgpr BlobsGetPropertiesResponse) ContentMD5() [md5.Size]byte {
|
||||
return md5StringToMD5(bgpr.rawResponse.Header.Get("Content-MD5"))
|
||||
}
|
||||
|
||||
// ContentMD5 returns the value for header Content-MD5.
|
||||
func (bpr BlobsPutResponse) ContentMD5() [md5.Size]byte {
|
||||
return md5StringToMD5(bpr.rawResponse.Header.Get("Content-MD5"))
|
||||
}
|
||||
|
||||
// ContentMD5 returns the value for header Content-MD5.
|
||||
func (bbpblr BlockBlobsPutBlockListResponse) ContentMD5() [md5.Size]byte {
|
||||
return md5StringToMD5(bbpblr.rawResponse.Header.Get("Content-MD5"))
|
||||
}
|
||||
|
||||
// ContentMD5 returns the value for header Content-MD5.
|
||||
func (bbpbr BlockBlobsPutBlockResponse) ContentMD5() [md5.Size]byte {
|
||||
return md5StringToMD5(bbpbr.rawResponse.Header.Get("Content-MD5"))
|
||||
}
|
||||
|
||||
// BlobContentMD5 returns the value for header x-ms-blob-content-md5.
|
||||
func (gr GetResponse) BlobContentMD5() [md5.Size]byte {
|
||||
return md5StringToMD5(gr.rawResponse.Header.Get("x-ms-blob-content-md5"))
|
||||
}
|
||||
|
||||
// ContentMD5 returns the value for header Content-MD5.
|
||||
func (gr GetResponse) ContentMD5() [md5.Size]byte {
|
||||
return md5StringToMD5(gr.rawResponse.Header.Get("Content-MD5"))
|
||||
}
|
||||
|
||||
// ContentMD5 returns the value for header Content-MD5.
|
||||
func (pbppr PageBlobsPutPageResponse) ContentMD5() [md5.Size]byte {
|
||||
return md5StringToMD5(pbppr.rawResponse.Header.Get("Content-MD5"))
|
||||
}
|
||||
|
||||
// DestinationSnapshot returns the value for header x-ms-copy-destination-snapshot
|
||||
func (bgpr BlobsGetPropertiesResponse) DestinationSnapshot() time.Time {
|
||||
if bgpr.IsIncrementalCopy() == "true" {
|
||||
t := bgpr.rawResponse.Header.Get("x-ms-copy-destination-snapshot")
|
||||
snapshot, err := time.Parse("2006-01-02T15:04:05Z", t)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return snapshot
|
||||
}
|
||||
return time.Time{}
|
||||
}
|
67
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/access_conditions.go
generated
vendored
67
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/access_conditions.go
generated
vendored
|
@ -1,67 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// HTTPAccessConditions identifies standard HTTP access conditions which you optionally set.
|
||||
type HTTPAccessConditions struct {
|
||||
IfModifiedSince time.Time
|
||||
IfUnmodifiedSince time.Time
|
||||
IfMatch ETag
|
||||
IfNoneMatch ETag
|
||||
}
|
||||
|
||||
// pointers is for internal infrastructure. It returns the fields as pointers.
|
||||
func (ac HTTPAccessConditions) pointers() (ims *time.Time, ius *time.Time, ime *ETag, inme *ETag) {
|
||||
if !ac.IfModifiedSince.IsZero() {
|
||||
ims = &ac.IfModifiedSince
|
||||
}
|
||||
if !ac.IfUnmodifiedSince.IsZero() {
|
||||
ius = &ac.IfUnmodifiedSince
|
||||
}
|
||||
if ac.IfMatch != ETagNone {
|
||||
ime = &ac.IfMatch
|
||||
}
|
||||
if ac.IfNoneMatch != ETagNone {
|
||||
inme = &ac.IfNoneMatch
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ContainerAccessConditions identifies container-specific access conditions which you optionally set.
|
||||
type ContainerAccessConditions struct {
|
||||
HTTPAccessConditions
|
||||
LeaseAccessConditions
|
||||
}
|
||||
|
||||
// BlobAccessConditions identifies blob-specific access conditions which you optionally set.
|
||||
type BlobAccessConditions struct {
|
||||
HTTPAccessConditions
|
||||
LeaseAccessConditions
|
||||
AppendBlobAccessConditions
|
||||
PageBlobAccessConditions
|
||||
}
|
||||
|
||||
// LeaseAccessConditions identifies lease access conditions for a container or blob which you optionally set.
|
||||
type LeaseAccessConditions struct {
|
||||
LeaseID string
|
||||
}
|
||||
|
||||
// pointers is for internal infrastructure. It returns the fields as pointers.
|
||||
func (ac LeaseAccessConditions) pointers() (leaseID *string) {
|
||||
if ac.LeaseID != "" {
|
||||
leaseID = &ac.LeaseID
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
// getInt32 is for internal infrastructure. It is used with access condition values where
|
||||
// 0 (the default setting) is meaningful. The library interprets 0 as do not send the header
|
||||
// and the privately-storage field in the access condition object is stored as +1 higher than desired.
|
||||
// THis method returns true, if the value is > 0 (explicitly set) and the stored value - 1 (the set desired value).
|
||||
func getInt32(value int32) (bool, int32) {
|
||||
return value > 0, value - 1
|
||||
}
|
||||
*/
|
79
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/atomicmorph.go
generated
vendored
79
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/atomicmorph.go
generated
vendored
|
@ -1,79 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
// AtomicMorpherInt32 identifies a method passed to and invoked by the AtomicMorphInt32 function.
|
||||
// The AtomicMorpher callback is passed a startValue and based on this value it returns
|
||||
// what the new value should be and the result that AtomicMorph should return to its caller.
|
||||
type AtomicMorpherInt32 func(startVal int32) (val int32, morphResult interface{})
|
||||
|
||||
// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function.
|
||||
func AtomicMorphInt32(target *int32, morpher AtomicMorpherInt32) interface{} {
|
||||
if target == nil || morpher == nil {
|
||||
panic("target and morpher mut not be nil")
|
||||
}
|
||||
for {
|
||||
currentVal := atomic.LoadInt32(target)
|
||||
desiredVal, morphResult := morpher(currentVal)
|
||||
if atomic.CompareAndSwapInt32(target, currentVal, desiredVal) {
|
||||
return morphResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AtomicMorpherUint32 identifies a method passed to and invoked by the AtomicMorph function.
|
||||
// The AtomicMorpher callback is passed a startValue and based on this value it returns
|
||||
// what the new value should be and the result that AtomicMorph should return to its caller.
|
||||
type AtomicMorpherUint32 func(startVal uint32) (val uint32, morphResult interface{})
|
||||
|
||||
// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function.
|
||||
func AtomicMorphUint32(target *uint32, morpher AtomicMorpherUint32) interface{} {
|
||||
if target == nil || morpher == nil {
|
||||
panic("target and morpher mut not be nil")
|
||||
}
|
||||
for {
|
||||
currentVal := atomic.LoadUint32(target)
|
||||
desiredVal, morphResult := morpher(currentVal)
|
||||
if atomic.CompareAndSwapUint32(target, currentVal, desiredVal) {
|
||||
return morphResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AtomicMorpherUint64 identifies a method passed to and invoked by the AtomicMorphUint64 function.
|
||||
// The AtomicMorpher callback is passed a startValue and based on this value it returns
|
||||
// what the new value should be and the result that AtomicMorph should return to its caller.
|
||||
type AtomicMorpherInt64 func(startVal int64) (val int64, morphResult interface{})
|
||||
|
||||
// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function.
|
||||
func AtomicMorphInt64(target *int64, morpher AtomicMorpherInt64) interface{} {
|
||||
if target == nil || morpher == nil {
|
||||
panic("target and morpher mut not be nil")
|
||||
}
|
||||
for {
|
||||
currentVal := atomic.LoadInt64(target)
|
||||
desiredVal, morphResult := morpher(currentVal)
|
||||
if atomic.CompareAndSwapInt64(target, currentVal, desiredVal) {
|
||||
return morphResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AtomicMorpherUint64 identifies a method passed to and invoked by the AtomicMorphUint64 function.
|
||||
// The AtomicMorpher callback is passed a startValue and based on this value it returns
|
||||
// what the new value should be and the result that AtomicMorph should return to its caller.
|
||||
type AtomicMorpherUint64 func(startVal uint64) (val uint64, morphResult interface{})
|
||||
|
||||
// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function.
|
||||
func AtomicMorphUint64(target *uint64, morpher AtomicMorpherUint64) interface{} {
|
||||
if target == nil || morpher == nil {
|
||||
panic("target and morpher mut not be nil")
|
||||
}
|
||||
for {
|
||||
currentVal := atomic.LoadUint64(target)
|
||||
desiredVal, morphResult := morpher(currentVal)
|
||||
if atomic.CompareAndSwapUint64(target, currentVal, desiredVal) {
|
||||
return morphResult
|
||||
}
|
||||
}
|
||||
}
|
510
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/highlevel.go
generated
vendored
510
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/highlevel.go
generated
vendored
|
@ -1,510 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"bytes"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// CommonResponseHeaders returns the headers common to all blob REST API responses.
|
||||
type CommonResponse interface {
|
||||
// ETag returns the value for header ETag.
|
||||
ETag() ETag
|
||||
|
||||
// LastModified returns the value for header Last-Modified.
|
||||
LastModified() time.Time
|
||||
|
||||
// RequestID returns the value for header x-ms-request-id.
|
||||
RequestID() string
|
||||
|
||||
// Date returns the value for header Date.
|
||||
Date() time.Time
|
||||
|
||||
// Version returns the value for header x-ms-version.
|
||||
Version() string
|
||||
|
||||
// Response returns the raw HTTP response object.
|
||||
Response() *http.Response
|
||||
}
|
||||
|
||||
// UploadToBlockBlobOptions identifies options used by the UploadBufferToBlockBlob and UploadFileToBlockBlob functions.
|
||||
type UploadToBlockBlobOptions struct {
|
||||
// BlockSize specifies the block size to use; the default (and maximum size) is BlockBlobMaxStageBlockBytes.
|
||||
BlockSize int64
|
||||
|
||||
// Progress is a function that is invoked periodically as bytes are sent to the BlockBlobURL.
|
||||
Progress pipeline.ProgressReceiver
|
||||
|
||||
// BlobHTTPHeaders indicates the HTTP headers to be associated with the blob.
|
||||
BlobHTTPHeaders BlobHTTPHeaders
|
||||
|
||||
// Metadata indicates the metadata to be associated with the blob when PutBlockList is called.
|
||||
Metadata Metadata
|
||||
|
||||
// AccessConditions indicates the access conditions for the block blob.
|
||||
AccessConditions BlobAccessConditions
|
||||
|
||||
// Parallelism indicates the maximum number of blocks to upload in parallel (0=default)
|
||||
Parallelism uint16
|
||||
}
|
||||
|
||||
// UploadBufferToBlockBlob uploads a buffer in blocks to a block blob.
|
||||
func UploadBufferToBlockBlob(ctx context.Context, b []byte,
|
||||
blockBlobURL BlockBlobURL, o UploadToBlockBlobOptions) (CommonResponse, error) {
|
||||
|
||||
// Validate parameters and set defaults
|
||||
if o.BlockSize < 0 || o.BlockSize > BlockBlobMaxUploadBlobBytes {
|
||||
panic(fmt.Sprintf("BlockSize option must be > 0 and <= %d", BlockBlobMaxUploadBlobBytes))
|
||||
}
|
||||
if o.BlockSize == 0 {
|
||||
o.BlockSize = BlockBlobMaxUploadBlobBytes // Default if unspecified
|
||||
}
|
||||
size := int64(len(b))
|
||||
|
||||
if size <= BlockBlobMaxUploadBlobBytes {
|
||||
// If the size can fit in 1 Upload call, do it this way
|
||||
var body io.ReadSeeker = bytes.NewReader(b)
|
||||
if o.Progress != nil {
|
||||
body = pipeline.NewRequestBodyProgress(body, o.Progress)
|
||||
}
|
||||
return blockBlobURL.Upload(ctx, body, o.BlobHTTPHeaders, o.Metadata, o.AccessConditions)
|
||||
}
|
||||
|
||||
var numBlocks = uint16(((size - 1) / o.BlockSize) + 1)
|
||||
if numBlocks > BlockBlobMaxBlocks {
|
||||
panic(fmt.Sprintf("The buffer's size is too big or the BlockSize is too small; the number of blocks must be <= %d", BlockBlobMaxBlocks))
|
||||
}
|
||||
|
||||
blockIDList := make([]string, numBlocks) // Base-64 encoded block IDs
|
||||
progress := int64(0)
|
||||
progressLock := &sync.Mutex{}
|
||||
|
||||
err := doBatchTransfer(ctx, batchTransferOptions{
|
||||
operationName: "UploadBufferToBlockBlob",
|
||||
transferSize: size,
|
||||
chunkSize: o.BlockSize,
|
||||
parallelism: o.Parallelism,
|
||||
operation: func(offset int64, count int64) error {
|
||||
// This function is called once per block.
|
||||
// It is passed this block's offset within the buffer and its count of bytes
|
||||
// Prepare to read the proper block/section of the buffer
|
||||
var body io.ReadSeeker = bytes.NewReader(b[offset : offset+count])
|
||||
blockNum := offset / o.BlockSize
|
||||
if o.Progress != nil {
|
||||
blockProgress := int64(0)
|
||||
body = pipeline.NewRequestBodyProgress(body,
|
||||
func(bytesTransferred int64) {
|
||||
diff := bytesTransferred - blockProgress
|
||||
blockProgress = bytesTransferred
|
||||
progressLock.Lock() // 1 goroutine at a time gets a progress report
|
||||
progress += diff
|
||||
o.Progress(progress)
|
||||
progressLock.Unlock()
|
||||
})
|
||||
}
|
||||
|
||||
// Block IDs are unique values to avoid issue if 2+ clients are uploading blocks
|
||||
// at the same time causing PutBlockList to get a mix of blocks from all the clients.
|
||||
blockIDList[blockNum] = base64.StdEncoding.EncodeToString(newUUID().bytes())
|
||||
_, err := blockBlobURL.StageBlock(ctx, blockIDList[blockNum], body, o.AccessConditions.LeaseAccessConditions)
|
||||
return err
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// All put blocks were successful, call Put Block List to finalize the blob
|
||||
return blockBlobURL.CommitBlockList(ctx, blockIDList, o.BlobHTTPHeaders, o.Metadata, o.AccessConditions)
|
||||
}
|
||||
|
||||
// UploadFileToBlockBlob uploads a file in blocks to a block blob.
|
||||
func UploadFileToBlockBlob(ctx context.Context, file *os.File,
|
||||
blockBlobURL BlockBlobURL, o UploadToBlockBlobOptions) (CommonResponse, error) {
|
||||
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := mmf{} // Default to an empty slice; used for 0-size file
|
||||
if stat.Size() != 0 {
|
||||
m, err = newMMF(file, false, 0, int(stat.Size()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer m.unmap()
|
||||
}
|
||||
return UploadBufferToBlockBlob(ctx, m, blockBlobURL, o)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
const BlobDefaultDownloadBlockSize = int64(4 * 1024 * 1024) // 4MB
|
||||
|
||||
// DownloadFromAzureFileOptions identifies options used by the DownloadAzureFileToBuffer and DownloadAzureFileToFile functions.
|
||||
type DownloadFromBlobOptions struct {
|
||||
// BlockSize specifies the block size to use for each parallel download; the default size is BlobDefaultDownloadBlockSize.
|
||||
BlockSize int64
|
||||
|
||||
// Progress is a function that is invoked periodically as bytes are received.
|
||||
Progress pipeline.ProgressReceiver
|
||||
|
||||
// AccessConditions indicates the access conditions used when making HTTP GET requests against the blob.
|
||||
AccessConditions BlobAccessConditions
|
||||
|
||||
// Parallelism indicates the maximum number of blocks to download in parallel (0=default)
|
||||
Parallelism uint16
|
||||
|
||||
// RetryReaderOptionsPerBlock is used when downloading each block.
|
||||
RetryReaderOptionsPerBlock RetryReaderOptions
|
||||
}
|
||||
|
||||
// downloadAzureFileToBuffer downloads an Azure file to a buffer with parallel.
|
||||
func downloadBlobToBuffer(ctx context.Context, blobURL BlobURL, offset int64, count int64,
|
||||
ac BlobAccessConditions, b []byte, o DownloadFromBlobOptions,
|
||||
initialDownloadResponse *DownloadResponse) error {
|
||||
// Validate parameters, and set defaults.
|
||||
if o.BlockSize < 0 {
|
||||
panic("BlockSize option must be >= 0")
|
||||
}
|
||||
if o.BlockSize == 0 {
|
||||
o.BlockSize = BlobDefaultDownloadBlockSize
|
||||
}
|
||||
|
||||
if offset < 0 {
|
||||
panic("offset option must be >= 0")
|
||||
}
|
||||
|
||||
if count < 0 {
|
||||
panic("count option must be >= 0")
|
||||
}
|
||||
|
||||
if count == CountToEnd { // If size not specified, calculate it
|
||||
if initialDownloadResponse != nil {
|
||||
count = initialDownloadResponse.ContentLength() - offset // if we have the length, use it
|
||||
} else {
|
||||
// If we don't have the length at all, get it
|
||||
dr, err := blobURL.Download(ctx, 0, CountToEnd, ac, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
count = dr.ContentLength() - offset
|
||||
}
|
||||
}
|
||||
|
||||
if int64(len(b)) < count {
|
||||
panic(fmt.Errorf("the buffer's size should be equal to or larger than the request count of bytes: %d", count))
|
||||
}
|
||||
|
||||
// Prepare and do parallel download.
|
||||
progress := int64(0)
|
||||
progressLock := &sync.Mutex{}
|
||||
|
||||
err := doBatchTransfer(ctx, batchTransferOptions{
|
||||
operationName: "downloadBlobToBuffer",
|
||||
transferSize: count,
|
||||
chunkSize: o.BlockSize,
|
||||
parallelism: o.Parallelism,
|
||||
operation: func(chunkStart int64, count int64) error {
|
||||
dr, err := blobURL.Download(ctx, chunkStart+ offset, count, ac, false)
|
||||
body := dr.Body(o.RetryReaderOptionsPerBlock)
|
||||
if o.Progress != nil {
|
||||
rangeProgress := int64(0)
|
||||
body = pipeline.NewResponseBodyProgress(
|
||||
body,
|
||||
func(bytesTransferred int64) {
|
||||
diff := bytesTransferred - rangeProgress
|
||||
rangeProgress = bytesTransferred
|
||||
progressLock.Lock()
|
||||
progress += diff
|
||||
o.Progress(progress)
|
||||
progressLock.Unlock()
|
||||
})
|
||||
}
|
||||
_, err = io.ReadFull(body, b[chunkStart:chunkStart+count])
|
||||
body.Close()
|
||||
return err
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DownloadAzureFileToBuffer downloads an Azure file to a buffer with parallel.
|
||||
// Offset and count are optional, pass 0 for both to download the entire blob.
|
||||
func DownloadBlobToBuffer(ctx context.Context, blobURL BlobURL, offset int64, count int64,
|
||||
ac BlobAccessConditions, b []byte, o DownloadFromBlobOptions) error {
|
||||
return downloadBlobToBuffer(ctx, blobURL, offset, count, ac, b, o, nil)
|
||||
}
|
||||
|
||||
// DownloadBlobToFile downloads an Azure file to a local file.
|
||||
// The file would be truncated if the size doesn't match.
|
||||
// Offset and count are optional, pass 0 for both to download the entire blob.
|
||||
func DownloadBlobToFile(ctx context.Context, blobURL BlobURL, offset int64, count int64,
|
||||
ac BlobAccessConditions, file *os.File, o DownloadFromBlobOptions) error {
|
||||
// 1. Validate parameters.
|
||||
if file == nil {
|
||||
panic("file must not be nil")
|
||||
}
|
||||
|
||||
// 2. Calculate the size of the destination file
|
||||
var size int64
|
||||
|
||||
if count == CountToEnd {
|
||||
// Try to get Azure file's size
|
||||
props, err := blobURL.GetProperties(ctx, ac)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
size = props.ContentLength() - offset
|
||||
} else {
|
||||
size = count
|
||||
}
|
||||
|
||||
// 3. Compare and try to resize local file's size if it doesn't match Azure file's size.
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if stat.Size() != size {
|
||||
if err = file.Truncate(size); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if size > 0 {
|
||||
// 4. Set mmap and call DownloadAzureFileToBuffer.
|
||||
m, err := newMMF(file, true, 0, int(size))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer m.unmap()
|
||||
return downloadBlobToBuffer(ctx, blobURL, offset, size, ac, m, o, nil)
|
||||
} else { // if the blob's size is 0, there is no need in downloading it
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// BatchTransferOptions identifies options used by doBatchTransfer.
|
||||
type batchTransferOptions struct {
|
||||
transferSize int64
|
||||
chunkSize int64
|
||||
parallelism uint16
|
||||
operation func(offset int64, chunkSize int64) error
|
||||
operationName string
|
||||
}
|
||||
|
||||
// doBatchTransfer helps to execute operations in a batch manner.
|
||||
func doBatchTransfer(ctx context.Context, o batchTransferOptions) error {
|
||||
// Prepare and do parallel operations.
|
||||
numChunks := uint16(((o.transferSize - 1) / o.chunkSize) + 1)
|
||||
operationChannel := make(chan func() error, o.parallelism) // Create the channel that release 'parallelism' goroutines concurrently
|
||||
operationResponseChannel := make(chan error, numChunks) // Holds each response
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
// Create the goroutines that process each operation (in parallel).
|
||||
if o.parallelism == 0 {
|
||||
o.parallelism = 5 // default parallelism
|
||||
}
|
||||
for g := uint16(0); g < o.parallelism; g++ {
|
||||
//grIndex := g
|
||||
go func() {
|
||||
for f := range operationChannel {
|
||||
//fmt.Printf("[%s] gr-%d start action\n", o.operationName, grIndex)
|
||||
err := f()
|
||||
operationResponseChannel <- err
|
||||
//fmt.Printf("[%s] gr-%d end action\n", o.operationName, grIndex)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Add each chunk's operation to the channel.
|
||||
for chunkNum := uint16(0); chunkNum < numChunks; chunkNum++ {
|
||||
curChunkSize := o.chunkSize
|
||||
|
||||
if chunkNum == numChunks-1 { // Last chunk
|
||||
curChunkSize = o.transferSize - (int64(chunkNum) * o.chunkSize) // Remove size of all transferred chunks from total
|
||||
}
|
||||
offset := int64(chunkNum) * o.chunkSize
|
||||
|
||||
operationChannel <- func() error {
|
||||
return o.operation(offset, curChunkSize)
|
||||
}
|
||||
}
|
||||
close(operationChannel)
|
||||
|
||||
// Wait for the operations to complete.
|
||||
for chunkNum := uint16(0); chunkNum < numChunks; chunkNum++ {
|
||||
responseError := <-operationResponseChannel
|
||||
if responseError != nil {
|
||||
cancel() // As soon as any operation fails, cancel all remaining operation calls
|
||||
return responseError // No need to process anymore responses
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type UploadStreamToBlockBlobOptions struct {
|
||||
BufferSize int
|
||||
MaxBuffers int
|
||||
BlobHTTPHeaders BlobHTTPHeaders
|
||||
Metadata Metadata
|
||||
AccessConditions BlobAccessConditions
|
||||
}
|
||||
|
||||
func UploadStreamToBlockBlob(ctx context.Context, reader io.Reader, blockBlobURL BlockBlobURL,
|
||||
o UploadStreamToBlockBlobOptions) (CommonResponse, error) {
|
||||
result, err := uploadStream(ctx, reader,
|
||||
UploadStreamOptions{BufferSize: o.BufferSize, MaxBuffers: o.MaxBuffers},
|
||||
&uploadStreamToBlockBlobOptions{b: blockBlobURL, o: o, blockIDPrefix: newUUID()})
|
||||
return result.(CommonResponse), err
|
||||
}
|
||||
|
||||
type uploadStreamToBlockBlobOptions struct {
|
||||
b BlockBlobURL
|
||||
o UploadStreamToBlockBlobOptions
|
||||
blockIDPrefix uuid // UUID used with all blockIDs
|
||||
maxBlockNum uint32 // defaults to 0
|
||||
firstBlock []byte // Used only if maxBlockNum is 0
|
||||
}
|
||||
|
||||
func (t *uploadStreamToBlockBlobOptions) start(ctx context.Context) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (t *uploadStreamToBlockBlobOptions) chunk(ctx context.Context, num uint32, buffer []byte) error {
|
||||
if num == 0 && len(buffer) < t.o.BufferSize {
|
||||
// If whole payload fits in 1 block, don't stage it; End will upload it with 1 I/O operation
|
||||
t.firstBlock = buffer
|
||||
return nil
|
||||
}
|
||||
// Else, upload a staged block...
|
||||
AtomicMorphUint32(&t.maxBlockNum, func(startVal uint32) (val uint32, morphResult interface{}) {
|
||||
// Atomically remember (in t.numBlocks) the maximum block num we've ever seen
|
||||
if startVal < num {
|
||||
return num, nil
|
||||
}
|
||||
return startVal, nil
|
||||
})
|
||||
blockID := newUuidBlockID(t.blockIDPrefix).WithBlockNumber(num).ToBase64()
|
||||
_, err := t.b.StageBlock(ctx, blockID, bytes.NewReader(buffer), LeaseAccessConditions{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *uploadStreamToBlockBlobOptions) end(ctx context.Context) (interface{}, error) {
|
||||
if t.maxBlockNum == 0 {
|
||||
// If whole payload fits in 1 block (block #0), upload it with 1 I/O operation
|
||||
return t.b.Upload(ctx, bytes.NewReader(t.firstBlock),
|
||||
t.o.BlobHTTPHeaders, t.o.Metadata, t.o.AccessConditions)
|
||||
}
|
||||
// Multiple blocks staged, commit them all now
|
||||
blockID := newUuidBlockID(t.blockIDPrefix)
|
||||
blockIDs := make([]string, t.maxBlockNum + 1)
|
||||
for bn := uint32(0); bn <= t.maxBlockNum; bn++ {
|
||||
blockIDs[bn] = blockID.WithBlockNumber(bn).ToBase64()
|
||||
}
|
||||
return t.b.CommitBlockList(ctx, blockIDs, t.o.BlobHTTPHeaders, t.o.Metadata, t.o.AccessConditions)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type iTransfer interface {
|
||||
start(ctx context.Context) (interface{}, error)
|
||||
chunk(ctx context.Context, num uint32, buffer []byte) error
|
||||
end(ctx context.Context) (interface{}, error)
|
||||
}
|
||||
|
||||
type UploadStreamOptions struct {
|
||||
MaxBuffers int
|
||||
BufferSize int
|
||||
}
|
||||
|
||||
func uploadStream(ctx context.Context, reader io.Reader, o UploadStreamOptions, t iTransfer) (interface{}, error) {
|
||||
ctx, cancel := context.WithCancel(ctx) // New context so that any failure cancels everything
|
||||
defer cancel()
|
||||
wg := sync.WaitGroup{} // Used to know when all outgoing messages have finished processing
|
||||
type OutgoingMsg struct {
|
||||
chunkNum uint32
|
||||
buffer []byte
|
||||
}
|
||||
|
||||
// Create a channel to hold the buffers usable for incoming datsa
|
||||
incoming := make(chan []byte, o.MaxBuffers)
|
||||
outgoing := make(chan OutgoingMsg, o.MaxBuffers) // Channel holding outgoing buffers
|
||||
if result, err := t.start(ctx); err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
numBuffers := 0 // The number of buffers & out going goroutines created so far
|
||||
injectBuffer := func() {
|
||||
// For each Buffer, create it and a goroutine to upload it
|
||||
incoming <- make([]byte, o.BufferSize) // Add the new buffer to the incoming channel so this goroutine can from the reader into it
|
||||
numBuffers++
|
||||
go func() {
|
||||
for outgoingMsg := range outgoing {
|
||||
// Upload the outgoing buffer
|
||||
err := t.chunk(ctx, outgoingMsg.chunkNum, outgoingMsg.buffer)
|
||||
wg.Done() // Indicate this buffer was sent
|
||||
if nil != err {
|
||||
cancel()
|
||||
}
|
||||
incoming <- outgoingMsg.buffer // The goroutine reading from the stream can use reuse this buffer now
|
||||
}
|
||||
}()
|
||||
}
|
||||
injectBuffer() // Create our 1st buffer & outgoing goroutine
|
||||
|
||||
// This goroutine grabs a buffer, reads from the stream into the buffer,
|
||||
// and inserts the buffer into the outgoing channel to be uploaded
|
||||
for c := uint32(0); true; c++ { // Iterate once per chunk
|
||||
var buffer []byte
|
||||
if numBuffers < o.MaxBuffers {
|
||||
select {
|
||||
// We're not at max buffers, see if a previously-created buffer is available
|
||||
case buffer = <-incoming:
|
||||
break
|
||||
default:
|
||||
// No buffer available; inject a new buffer & go routine to process it
|
||||
injectBuffer()
|
||||
buffer = <-incoming // Grab the just-injected buffer
|
||||
}
|
||||
} else {
|
||||
// We are at max buffers, block until we get to reuse one
|
||||
buffer = <-incoming
|
||||
}
|
||||
n, err := io.ReadFull(reader, buffer)
|
||||
if err != nil {
|
||||
buffer = buffer[:n] // Make slice match the # of read bytes
|
||||
}
|
||||
if len(buffer) > 0 {
|
||||
// Buffer not empty, upload it
|
||||
wg.Add(1) // We're posting a buffer to be sent
|
||||
outgoing <- OutgoingMsg{chunkNum: c, buffer: buffer}
|
||||
}
|
||||
if err != nil { // The reader is done, no more outgoing buffers
|
||||
break
|
||||
}
|
||||
}
|
||||
// NOTE: Don't close the incoming channel because the outgoing goroutines post buffers into it when they are done
|
||||
close(outgoing) // Make all the outgoing goroutines terminate when this channel is empty
|
||||
wg.Wait() // Wait for all pending outgoing messages to complete
|
||||
// After all blocks uploaded, commit them to the blob & return the result
|
||||
return t.end(ctx)
|
||||
}
|
111
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/parsing_urls.go
generated
vendored
111
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/parsing_urls.go
generated
vendored
|
@ -1,111 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
snapshot = "snapshot"
|
||||
SnapshotTimeFormat = "2006-01-02T15:04:05.0000000Z07:00"
|
||||
)
|
||||
|
||||
// A BlobURLParts object represents the components that make up an Azure Storage Container/Blob URL. You parse an
|
||||
// existing URL into its parts by calling NewBlobURLParts(). You construct a URL from parts by calling URL().
|
||||
// NOTE: Changing any SAS-related field requires computing a new SAS signature.
|
||||
type BlobURLParts struct {
|
||||
Scheme string // Ex: "https://"
|
||||
Host string // Ex: "account.blob.core.windows.net"
|
||||
ContainerName string // "" if no container
|
||||
BlobName string // "" if no blob
|
||||
Snapshot string // "" if not a snapshot
|
||||
SAS SASQueryParameters
|
||||
UnparsedParams string
|
||||
}
|
||||
|
||||
// NewBlobURLParts parses a URL initializing BlobURLParts' fields including any SAS-related & snapshot query parameters. Any other
|
||||
// query parameters remain in the UnparsedParams field. This method overwrites all fields in the BlobURLParts object.
|
||||
func NewBlobURLParts(u url.URL) BlobURLParts {
|
||||
up := BlobURLParts{
|
||||
Scheme: u.Scheme,
|
||||
Host: u.Host,
|
||||
}
|
||||
|
||||
// Find the container & blob names (if any)
|
||||
if u.Path != "" {
|
||||
path := u.Path
|
||||
if path[0] == '/' {
|
||||
path = path[1:] // If path starts with a slash, remove it
|
||||
}
|
||||
|
||||
// Find the next slash (if it exists)
|
||||
containerEndIndex := strings.Index(path, "/")
|
||||
if containerEndIndex == -1 { // Slash not found; path has container name & no blob name
|
||||
up.ContainerName = path
|
||||
} else {
|
||||
up.ContainerName = path[:containerEndIndex] // The container name is the part between the slashes
|
||||
up.BlobName = path[containerEndIndex+1:] // The blob name is after the container slash
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the query parameters to a case-sensitive map & trim whitespace
|
||||
paramsMap := u.Query()
|
||||
|
||||
up.Snapshot = "" // Assume no snapshot
|
||||
if snapshotStr, ok := caseInsensitiveValues(paramsMap).Get(snapshot); ok {
|
||||
up.Snapshot = snapshotStr[0]
|
||||
// If we recognized the query parameter, remove it from the map
|
||||
delete(paramsMap, snapshot)
|
||||
}
|
||||
up.SAS = newSASQueryParameters(paramsMap, true)
|
||||
up.UnparsedParams = paramsMap.Encode()
|
||||
return up
|
||||
}
|
||||
|
||||
type caseInsensitiveValues url.Values // map[string][]string
|
||||
func (values caseInsensitiveValues) Get(key string) ([]string, bool) {
|
||||
key = strings.ToLower(key)
|
||||
for k, v := range values {
|
||||
if strings.ToLower(k) == key {
|
||||
return v, true
|
||||
}
|
||||
}
|
||||
return []string{}, false
|
||||
}
|
||||
|
||||
// URL returns a URL object whose fields are initialized from the BlobURLParts fields. The URL's RawQuery
|
||||
// field contains the SAS, snapshot, and unparsed query parameters.
|
||||
func (up BlobURLParts) URL() url.URL {
|
||||
path := ""
|
||||
// Concatenate container & blob names (if they exist)
|
||||
if up.ContainerName != "" {
|
||||
path += "/" + up.ContainerName
|
||||
if up.BlobName != "" {
|
||||
path += "/" + up.BlobName
|
||||
}
|
||||
}
|
||||
|
||||
rawQuery := up.UnparsedParams
|
||||
|
||||
// Concatenate blob snapshot query parameter (if it exists)
|
||||
if up.Snapshot != "" {
|
||||
if len(rawQuery) > 0 {
|
||||
rawQuery += "&"
|
||||
}
|
||||
rawQuery += snapshot + "=" + up.Snapshot
|
||||
}
|
||||
sas := up.SAS.Encode()
|
||||
if sas != "" {
|
||||
if len(rawQuery) > 0 {
|
||||
rawQuery += "&"
|
||||
}
|
||||
rawQuery += sas
|
||||
}
|
||||
u := url.URL{
|
||||
Scheme: up.Scheme,
|
||||
Host: up.Host,
|
||||
Path: path,
|
||||
RawQuery: rawQuery,
|
||||
}
|
||||
return u
|
||||
}
|
206
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/sas_service.go
generated
vendored
206
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/sas_service.go
generated
vendored
|
@ -1,206 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BlobSASSignatureValues is used to generate a Shared Access Signature (SAS) for an Azure Storage container or blob.
|
||||
type BlobSASSignatureValues struct {
|
||||
Version string `param:"sv"` // If not specified, this defaults to SASVersion
|
||||
Protocol SASProtocol `param:"spr"` // See the SASProtocol* constants
|
||||
StartTime time.Time `param:"st"` // Not specified if IsZero
|
||||
ExpiryTime time.Time `param:"se"` // Not specified if IsZero
|
||||
Permissions string `param:"sp"` // Create by initializing a ContainerSASPermissions or BlobSASPermissions and then call String()
|
||||
IPRange IPRange `param:"sip"`
|
||||
Identifier string `param:"si"`
|
||||
ContainerName string
|
||||
BlobName string // Use "" to create a Container SAS
|
||||
CacheControl string // rscc
|
||||
ContentDisposition string // rscd
|
||||
ContentEncoding string // rsce
|
||||
ContentLanguage string // rscl
|
||||
ContentType string // rsct
|
||||
}
|
||||
|
||||
// NewSASQueryParameters uses an account's shared key credential to sign this signature values to produce
|
||||
// the proper SAS query parameters.
|
||||
func (v BlobSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *SharedKeyCredential) SASQueryParameters {
|
||||
if sharedKeyCredential == nil {
|
||||
panic("sharedKeyCredential can't be nil")
|
||||
}
|
||||
|
||||
resource := "c"
|
||||
if v.BlobName == "" {
|
||||
// Make sure the permission characters are in the correct order
|
||||
perms := &ContainerSASPermissions{}
|
||||
if err := perms.Parse(v.Permissions); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
v.Permissions = perms.String()
|
||||
} else {
|
||||
resource = "b"
|
||||
// Make sure the permission characters are in the correct order
|
||||
perms := &BlobSASPermissions{}
|
||||
if err := perms.Parse(v.Permissions); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
v.Permissions = perms.String()
|
||||
}
|
||||
if v.Version == "" {
|
||||
v.Version = SASVersion
|
||||
}
|
||||
startTime, expiryTime := FormatTimesForSASSigning(v.StartTime, v.ExpiryTime)
|
||||
|
||||
// String to sign: http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx
|
||||
stringToSign := strings.Join([]string{
|
||||
v.Permissions,
|
||||
startTime,
|
||||
expiryTime,
|
||||
getCanonicalName(sharedKeyCredential.AccountName(), v.ContainerName, v.BlobName),
|
||||
v.Identifier,
|
||||
v.IPRange.String(),
|
||||
string(v.Protocol),
|
||||
v.Version,
|
||||
v.CacheControl, // rscc
|
||||
v.ContentDisposition, // rscd
|
||||
v.ContentEncoding, // rsce
|
||||
v.ContentLanguage, // rscl
|
||||
v.ContentType}, // rsct
|
||||
"\n")
|
||||
signature := sharedKeyCredential.ComputeHMACSHA256(stringToSign)
|
||||
|
||||
p := SASQueryParameters{
|
||||
// Common SAS parameters
|
||||
version: v.Version,
|
||||
protocol: v.Protocol,
|
||||
startTime: v.StartTime,
|
||||
expiryTime: v.ExpiryTime,
|
||||
permissions: v.Permissions,
|
||||
ipRange: v.IPRange,
|
||||
|
||||
// Container/Blob-specific SAS parameters
|
||||
resource: resource,
|
||||
identifier: v.Identifier,
|
||||
|
||||
// Calculated SAS signature
|
||||
signature: signature,
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// getCanonicalName computes the canonical name for a container or blob resource for SAS signing.
|
||||
func getCanonicalName(account string, containerName string, blobName string) string {
|
||||
// Container: "/blob/account/containername"
|
||||
// Blob: "/blob/account/containername/blobname"
|
||||
elements := []string{"/blob/", account, "/", containerName}
|
||||
if blobName != "" {
|
||||
elements = append(elements, "/", strings.Replace(blobName, "\\", "/", -1))
|
||||
}
|
||||
return strings.Join(elements, "")
|
||||
}
|
||||
|
||||
// The ContainerSASPermissions type simplifies creating the permissions string for an Azure Storage container SAS.
|
||||
// Initialize an instance of this type and then call its String method to set BlobSASSignatureValues's Permissions field.
|
||||
type ContainerSASPermissions struct {
|
||||
Read, Add, Create, Write, Delete, List bool
|
||||
}
|
||||
|
||||
// String produces the SAS permissions string for an Azure Storage container.
|
||||
// Call this method to set BlobSASSignatureValues's Permissions field.
|
||||
func (p ContainerSASPermissions) String() string {
|
||||
var b bytes.Buffer
|
||||
if p.Read {
|
||||
b.WriteRune('r')
|
||||
}
|
||||
if p.Add {
|
||||
b.WriteRune('a')
|
||||
}
|
||||
if p.Create {
|
||||
b.WriteRune('c')
|
||||
}
|
||||
if p.Write {
|
||||
b.WriteRune('w')
|
||||
}
|
||||
if p.Delete {
|
||||
b.WriteRune('d')
|
||||
}
|
||||
if p.List {
|
||||
b.WriteRune('l')
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Parse initializes the ContainerSASPermissions's fields from a string.
|
||||
func (p *ContainerSASPermissions) Parse(s string) error {
|
||||
*p = ContainerSASPermissions{} // Clear the flags
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 'r':
|
||||
p.Read = true
|
||||
case 'a':
|
||||
p.Add = true
|
||||
case 'c':
|
||||
p.Create = true
|
||||
case 'w':
|
||||
p.Write = true
|
||||
case 'd':
|
||||
p.Delete = true
|
||||
case 'l':
|
||||
p.List = true
|
||||
default:
|
||||
return fmt.Errorf("Invalid permission: '%v'", r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// The BlobSASPermissions type simplifies creating the permissions string for an Azure Storage blob SAS.
|
||||
// Initialize an instance of this type and then call its String method to set BlobSASSignatureValues's Permissions field.
|
||||
type BlobSASPermissions struct{ Read, Add, Create, Write, Delete bool }
|
||||
|
||||
// String produces the SAS permissions string for an Azure Storage blob.
|
||||
// Call this method to set BlobSASSignatureValues's Permissions field.
|
||||
func (p BlobSASPermissions) String() string {
|
||||
var b bytes.Buffer
|
||||
if p.Read {
|
||||
b.WriteRune('r')
|
||||
}
|
||||
if p.Add {
|
||||
b.WriteRune('a')
|
||||
}
|
||||
if p.Create {
|
||||
b.WriteRune('c')
|
||||
}
|
||||
if p.Write {
|
||||
b.WriteRune('w')
|
||||
}
|
||||
if p.Delete {
|
||||
b.WriteRune('d')
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Parse initializes the BlobSASPermissions's fields from a string.
|
||||
func (p *BlobSASPermissions) Parse(s string) error {
|
||||
*p = BlobSASPermissions{} // Clear the flags
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 'r':
|
||||
p.Read = true
|
||||
case 'a':
|
||||
p.Add = true
|
||||
case 'c':
|
||||
p.Create = true
|
||||
case 'w':
|
||||
p.Write = true
|
||||
case 'd':
|
||||
p.Delete = true
|
||||
default:
|
||||
return fmt.Errorf("Invalid permission: '%v'", r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
195
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/service_codes_blob.go
generated
vendored
195
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/service_codes_blob.go
generated
vendored
|
@ -1,195 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/blob-service-error-codes
|
||||
|
||||
// ServiceCode values indicate a service failure.
|
||||
const (
|
||||
// ServiceCodeAppendPositionConditionNotMet means the append position condition specified was not met.
|
||||
ServiceCodeAppendPositionConditionNotMet ServiceCodeType = "AppendPositionConditionNotMet"
|
||||
|
||||
// ServiceCodeBlobAlreadyExists means the specified blob already exists.
|
||||
ServiceCodeBlobAlreadyExists ServiceCodeType = "BlobAlreadyExists"
|
||||
|
||||
// ServiceCodeBlobNotFound means the specified blob does not exist.
|
||||
ServiceCodeBlobNotFound ServiceCodeType = "BlobNotFound"
|
||||
|
||||
// ServiceCodeBlobOverwritten means the blob has been recreated since the previous snapshot was taken.
|
||||
ServiceCodeBlobOverwritten ServiceCodeType = "BlobOverwritten"
|
||||
|
||||
// ServiceCodeBlobTierInadequateForContentLength means the specified blob tier size limit cannot be less than content length.
|
||||
ServiceCodeBlobTierInadequateForContentLength ServiceCodeType = "BlobTierInadequateForContentLength"
|
||||
|
||||
// ServiceCodeBlockCountExceedsLimit means the committed block count cannot exceed the maximum limit of 50,000 blocks
|
||||
// or that the uncommitted block count cannot exceed the maximum limit of 100,000 blocks.
|
||||
ServiceCodeBlockCountExceedsLimit ServiceCodeType = "BlockCountExceedsLimit"
|
||||
|
||||
// ServiceCodeBlockListTooLong means the block list may not contain more than 50,000 blocks.
|
||||
ServiceCodeBlockListTooLong ServiceCodeType = "BlockListTooLong"
|
||||
|
||||
// ServiceCodeCannotChangeToLowerTier means that a higher blob tier has already been explicitly set.
|
||||
ServiceCodeCannotChangeToLowerTier ServiceCodeType = "CannotChangeToLowerTier"
|
||||
|
||||
// ServiceCodeCannotVerifyCopySource means that the service could not verify the copy source within the specified time.
|
||||
// Examine the HTTP status code and message for more information about the failure.
|
||||
ServiceCodeCannotVerifyCopySource ServiceCodeType = "CannotVerifyCopySource"
|
||||
|
||||
// ServiceCodeContainerAlreadyExists means the specified container already exists.
|
||||
ServiceCodeContainerAlreadyExists ServiceCodeType = "ContainerAlreadyExists"
|
||||
|
||||
// ServiceCodeContainerBeingDeleted means the specified container is being deleted.
|
||||
ServiceCodeContainerBeingDeleted ServiceCodeType = "ContainerBeingDeleted"
|
||||
|
||||
// ServiceCodeContainerDisabled means the specified container has been disabled by the administrator.
|
||||
ServiceCodeContainerDisabled ServiceCodeType = "ContainerDisabled"
|
||||
|
||||
// ServiceCodeContainerNotFound means the specified container does not exist.
|
||||
ServiceCodeContainerNotFound ServiceCodeType = "ContainerNotFound"
|
||||
|
||||
// ServiceCodeContentLengthLargerThanTierLimit means the blob's content length cannot exceed its tier limit.
|
||||
ServiceCodeContentLengthLargerThanTierLimit ServiceCodeType = "ContentLengthLargerThanTierLimit"
|
||||
|
||||
// ServiceCodeCopyAcrossAccountsNotSupported means the copy source account and destination account must be the same.
|
||||
ServiceCodeCopyAcrossAccountsNotSupported ServiceCodeType = "CopyAcrossAccountsNotSupported"
|
||||
|
||||
// ServiceCodeCopyIDMismatch means the specified copy ID did not match the copy ID for the pending copy operation.
|
||||
ServiceCodeCopyIDMismatch ServiceCodeType = "CopyIdMismatch"
|
||||
|
||||
// ServiceCodeFeatureVersionMismatch means the type of blob in the container is unrecognized by this version or
|
||||
// that the operation for AppendBlob requires at least version 2015-02-21.
|
||||
ServiceCodeFeatureVersionMismatch ServiceCodeType = "FeatureVersionMismatch"
|
||||
|
||||
// ServiceCodeIncrementalCopyBlobMismatch means the specified source blob is different than the copy source of the existing incremental copy blob.
|
||||
ServiceCodeIncrementalCopyBlobMismatch ServiceCodeType = "IncrementalCopyBlobMismatch"
|
||||
|
||||
// ServiceCodeIncrementalCopyOfEralierVersionSnapshotNotAllowed means the specified snapshot is earlier than the last snapshot copied into the incremental copy blob.
|
||||
ServiceCodeIncrementalCopyOfEralierVersionSnapshotNotAllowed ServiceCodeType = "IncrementalCopyOfEralierVersionSnapshotNotAllowed"
|
||||
|
||||
// ServiceCodeIncrementalCopySourceMustBeSnapshot means the source for incremental copy request must be a snapshot.
|
||||
ServiceCodeIncrementalCopySourceMustBeSnapshot ServiceCodeType = "IncrementalCopySourceMustBeSnapshot"
|
||||
|
||||
// ServiceCodeInfiniteLeaseDurationRequired means the lease ID matched, but the specified lease must be an infinite-duration lease.
|
||||
ServiceCodeInfiniteLeaseDurationRequired ServiceCodeType = "InfiniteLeaseDurationRequired"
|
||||
|
||||
// ServiceCodeInvalidBlobOrBlock means the specified blob or block content is invalid.
|
||||
ServiceCodeInvalidBlobOrBlock ServiceCodeType = "InvalidBlobOrBlock"
|
||||
|
||||
// ServiceCodeInvalidBlobType means the blob type is invalid for this operation.
|
||||
ServiceCodeInvalidBlobType ServiceCodeType = "InvalidBlobType"
|
||||
|
||||
// ServiceCodeInvalidBlockID means the specified block ID is invalid. The block ID must be Base64-encoded.
|
||||
ServiceCodeInvalidBlockID ServiceCodeType = "InvalidBlockId"
|
||||
|
||||
// ServiceCodeInvalidBlockList means the specified block list is invalid.
|
||||
ServiceCodeInvalidBlockList ServiceCodeType = "InvalidBlockList"
|
||||
|
||||
// ServiceCodeInvalidOperation means an invalid operation against a blob snapshot.
|
||||
ServiceCodeInvalidOperation ServiceCodeType = "InvalidOperation"
|
||||
|
||||
// ServiceCodeInvalidPageRange means the page range specified is invalid.
|
||||
ServiceCodeInvalidPageRange ServiceCodeType = "InvalidPageRange"
|
||||
|
||||
// ServiceCodeInvalidSourceBlobType means the copy source blob type is invalid for this operation.
|
||||
ServiceCodeInvalidSourceBlobType ServiceCodeType = "InvalidSourceBlobType"
|
||||
|
||||
// ServiceCodeInvalidSourceBlobURL means the source URL for incremental copy request must be valid Azure Storage blob URL.
|
||||
ServiceCodeInvalidSourceBlobURL ServiceCodeType = "InvalidSourceBlobUrl"
|
||||
|
||||
// ServiceCodeInvalidVersionForPageBlobOperation means that all operations on page blobs require at least version 2009-09-19.
|
||||
ServiceCodeInvalidVersionForPageBlobOperation ServiceCodeType = "InvalidVersionForPageBlobOperation"
|
||||
|
||||
// ServiceCodeLeaseAlreadyPresent means there is already a lease present.
|
||||
ServiceCodeLeaseAlreadyPresent ServiceCodeType = "LeaseAlreadyPresent"
|
||||
|
||||
// ServiceCodeLeaseAlreadyBroken means the lease has already been broken and cannot be broken again.
|
||||
ServiceCodeLeaseAlreadyBroken ServiceCodeType = "LeaseAlreadyBroken"
|
||||
|
||||
// ServiceCodeLeaseIDMismatchWithBlobOperation means the lease ID specified did not match the lease ID for the blob.
|
||||
ServiceCodeLeaseIDMismatchWithBlobOperation ServiceCodeType = "LeaseIdMismatchWithBlobOperation"
|
||||
|
||||
// ServiceCodeLeaseIDMismatchWithContainerOperation means the lease ID specified did not match the lease ID for the container.
|
||||
ServiceCodeLeaseIDMismatchWithContainerOperation ServiceCodeType = "LeaseIdMismatchWithContainerOperation"
|
||||
|
||||
// ServiceCodeLeaseIDMismatchWithLeaseOperation means the lease ID specified did not match the lease ID for the blob/container.
|
||||
ServiceCodeLeaseIDMismatchWithLeaseOperation ServiceCodeType = "LeaseIdMismatchWithLeaseOperation"
|
||||
|
||||
// ServiceCodeLeaseIDMissing means there is currently a lease on the blob/container and no lease ID was specified in the request.
|
||||
ServiceCodeLeaseIDMissing ServiceCodeType = "LeaseIdMissing"
|
||||
|
||||
// ServiceCodeLeaseIsBreakingAndCannotBeAcquired means the lease ID matched, but the lease is currently in breaking state and cannot be acquired until it is broken.
|
||||
ServiceCodeLeaseIsBreakingAndCannotBeAcquired ServiceCodeType = "LeaseIsBreakingAndCannotBeAcquired"
|
||||
|
||||
// ServiceCodeLeaseIsBreakingAndCannotBeChanged means the lease ID matched, but the lease is currently in breaking state and cannot be changed.
|
||||
ServiceCodeLeaseIsBreakingAndCannotBeChanged ServiceCodeType = "LeaseIsBreakingAndCannotBeChanged"
|
||||
|
||||
// ServiceCodeLeaseIsBrokenAndCannotBeRenewed means the lease ID matched, but the lease has been broken explicitly and cannot be renewed.
|
||||
ServiceCodeLeaseIsBrokenAndCannotBeRenewed ServiceCodeType = "LeaseIsBrokenAndCannotBeRenewed"
|
||||
|
||||
// ServiceCodeLeaseLost means a lease ID was specified, but the lease for the blob/container has expired.
|
||||
ServiceCodeLeaseLost ServiceCodeType = "LeaseLost"
|
||||
|
||||
// ServiceCodeLeaseNotPresentWithBlobOperation means there is currently no lease on the blob.
|
||||
ServiceCodeLeaseNotPresentWithBlobOperation ServiceCodeType = "LeaseNotPresentWithBlobOperation"
|
||||
|
||||
// ServiceCodeLeaseNotPresentWithContainerOperation means there is currently no lease on the container.
|
||||
ServiceCodeLeaseNotPresentWithContainerOperation ServiceCodeType = "LeaseNotPresentWithContainerOperation"
|
||||
|
||||
// ServiceCodeLeaseNotPresentWithLeaseOperation means there is currently no lease on the blob/container.
|
||||
ServiceCodeLeaseNotPresentWithLeaseOperation ServiceCodeType = "LeaseNotPresentWithLeaseOperation"
|
||||
|
||||
// ServiceCodeMaxBlobSizeConditionNotMet means the max blob size condition specified was not met.
|
||||
ServiceCodeMaxBlobSizeConditionNotMet ServiceCodeType = "MaxBlobSizeConditionNotMet"
|
||||
|
||||
// ServiceCodeNoPendingCopyOperation means there is currently no pending copy operation.
|
||||
ServiceCodeNoPendingCopyOperation ServiceCodeType = "NoPendingCopyOperation"
|
||||
|
||||
// ServiceCodeOperationNotAllowedOnIncrementalCopyBlob means the specified operation is not allowed on an incremental copy blob.
|
||||
ServiceCodeOperationNotAllowedOnIncrementalCopyBlob ServiceCodeType = "OperationNotAllowedOnIncrementalCopyBlob"
|
||||
|
||||
// ServiceCodePendingCopyOperation means there is currently a pending copy operation.
|
||||
ServiceCodePendingCopyOperation ServiceCodeType = "PendingCopyOperation"
|
||||
|
||||
// ServiceCodePreviousSnapshotCannotBeNewer means the prevsnapshot query parameter value cannot be newer than snapshot query parameter value.
|
||||
ServiceCodePreviousSnapshotCannotBeNewer ServiceCodeType = "PreviousSnapshotCannotBeNewer"
|
||||
|
||||
// ServiceCodePreviousSnapshotNotFound means the previous snapshot is not found.
|
||||
ServiceCodePreviousSnapshotNotFound ServiceCodeType = "PreviousSnapshotNotFound"
|
||||
|
||||
// ServiceCodePreviousSnapshotOperationNotSupported means that differential Get Page Ranges is not supported on the previous snapshot.
|
||||
ServiceCodePreviousSnapshotOperationNotSupported ServiceCodeType = "PreviousSnapshotOperationNotSupported"
|
||||
|
||||
// ServiceCodeSequenceNumberConditionNotMet means the sequence number condition specified was not met.
|
||||
ServiceCodeSequenceNumberConditionNotMet ServiceCodeType = "SequenceNumberConditionNotMet"
|
||||
|
||||
// ServiceCodeSequenceNumberIncrementTooLarge means the sequence number increment cannot be performed because it would result in overflow of the sequence number.
|
||||
ServiceCodeSequenceNumberIncrementTooLarge ServiceCodeType = "SequenceNumberIncrementTooLarge"
|
||||
|
||||
// ServiceCodeSnapshotCountExceeded means the snapshot count against this blob has been exceeded.
|
||||
ServiceCodeSnapshotCountExceeded ServiceCodeType = "SnapshotCountExceeded"
|
||||
|
||||
// ServiceCodeSnaphotOperationRateExceeded means the rate of snapshot operations against this blob has been exceeded.
|
||||
ServiceCodeSnaphotOperationRateExceeded ServiceCodeType = "SnaphotOperationRateExceeded"
|
||||
|
||||
// ServiceCodeSnapshotsPresent means this operation is not permitted while the blob has snapshots.
|
||||
ServiceCodeSnapshotsPresent ServiceCodeType = "SnapshotsPresent"
|
||||
|
||||
// ServiceCodeSourceConditionNotMet means the source condition specified using HTTP conditional header(s) is not met.
|
||||
ServiceCodeSourceConditionNotMet ServiceCodeType = "SourceConditionNotMet"
|
||||
|
||||
// ServiceCodeSystemInUse means this blob is in use by the system.
|
||||
ServiceCodeSystemInUse ServiceCodeType = "SystemInUse"
|
||||
|
||||
// ServiceCodeTargetConditionNotMet means the target condition specified using HTTP conditional header(s) is not met.
|
||||
ServiceCodeTargetConditionNotMet ServiceCodeType = "TargetConditionNotMet"
|
||||
|
||||
// ServiceCodeUnauthorizedBlobOverwrite means this request is not authorized to perform blob overwrites.
|
||||
ServiceCodeUnauthorizedBlobOverwrite ServiceCodeType = "UnauthorizedBlobOverwrite"
|
||||
|
||||
// ServiceCodeBlobBeingRehydrated means this operation is not permitted because the blob is being rehydrated.
|
||||
ServiceCodeBlobBeingRehydrated ServiceCodeType = "BlobBeingRehydrated"
|
||||
|
||||
// ServiceCodeBlobArchived means this operation is not permitted on an archived blob.
|
||||
ServiceCodeBlobArchived ServiceCodeType = "BlobArchived"
|
||||
|
||||
// ServiceCodeBlobNotArchived means this blob is currently not in the archived state.
|
||||
ServiceCodeBlobNotArchived ServiceCodeType = "BlobNotArchived"
|
||||
)
|
112
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/url_append_blob.go
generated
vendored
112
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/url_append_blob.go
generated
vendored
|
@ -1,112 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/url"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
const (
|
||||
// AppendBlobMaxAppendBlockBytes indicates the maximum number of bytes that can be sent in a call to AppendBlock.
|
||||
AppendBlobMaxAppendBlockBytes = 4 * 1024 * 1024 // 4MB
|
||||
|
||||
// AppendBlobMaxBlocks indicates the maximum number of blocks allowed in an append blob.
|
||||
AppendBlobMaxBlocks = 50000
|
||||
)
|
||||
|
||||
// AppendBlobURL defines a set of operations applicable to append blobs.
|
||||
type AppendBlobURL struct {
|
||||
BlobURL
|
||||
abClient appendBlobsClient
|
||||
}
|
||||
|
||||
// NewAppendBlobURL creates an AppendBlobURL object using the specified URL and request policy pipeline.
|
||||
func NewAppendBlobURL(url url.URL, p pipeline.Pipeline) AppendBlobURL {
|
||||
blobClient := newBlobsClient(url, p)
|
||||
abClient := newAppendBlobsClient(url, p)
|
||||
return AppendBlobURL{BlobURL: BlobURL{blobClient: blobClient}, abClient: abClient}
|
||||
}
|
||||
|
||||
// WithPipeline creates a new AppendBlobURL object identical to the source but with the specific request policy pipeline.
|
||||
func (ab AppendBlobURL) WithPipeline(p pipeline.Pipeline) AppendBlobURL {
|
||||
return NewAppendBlobURL(ab.blobClient.URL(), p)
|
||||
}
|
||||
|
||||
// WithSnapshot creates a new AppendBlobURL object identical to the source but with the specified snapshot timestamp.
|
||||
// Pass "" to remove the snapshot returning a URL to the base blob.
|
||||
func (ab AppendBlobURL) WithSnapshot(snapshot string) AppendBlobURL {
|
||||
p := NewBlobURLParts(ab.URL())
|
||||
p.Snapshot = snapshot
|
||||
return NewAppendBlobURL(p.URL(), ab.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// Create creates a 0-length append blob. Call AppendBlock to append data to an append blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-blob.
|
||||
func (ab AppendBlobURL) Create(ctx context.Context, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions) (*AppendBlobsCreateResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch := ac.HTTPAccessConditions.pointers()
|
||||
return ab.abClient.Create(ctx, 0, nil,
|
||||
&h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5,
|
||||
&h.CacheControl, metadata, ac.LeaseAccessConditions.pointers(), &h.ContentDisposition,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, nil)
|
||||
}
|
||||
|
||||
// AppendBlock writes a stream to a new block of data to the end of the existing append blob.
|
||||
// This method panics if the stream is not at position 0.
|
||||
// Note that the http client closes the body stream after the request is sent to the service.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/append-block.
|
||||
func (ab AppendBlobURL) AppendBlock(ctx context.Context, body io.ReadSeeker, ac BlobAccessConditions) (*AppendBlobsAppendBlockResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
ifAppendPositionEqual, ifMaxSizeLessThanOrEqual := ac.AppendBlobAccessConditions.pointers()
|
||||
return ab.abClient.AppendBlock(ctx, body, validateSeekableStreamAt0AndGetCount(body), nil,
|
||||
ac.LeaseAccessConditions.pointers(),
|
||||
ifMaxSizeLessThanOrEqual, ifAppendPositionEqual,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// AppendBlobAccessConditions identifies append blob-specific access conditions which you optionally set.
|
||||
type AppendBlobAccessConditions struct {
|
||||
// IfAppendPositionEqual ensures that the AppendBlock operation succeeds
|
||||
// only if the append position is equal to a value.
|
||||
// IfAppendPositionEqual=0 means no 'IfAppendPositionEqual' header specified.
|
||||
// IfAppendPositionEqual>0 means 'IfAppendPositionEqual' header specified with its value
|
||||
// IfAppendPositionEqual==-1 means IfAppendPositionEqual' header specified with a value of 0
|
||||
IfAppendPositionEqual int64
|
||||
|
||||
// IfMaxSizeLessThanOrEqual ensures that the AppendBlock operation succeeds
|
||||
// only if the append blob's size is less than or equal to a value.
|
||||
// IfMaxSizeLessThanOrEqual=0 means no 'IfMaxSizeLessThanOrEqual' header specified.
|
||||
// IfMaxSizeLessThanOrEqual>0 means 'IfMaxSizeLessThanOrEqual' header specified with its value
|
||||
// IfMaxSizeLessThanOrEqual==-1 means 'IfMaxSizeLessThanOrEqual' header specified with a value of 0
|
||||
IfMaxSizeLessThanOrEqual int64
|
||||
}
|
||||
|
||||
// pointers is for internal infrastructure. It returns the fields as pointers.
|
||||
func (ac AppendBlobAccessConditions) pointers() (iape *int64, imsltoe *int64) {
|
||||
if ac.IfAppendPositionEqual < -1 {
|
||||
panic("IfAppendPositionEqual can't be less than -1")
|
||||
}
|
||||
if ac.IfMaxSizeLessThanOrEqual < -1 {
|
||||
panic("IfMaxSizeLessThanOrEqual can't be less than -1")
|
||||
}
|
||||
var zero int64 // defaults to 0
|
||||
switch ac.IfAppendPositionEqual {
|
||||
case -1:
|
||||
iape = &zero
|
||||
case 0:
|
||||
iape = nil
|
||||
default:
|
||||
iape = &ac.IfAppendPositionEqual
|
||||
}
|
||||
|
||||
switch ac.IfMaxSizeLessThanOrEqual {
|
||||
case -1:
|
||||
imsltoe = &zero
|
||||
case 0:
|
||||
imsltoe = nil
|
||||
default:
|
||||
imsltoe = &ac.IfMaxSizeLessThanOrEqual
|
||||
}
|
||||
return
|
||||
}
|
221
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/url_blob.go
generated
vendored
221
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/url_blob.go
generated
vendored
|
@ -1,221 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// A BlobURL represents a URL to an Azure Storage blob; the blob may be a block blob, append blob, or page blob.
|
||||
type BlobURL struct {
|
||||
blobClient blobsClient
|
||||
}
|
||||
|
||||
// NewBlobURL creates a BlobURL object using the specified URL and request policy pipeline.
|
||||
func NewBlobURL(url url.URL, p pipeline.Pipeline) BlobURL {
|
||||
if p == nil {
|
||||
panic("p can't be nil")
|
||||
}
|
||||
blobClient := newBlobsClient(url, p)
|
||||
return BlobURL{blobClient: blobClient}
|
||||
}
|
||||
|
||||
// URL returns the URL endpoint used by the BlobURL object.
|
||||
func (b BlobURL) URL() url.URL {
|
||||
return b.blobClient.URL()
|
||||
}
|
||||
|
||||
// String returns the URL as a string.
|
||||
func (b BlobURL) String() string {
|
||||
u := b.URL()
|
||||
return u.String()
|
||||
}
|
||||
|
||||
// WithPipeline creates a new BlobURL object identical to the source but with the specified request policy pipeline.
|
||||
func (b BlobURL) WithPipeline(p pipeline.Pipeline) BlobURL {
|
||||
if p == nil {
|
||||
panic("p can't be nil")
|
||||
}
|
||||
return NewBlobURL(b.blobClient.URL(), p)
|
||||
}
|
||||
|
||||
// WithSnapshot creates a new BlobURL object identical to the source but with the specified snapshot timestamp.
|
||||
// Pass "" to remove the snapshot returning a URL to the base blob.
|
||||
func (b BlobURL) WithSnapshot(snapshot string) BlobURL {
|
||||
p := NewBlobURLParts(b.URL())
|
||||
p.Snapshot = snapshot
|
||||
return NewBlobURL(p.URL(), b.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// ToAppendBlobURL creates an AppendBlobURL using the source's URL and pipeline.
|
||||
func (b BlobURL) ToAppendBlobURL() AppendBlobURL {
|
||||
return NewAppendBlobURL(b.URL(), b.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// ToBlockBlobURL creates a BlockBlobURL using the source's URL and pipeline.
|
||||
func (b BlobURL) ToBlockBlobURL() BlockBlobURL {
|
||||
return NewBlockBlobURL(b.URL(), b.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// ToPageBlobURL creates a PageBlobURL using the source's URL and pipeline.
|
||||
func (b BlobURL) ToPageBlobURL() PageBlobURL {
|
||||
return NewPageBlobURL(b.URL(), b.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// DownloadBlob reads a range of bytes from a blob. The response also includes the blob's properties and metadata.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-blob.
|
||||
func (b BlobURL) Download(ctx context.Context, offset int64, count int64, ac BlobAccessConditions, rangeGetContentMD5 bool) (*DownloadResponse, error) {
|
||||
var xRangeGetContentMD5 *bool
|
||||
if rangeGetContentMD5 {
|
||||
xRangeGetContentMD5 = &rangeGetContentMD5
|
||||
}
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
dr, err := b.blobClient.Download(ctx, nil, nil,
|
||||
httpRange{offset: offset, count: count}.pointers(),
|
||||
ac.LeaseAccessConditions.pointers(), xRangeGetContentMD5,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DownloadResponse{
|
||||
b: b,
|
||||
r: dr,
|
||||
ctx: ctx,
|
||||
getInfo: HTTPGetterInfo{Offset: offset, Count: count, ETag: dr.ETag()},
|
||||
}, err
|
||||
}
|
||||
|
||||
// DeleteBlob marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection.
|
||||
// Note that deleting a blob also deletes all its snapshots.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/delete-blob.
|
||||
func (b BlobURL) Delete(ctx context.Context, deleteOptions DeleteSnapshotsOptionType, ac BlobAccessConditions) (*BlobsDeleteResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return b.blobClient.Delete(ctx, nil, nil, ac.LeaseAccessConditions.pointers(), deleteOptions,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// Undelete restores the contents and metadata of a soft-deleted blob and any associated soft-deleted snapshots.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/undelete-blob.
|
||||
func (b BlobURL) Undelete(ctx context.Context) (*BlobsUndeleteResponse, error) {
|
||||
return b.blobClient.Undelete(ctx, nil, nil)
|
||||
}
|
||||
|
||||
// SetTier operation sets the tier on a blob. The operation is allowed on a page
|
||||
// blob in a premium storage account and on a block blob in a blob storage account (locally
|
||||
// redundant storage only). A premium page blob's tier determines the allowed size, IOPS, and
|
||||
// bandwidth of the blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation
|
||||
// does not update the blob's ETag.
|
||||
// For detailed information about block blob level tiering see https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-storage-tiers.
|
||||
func (b BlobURL) SetTier(ctx context.Context, tier AccessTierType) (*BlobsSetTierResponse, error) {
|
||||
return b.blobClient.SetTier(ctx, tier, nil, nil)
|
||||
}
|
||||
|
||||
// GetBlobProperties returns the blob's properties.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-blob-properties.
|
||||
func (b BlobURL) GetProperties(ctx context.Context, ac BlobAccessConditions) (*BlobsGetPropertiesResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return b.blobClient.GetProperties(ctx, nil, nil, ac.LeaseAccessConditions.pointers(),
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// SetBlobHTTPHeaders changes a blob's HTTP headers.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-blob-properties.
|
||||
func (b BlobURL) SetHTTPHeaders(ctx context.Context, h BlobHTTPHeaders, ac BlobAccessConditions) (*BlobsSetHTTPHeadersResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return b.blobClient.SetHTTPHeaders(ctx, nil,
|
||||
&h.CacheControl, &h.ContentType, h.ContentMD5, &h.ContentEncoding, &h.ContentLanguage,
|
||||
ac.LeaseAccessConditions.pointers(), ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
|
||||
&h.ContentDisposition, nil)
|
||||
}
|
||||
|
||||
// SetBlobMetadata changes a blob's metadata.
|
||||
// https://docs.microsoft.com/rest/api/storageservices/set-blob-metadata.
|
||||
func (b BlobURL) SetMetadata(ctx context.Context, metadata Metadata, ac BlobAccessConditions) (*BlobsSetMetadataResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return b.blobClient.SetMetadata(ctx, nil, metadata, ac.LeaseAccessConditions.pointers(),
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// CreateSnapshot creates a read-only snapshot of a blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/snapshot-blob.
|
||||
func (b BlobURL) CreateSnapshot(ctx context.Context, metadata Metadata, ac BlobAccessConditions) (*BlobsCreateSnapshotResponse, error) {
|
||||
// CreateSnapshot does NOT panic if the user tries to create a snapshot using a URL that already has a snapshot query parameter
|
||||
// because checking this would be a performance hit for a VERY unusual path and I don't think the common case should suffer this
|
||||
// performance hit.
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return b.blobClient.CreateSnapshot(ctx, nil, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, ac.LeaseAccessConditions.pointers(), nil)
|
||||
}
|
||||
|
||||
// AcquireLease acquires a lease on the blob for write and delete operations. The lease duration must be between
|
||||
// 15 to 60 seconds, or infinite (-1).
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob.
|
||||
func (b BlobURL) AcquireLease(ctx context.Context, proposedID string, duration int32, ac HTTPAccessConditions) (*BlobsAcquireLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
|
||||
return b.blobClient.AcquireLease(ctx, nil, &duration, &proposedID,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// RenewLease renews the blob's previously-acquired lease.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob.
|
||||
func (b BlobURL) RenewLease(ctx context.Context, leaseID string, ac HTTPAccessConditions) (*BlobsRenewLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
|
||||
return b.blobClient.RenewLease(ctx, leaseID, nil,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// ReleaseLease releases the blob's previously-acquired lease.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob.
|
||||
func (b BlobURL) ReleaseLease(ctx context.Context, leaseID string, ac HTTPAccessConditions) (*BlobsReleaseLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
|
||||
return b.blobClient.ReleaseLease(ctx, leaseID, nil,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// BreakLease breaks the blob's previously-acquired lease (if it exists). Pass the LeaseBreakDefault (-1)
|
||||
// constant to break a fixed-duration lease when it expires or an infinite lease immediately.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob.
|
||||
func (b BlobURL) BreakLease(ctx context.Context, breakPeriodInSeconds int32, ac HTTPAccessConditions) (*BlobsBreakLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
|
||||
return b.blobClient.BreakLease(ctx, nil, leasePeriodPointer(breakPeriodInSeconds),
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// ChangeLease changes the blob's lease ID.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob.
|
||||
func (b BlobURL) ChangeLease(ctx context.Context, leaseID string, proposedID string, ac HTTPAccessConditions) (*BlobsChangeLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers()
|
||||
return b.blobClient.ChangeLease(ctx, leaseID, proposedID,
|
||||
nil, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// LeaseBreakNaturally tells ContainerURL's or BlobURL's BreakLease method to break the lease using service semantics.
|
||||
const LeaseBreakNaturally = -1
|
||||
|
||||
func leasePeriodPointer(period int32) (p *int32) {
|
||||
if period != LeaseBreakNaturally {
|
||||
p = &period
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartCopyFromURL copies the data at the source URL to a blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/copy-blob.
|
||||
func (b BlobURL) StartCopyFromURL(ctx context.Context, source url.URL, metadata Metadata, srcac BlobAccessConditions, dstac BlobAccessConditions) (*BlobsStartCopyFromURLResponse, error) {
|
||||
srcIfModifiedSince, srcIfUnmodifiedSince, srcIfMatchETag, srcIfNoneMatchETag := srcac.HTTPAccessConditions.pointers()
|
||||
dstIfModifiedSince, dstIfUnmodifiedSince, dstIfMatchETag, dstIfNoneMatchETag := dstac.HTTPAccessConditions.pointers()
|
||||
srcLeaseID := srcac.LeaseAccessConditions.pointers()
|
||||
dstLeaseID := dstac.LeaseAccessConditions.pointers()
|
||||
|
||||
return b.blobClient.StartCopyFromURL(ctx, source.String(), nil, metadata,
|
||||
srcIfModifiedSince, srcIfUnmodifiedSince,
|
||||
srcIfMatchETag, srcIfNoneMatchETag,
|
||||
dstIfModifiedSince, dstIfUnmodifiedSince,
|
||||
dstIfMatchETag, dstIfNoneMatchETag,
|
||||
dstLeaseID, srcLeaseID, nil)
|
||||
}
|
||||
|
||||
// AbortCopyFromURL stops a pending copy that was previously started and leaves a destination blob with 0 length and metadata.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/abort-copy-blob.
|
||||
func (b BlobURL) AbortCopyFromURL(ctx context.Context, copyID string, ac LeaseAccessConditions) (*BlobsAbortCopyFromURLResponse, error) {
|
||||
return b.blobClient.AbortCopyFromURL(ctx, copyID, nil, ac.pointers(), nil)
|
||||
}
|
148
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/url_block_blob.go
generated
vendored
148
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/url_block_blob.go
generated
vendored
|
@ -1,148 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/url"
|
||||
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
const (
|
||||
// BlockBlobMaxPutBlobBytes indicates the maximum number of bytes that can be sent in a call to Upload.
|
||||
BlockBlobMaxUploadBlobBytes = 256 * 1024 * 1024 // 256MB
|
||||
|
||||
// BlockBlobMaxStageBlockBytes indicates the maximum number of bytes that can be sent in a call to StageBlock.
|
||||
BlockBlobMaxStageBlockBytes = 100 * 1024 * 1024 // 100MB
|
||||
|
||||
// BlockBlobMaxBlocks indicates the maximum number of blocks allowed in a block blob.
|
||||
BlockBlobMaxBlocks = 50000
|
||||
)
|
||||
|
||||
// BlockBlobURL defines a set of operations applicable to block blobs.
|
||||
type BlockBlobURL struct {
|
||||
BlobURL
|
||||
bbClient blockBlobsClient
|
||||
}
|
||||
|
||||
// NewBlockBlobURL creates a BlockBlobURL object using the specified URL and request policy pipeline.
|
||||
func NewBlockBlobURL(url url.URL, p pipeline.Pipeline) BlockBlobURL {
|
||||
if p == nil {
|
||||
panic("p can't be nil")
|
||||
}
|
||||
blobClient := newBlobsClient(url, p)
|
||||
bbClient := newBlockBlobsClient(url, p)
|
||||
return BlockBlobURL{BlobURL: BlobURL{blobClient: blobClient}, bbClient: bbClient}
|
||||
}
|
||||
|
||||
// WithPipeline creates a new BlockBlobURL object identical to the source but with the specific request policy pipeline.
|
||||
func (bb BlockBlobURL) WithPipeline(p pipeline.Pipeline) BlockBlobURL {
|
||||
return NewBlockBlobURL(bb.blobClient.URL(), p)
|
||||
}
|
||||
|
||||
// WithSnapshot creates a new BlockBlobURL object identical to the source but with the specified snapshot timestamp.
|
||||
// Pass "" to remove the snapshot returning a URL to the base blob.
|
||||
func (bb BlockBlobURL) WithSnapshot(snapshot string) BlockBlobURL {
|
||||
p := NewBlobURLParts(bb.URL())
|
||||
p.Snapshot = snapshot
|
||||
return NewBlockBlobURL(p.URL(), bb.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// Upload creates a new block blob or overwrites an existing block blob.
|
||||
// Updating an existing block blob overwrites any existing metadata on the blob. Partial updates are not
|
||||
// supported with Upload; the content of the existing blob is overwritten with the new content. To
|
||||
// perform a partial update of a block blob, use StageBlock and CommitBlockList.
|
||||
// This method panics if the stream is not at position 0.
|
||||
// Note that the http client closes the body stream after the request is sent to the service.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-blob.
|
||||
func (bb BlockBlobURL) Upload(ctx context.Context, body io.ReadSeeker, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions) (*BlockBlobsUploadResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return bb.bbClient.Upload(ctx, body, validateSeekableStreamAt0AndGetCount(body),nil,
|
||||
&h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5,
|
||||
&h.CacheControl, metadata, ac.LeaseAccessConditions.pointers(),
|
||||
&h.ContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
|
||||
nil)
|
||||
}
|
||||
|
||||
// StageBlock uploads the specified block to the block blob's "staging area" to be later committed by a call to CommitBlockList.
|
||||
// Note that the http client closes the body stream after the request is sent to the service.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-block.
|
||||
func (bb BlockBlobURL) StageBlock(ctx context.Context, base64BlockID string, body io.ReadSeeker, ac LeaseAccessConditions) (*BlockBlobsStageBlockResponse, error) {
|
||||
return bb.bbClient.StageBlock(ctx, base64BlockID, validateSeekableStreamAt0AndGetCount(body), body, nil, ac.pointers(), nil)
|
||||
}
|
||||
|
||||
// CommitBlockList writes a blob by specifying the list of block IDs that make up the blob.
|
||||
// In order to be written as part of a blob, a block must have been successfully written
|
||||
// to the server in a prior PutBlock operation. You can call PutBlockList to update a blob
|
||||
// by uploading only those blocks that have changed, then committing the new and existing
|
||||
// blocks together. Any blocks not specified in the block list and permanently deleted.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-block-list.
|
||||
func (bb BlockBlobURL) CommitBlockList(ctx context.Context, base64BlockIDs []string, h BlobHTTPHeaders,
|
||||
metadata Metadata, ac BlobAccessConditions) (*BlockBlobsCommitBlockListResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return bb.bbClient.CommitBlockList(ctx, BlockLookupList{Latest: base64BlockIDs}, nil,
|
||||
&h.CacheControl, &h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5,
|
||||
metadata, ac.LeaseAccessConditions.pointers(), &h.ContentDisposition,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// GetBlockList returns the list of blocks that have been uploaded as part of a block blob using the specified block list filter.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-block-list.
|
||||
func (bb BlockBlobURL) GetBlockList(ctx context.Context, listType BlockListType, ac LeaseAccessConditions) (*BlockList, error) {
|
||||
return bb.bbClient.GetBlockList(ctx, listType, nil, nil, ac.pointers(), nil)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type BlockID [64]byte
|
||||
|
||||
func (blockID BlockID) ToBase64() string {
|
||||
return base64.StdEncoding.EncodeToString(blockID[:])
|
||||
}
|
||||
|
||||
func (blockID *BlockID) FromBase64(s string) error {
|
||||
*blockID = BlockID{} // Zero out the block ID
|
||||
_, err := base64.StdEncoding.Decode(blockID[:], ([]byte)(s))
|
||||
return err
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type uuidBlockID BlockID
|
||||
|
||||
func (ubi uuidBlockID) UUID() uuid {
|
||||
u := uuid{}
|
||||
copy(u[:], ubi[:len(u)])
|
||||
return u
|
||||
}
|
||||
|
||||
func (ubi uuidBlockID) Number() uint32 {
|
||||
return binary.BigEndian.Uint32(ubi[len(uuid{}):])
|
||||
}
|
||||
|
||||
func newUuidBlockID(u uuid) uuidBlockID {
|
||||
ubi := uuidBlockID{} // Create a new uuidBlockID
|
||||
copy(ubi[:len(u)], u[:]) // Copy the specified UUID into it
|
||||
// Block number defaults to 0
|
||||
return ubi
|
||||
}
|
||||
|
||||
func (ubi *uuidBlockID) SetUUID(u uuid) *uuidBlockID {
|
||||
copy(ubi[:len(u)], u[:])
|
||||
return ubi
|
||||
}
|
||||
|
||||
func (ubi uuidBlockID) WithBlockNumber(blockNumber uint32) uuidBlockID {
|
||||
binary.BigEndian.PutUint32(ubi[len(uuid{}):], blockNumber) // Put block number after UUID
|
||||
return ubi // Return the passed-in copy
|
||||
}
|
||||
|
||||
func (ubi uuidBlockID) ToBase64() string {
|
||||
return BlockID(ubi).ToBase64()
|
||||
}
|
||||
|
||||
func (ubi *uuidBlockID) FromBase64(s string) error {
|
||||
return (*BlockID)(ubi).FromBase64(s)
|
||||
}
|
301
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/url_container.go
generated
vendored
301
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/url_container.go
generated
vendored
|
@ -1,301 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// A ContainerURL represents a URL to the Azure Storage container allowing you to manipulate its blobs.
|
||||
type ContainerURL struct {
|
||||
client containersClient
|
||||
}
|
||||
|
||||
// NewContainerURL creates a ContainerURL object using the specified URL and request policy pipeline.
|
||||
func NewContainerURL(url url.URL, p pipeline.Pipeline) ContainerURL {
|
||||
if p == nil {
|
||||
panic("p can't be nil")
|
||||
}
|
||||
client := newContainersClient(url, p)
|
||||
return ContainerURL{client: client}
|
||||
}
|
||||
|
||||
// URL returns the URL endpoint used by the ContainerURL object.
|
||||
func (c ContainerURL) URL() url.URL {
|
||||
return c.client.URL()
|
||||
}
|
||||
|
||||
// String returns the URL as a string.
|
||||
func (c ContainerURL) String() string {
|
||||
u := c.URL()
|
||||
return u.String()
|
||||
}
|
||||
|
||||
// WithPipeline creates a new ContainerURL object identical to the source but with the specified request policy pipeline.
|
||||
func (c ContainerURL) WithPipeline(p pipeline.Pipeline) ContainerURL {
|
||||
return NewContainerURL(c.URL(), p)
|
||||
}
|
||||
|
||||
// NewBlobURL creates a new BlobURL object by concatenating blobName to the end of
|
||||
// ContainerURL's URL. The new BlobURL uses the same request policy pipeline as the ContainerURL.
|
||||
// To change the pipeline, create the BlobURL and then call its WithPipeline method passing in the
|
||||
// desired pipeline object. Or, call this package's NewBlobURL instead of calling this object's
|
||||
// NewBlobURL method.
|
||||
func (c ContainerURL) NewBlobURL(blobName string) BlobURL {
|
||||
blobURL := appendToURLPath(c.URL(), blobName)
|
||||
return NewBlobURL(blobURL, c.client.Pipeline())
|
||||
}
|
||||
|
||||
// NewAppendBlobURL creates a new AppendBlobURL object by concatenating blobName to the end of
|
||||
// ContainerURL's URL. The new AppendBlobURL uses the same request policy pipeline as the ContainerURL.
|
||||
// To change the pipeline, create the AppendBlobURL and then call its WithPipeline method passing in the
|
||||
// desired pipeline object. Or, call this package's NewAppendBlobURL instead of calling this object's
|
||||
// NewAppendBlobURL method.
|
||||
func (c ContainerURL) NewAppendBlobURL(blobName string) AppendBlobURL {
|
||||
blobURL := appendToURLPath(c.URL(), blobName)
|
||||
return NewAppendBlobURL(blobURL, c.client.Pipeline())
|
||||
}
|
||||
|
||||
// NewBlockBlobURL creates a new BlockBlobURL object by concatenating blobName to the end of
|
||||
// ContainerURL's URL. The new BlockBlobURL uses the same request policy pipeline as the ContainerURL.
|
||||
// To change the pipeline, create the BlockBlobURL and then call its WithPipeline method passing in the
|
||||
// desired pipeline object. Or, call this package's NewBlockBlobURL instead of calling this object's
|
||||
// NewBlockBlobURL method.
|
||||
func (c ContainerURL) NewBlockBlobURL(blobName string) BlockBlobURL {
|
||||
blobURL := appendToURLPath(c.URL(), blobName)
|
||||
return NewBlockBlobURL(blobURL, c.client.Pipeline())
|
||||
}
|
||||
|
||||
// NewPageBlobURL creates a new PageBlobURL object by concatenating blobName to the end of
|
||||
// ContainerURL's URL. The new PageBlobURL uses the same request policy pipeline as the ContainerURL.
|
||||
// To change the pipeline, create the PageBlobURL and then call its WithPipeline method passing in the
|
||||
// desired pipeline object. Or, call this package's NewPageBlobURL instead of calling this object's
|
||||
// NewPageBlobURL method.
|
||||
func (c ContainerURL) NewPageBlobURL(blobName string) PageBlobURL {
|
||||
blobURL := appendToURLPath(c.URL(), blobName)
|
||||
return NewPageBlobURL(blobURL, c.client.Pipeline())
|
||||
}
|
||||
|
||||
// Create creates a new container within a storage account. If a container with the same name already exists, the operation fails.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/create-container.
|
||||
func (c ContainerURL) Create(ctx context.Context, metadata Metadata, publicAccessType PublicAccessType) (*ContainersCreateResponse, error) {
|
||||
return c.client.Create(ctx, nil, metadata, publicAccessType, nil)
|
||||
}
|
||||
|
||||
// Delete marks the specified container for deletion. The container and any blobs contained within it are later deleted during garbage collection.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/delete-container.
|
||||
func (c ContainerURL) Delete(ctx context.Context, ac ContainerAccessConditions) (*ContainersDeleteResponse, error) {
|
||||
if ac.IfMatch != ETagNone || ac.IfNoneMatch != ETagNone {
|
||||
panic("the IfMatch and IfNoneMatch access conditions must have their default values because they are ignored by the service")
|
||||
}
|
||||
|
||||
ifModifiedSince, ifUnmodifiedSince, _, _:= ac.HTTPAccessConditions.pointers()
|
||||
return c.client.Delete(ctx, nil, ac.LeaseAccessConditions.pointers(),
|
||||
ifModifiedSince, ifUnmodifiedSince, nil)
|
||||
}
|
||||
|
||||
// GetContainerProperties returns the container's properties.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-container-metadata.
|
||||
func (c ContainerURL) GetProperties(ctx context.Context, ac LeaseAccessConditions) (*ContainersGetPropertiesResponse, error) {
|
||||
// NOTE: GetMetadata actually calls GetProperties internally because GetProperties returns the metadata AND the properties.
|
||||
// This allows us to not expose a GetProperties method at all simplifying the API.
|
||||
return c.client.GetProperties(ctx, nil, ac.pointers(), nil)
|
||||
}
|
||||
|
||||
// SetContainerMetadata sets the container's metadata.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-container-metadata.
|
||||
func (c ContainerURL) SetMetadata(ctx context.Context, metadata Metadata, ac ContainerAccessConditions) (*ContainersSetMetadataResponse, error) {
|
||||
if !ac.IfUnmodifiedSince.IsZero() || ac.IfMatch != ETagNone || ac.IfNoneMatch != ETagNone {
|
||||
panic("the IfUnmodifiedSince, IfMatch, and IfNoneMatch must have their default values because they are ignored by the blob service")
|
||||
}
|
||||
ifModifiedSince, _, _, _ := ac.HTTPAccessConditions.pointers()
|
||||
return c.client.SetMetadata(ctx, nil, ac.LeaseAccessConditions.pointers(), metadata, ifModifiedSince, nil)
|
||||
}
|
||||
|
||||
// GetContainerAccessPolicy returns the container's access policy. The access policy indicates whether container's blobs may be accessed publicly.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-container-acl.
|
||||
func (c ContainerURL) GetAccessPolicy(ctx context.Context, ac LeaseAccessConditions) (*SignedIdentifiers, error) {
|
||||
return c.client.GetAccessPolicy(ctx, nil, ac.pointers(), nil)
|
||||
}
|
||||
|
||||
// The AccessPolicyPermission type simplifies creating the permissions string for a container's access policy.
|
||||
// Initialize an instance of this type and then call its String method to set AccessPolicy's Permission field.
|
||||
type AccessPolicyPermission struct {
|
||||
Read, Add, Create, Write, Delete, List bool
|
||||
}
|
||||
|
||||
// String produces the access policy permission string for an Azure Storage container.
|
||||
// Call this method to set AccessPolicy's Permission field.
|
||||
func (p AccessPolicyPermission) String() string {
|
||||
var b bytes.Buffer
|
||||
if p.Read {
|
||||
b.WriteRune('r')
|
||||
}
|
||||
if p.Add {
|
||||
b.WriteRune('a')
|
||||
}
|
||||
if p.Create {
|
||||
b.WriteRune('c')
|
||||
}
|
||||
if p.Write {
|
||||
b.WriteRune('w')
|
||||
}
|
||||
if p.Delete {
|
||||
b.WriteRune('d')
|
||||
}
|
||||
if p.List {
|
||||
b.WriteRune('l')
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Parse initializes the AccessPolicyPermission's fields from a string.
|
||||
func (p *AccessPolicyPermission) Parse(s string) error {
|
||||
*p = AccessPolicyPermission{} // Clear the flags
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 'r':
|
||||
p.Read = true
|
||||
case 'a':
|
||||
p.Add = true
|
||||
case 'c':
|
||||
p.Create = true
|
||||
case 'w':
|
||||
p.Write = true
|
||||
case 'd':
|
||||
p.Delete = true
|
||||
case 'l':
|
||||
p.List = true
|
||||
default:
|
||||
return fmt.Errorf("invalid permission: '%v'", r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetContainerAccessPolicy sets the container's permissions. The access policy indicates whether blobs in a container may be accessed publicly.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-container-acl.
|
||||
func (c ContainerURL) SetAccessPolicy(ctx context.Context, accessType PublicAccessType, si []SignedIdentifier,
|
||||
ac ContainerAccessConditions) (*ContainersSetAccessPolicyResponse, error) {
|
||||
if ac.IfMatch != ETagNone || ac.IfNoneMatch != ETagNone {
|
||||
panic("the IfMatch and IfNoneMatch access conditions must have their default values because they are ignored by the service")
|
||||
}
|
||||
ifModifiedSince, ifUnmodifiedSince, _, _:= ac.HTTPAccessConditions.pointers()
|
||||
return c.client.SetAccessPolicy(ctx, si, nil, ac.LeaseAccessConditions.pointers(),
|
||||
accessType, ifModifiedSince, ifUnmodifiedSince, nil)
|
||||
}
|
||||
|
||||
// AcquireContainerLease acquires a lease on the container for delete operations. The lease duration must be between 15 to 60 seconds, or infinite (-1).
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container.
|
||||
func (c ContainerURL) AcquireLease(ctx context.Context, proposedID string, duration int32, ac HTTPAccessConditions) (*ContainersAcquireLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers()
|
||||
return c.client.AcquireLease(ctx, nil, &duration, &proposedID,
|
||||
ifModifiedSince, ifUnmodifiedSince, nil)
|
||||
}
|
||||
|
||||
// RenewContainerLease renews the container's previously-acquired lease.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container.
|
||||
func (c ContainerURL) RenewLease(ctx context.Context, leaseID string, ac HTTPAccessConditions) (*ContainersRenewLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers()
|
||||
return c.client.RenewLease(ctx, leaseID, nil, ifModifiedSince, ifUnmodifiedSince, nil)
|
||||
}
|
||||
|
||||
// ReleaseContainerLease releases the container's previously-acquired lease.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container.
|
||||
func (c ContainerURL) ReleaseLease(ctx context.Context, leaseID string, ac HTTPAccessConditions) (*ContainersReleaseLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers()
|
||||
return c.client.ReleaseLease(ctx,leaseID, nil, ifModifiedSince, ifUnmodifiedSince, nil)
|
||||
}
|
||||
|
||||
// BreakContainerLease breaks the container's previously-acquired lease (if it exists).
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container.
|
||||
func (c ContainerURL) BreakLease(ctx context.Context, period int32, ac HTTPAccessConditions) (*ContainersBreakLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers()
|
||||
return c.client.BreakLease(ctx, nil, leasePeriodPointer(period), ifModifiedSince, ifUnmodifiedSince, nil)
|
||||
}
|
||||
|
||||
// ChangeContainerLease changes the container's lease ID.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container.
|
||||
func (c ContainerURL) ChangeLease(ctx context.Context, leaseID string, proposedID string, ac HTTPAccessConditions) (*ContainersChangeLeaseResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers()
|
||||
return c.client.ChangeLease(ctx, leaseID, proposedID, nil, ifModifiedSince, ifUnmodifiedSince, nil)
|
||||
}
|
||||
|
||||
// ListBlobsFlatSegment returns a single segment of blobs starting from the specified Marker. Use an empty
|
||||
// Marker to start enumeration from the beginning. Blob names are returned in lexicographic order.
|
||||
// After getting a segment, process it, and then call ListBlobsFlatSegment again (passing the the
|
||||
// previously-returned Marker) to get the next segment.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/list-blobs.
|
||||
func (c ContainerURL) ListBlobsFlatSegment(ctx context.Context, marker Marker, o ListBlobsSegmentOptions) (*ListBlobsFlatResponse, error) {
|
||||
prefix, include, maxResults := o.pointers()
|
||||
return c.client.ListBlobFlatSegment(ctx, prefix, marker.val, maxResults, include, nil, nil)
|
||||
}
|
||||
|
||||
// ListBlobsHierarchicalSegment returns a single segment of blobs starting from the specified Marker. Use an empty
|
||||
// Marker to start enumeration from the beginning. Blob names are returned in lexicographic order.
|
||||
// After getting a segment, process it, and then call ListBlobsHierarchicalSegment again (passing the the
|
||||
// previously-returned Marker) to get the next segment.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/list-blobs.
|
||||
func (c ContainerURL) ListBlobsHierarchySegment(ctx context.Context, marker Marker, delimiter string, o ListBlobsSegmentOptions) (*ListBlobsHierarchyResponse, error) {
|
||||
if o.Details.Snapshots {
|
||||
panic("snapshots are not supported in this listing operation")
|
||||
}
|
||||
prefix, include, maxResults := o.pointers()
|
||||
return c.client.ListBlobHierarchySegment(ctx, delimiter, prefix, marker.val, maxResults, include, nil, nil)
|
||||
}
|
||||
|
||||
|
||||
// ListBlobsOptions defines options available when calling ListBlobs.
|
||||
type ListBlobsSegmentOptions struct {
|
||||
Details BlobListingDetails // No IncludeType header is produced if ""
|
||||
Prefix string // No Prefix header is produced if ""
|
||||
|
||||
// SetMaxResults sets the maximum desired results you want the service to return. Note, the
|
||||
// service may return fewer results than requested.
|
||||
// MaxResults=0 means no 'MaxResults' header specified.
|
||||
MaxResults int32
|
||||
}
|
||||
|
||||
func (o *ListBlobsSegmentOptions) pointers() (prefix *string, include []ListBlobsIncludeItemType, maxResults *int32) {
|
||||
if o.Prefix != "" {
|
||||
prefix = &o.Prefix
|
||||
}
|
||||
include = o.Details.slice()
|
||||
if o.MaxResults != 0 {
|
||||
if o.MaxResults < 0 {
|
||||
panic("MaxResults must be >= 0")
|
||||
}
|
||||
maxResults = &o.MaxResults
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// BlobListingDetails indicates what additional information the service should return with each blob.
|
||||
type BlobListingDetails struct {
|
||||
Copy, Metadata, Snapshots, UncommittedBlobs, Deleted bool
|
||||
}
|
||||
|
||||
// string produces the Include query parameter's value.
|
||||
func (d *BlobListingDetails) slice() []ListBlobsIncludeItemType {
|
||||
items := []ListBlobsIncludeItemType{}
|
||||
// NOTE: Multiple strings MUST be appended in alphabetic order or signing the string for authentication fails!
|
||||
if d.Copy {
|
||||
items = append(items, ListBlobsIncludeItemCopy)
|
||||
}
|
||||
if d.Deleted {
|
||||
items = append(items, ListBlobsIncludeItemDeleted)
|
||||
}
|
||||
if d.Metadata {
|
||||
items = append(items, ListBlobsIncludeItemMetadata)
|
||||
}
|
||||
if d.Snapshots {
|
||||
items = append(items, ListBlobsIncludeItemSnapshots)
|
||||
}
|
||||
if d.UncommittedBlobs {
|
||||
items = append(items, ListBlobsIncludeItemUncommittedblobs)
|
||||
}
|
||||
return items
|
||||
}
|
236
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/url_page_blob.go
generated
vendored
236
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/url_page_blob.go
generated
vendored
|
@ -1,236 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
const (
|
||||
// PageBlobPageBytes indicates the number of bytes in a page (512).
|
||||
PageBlobPageBytes = 512
|
||||
|
||||
// PageBlobMaxPutPagesBytes indicates the maximum number of bytes that can be sent in a call to PutPage.
|
||||
PageBlobMaxUploadPagesBytes = 4 * 1024 * 1024 // 4MB
|
||||
)
|
||||
|
||||
// PageBlobURL defines a set of operations applicable to page blobs.
|
||||
type PageBlobURL struct {
|
||||
BlobURL
|
||||
pbClient pageBlobsClient
|
||||
}
|
||||
|
||||
// NewPageBlobURL creates a PageBlobURL object using the specified URL and request policy pipeline.
|
||||
func NewPageBlobURL(url url.URL, p pipeline.Pipeline) PageBlobURL {
|
||||
if p == nil {
|
||||
panic("p can't be nil")
|
||||
}
|
||||
blobClient := newBlobsClient(url, p)
|
||||
pbClient := newPageBlobsClient(url, p)
|
||||
return PageBlobURL{BlobURL: BlobURL{blobClient: blobClient}, pbClient: pbClient}
|
||||
}
|
||||
|
||||
// WithPipeline creates a new PageBlobURL object identical to the source but with the specific request policy pipeline.
|
||||
func (pb PageBlobURL) WithPipeline(p pipeline.Pipeline) PageBlobURL {
|
||||
return NewPageBlobURL(pb.blobClient.URL(), p)
|
||||
}
|
||||
|
||||
// WithSnapshot creates a new PageBlobURL object identical to the source but with the specified snapshot timestamp.
|
||||
// Pass "" to remove the snapshot returning a URL to the base blob.
|
||||
func (pb PageBlobURL) WithSnapshot(snapshot string) PageBlobURL {
|
||||
p := NewBlobURLParts(pb.URL())
|
||||
p.Snapshot = snapshot
|
||||
return NewPageBlobURL(p.URL(), pb.blobClient.Pipeline())
|
||||
}
|
||||
|
||||
// CreatePageBlob creates a page blob of the specified length. Call PutPage to upload data data to a page blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-blob.
|
||||
func (pb PageBlobURL) Create(ctx context.Context, size int64, sequenceNumber int64, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions) (*PageBlobsCreateResponse, error) {
|
||||
if sequenceNumber < 0 {
|
||||
panic("sequenceNumber must be greater than or equal to 0")
|
||||
}
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return pb.pbClient.Create(ctx, 0, nil,
|
||||
&h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5, &h.CacheControl,
|
||||
metadata, ac.LeaseAccessConditions.pointers(),
|
||||
&h.ContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, &size, &sequenceNumber, nil)
|
||||
}
|
||||
|
||||
// UploadPages writes 1 or more pages to the page blob. The start offset and the stream size must be a multiple of 512 bytes.
|
||||
// This method panics if the stream is not at position 0.
|
||||
// Note that the http client closes the body stream after the request is sent to the service.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-page.
|
||||
func (pb PageBlobURL) UploadPages(ctx context.Context, offset int64, body io.ReadSeeker, ac BlobAccessConditions) (*PageBlobsUploadPagesResponse, error) {
|
||||
count := validateSeekableStreamAt0AndGetCount(body)
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual := ac.PageBlobAccessConditions.pointers()
|
||||
return pb.pbClient.UploadPages(ctx, body, count, nil,
|
||||
PageRange{Start: offset, End: offset + count - 1}.pointers(),
|
||||
ac.LeaseAccessConditions.pointers(),
|
||||
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// ClearPages frees the specified pages from the page blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-page.
|
||||
func (pb PageBlobURL) ClearPages(ctx context.Context, offset int64, count int64, ac BlobAccessConditions) (*PageBlobsClearPagesResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual := ac.PageBlobAccessConditions.pointers()
|
||||
return pb.pbClient.ClearPages(ctx, 0, nil,
|
||||
PageRange{Start: offset, End: offset + count - 1}.pointers(),
|
||||
ac.LeaseAccessConditions.pointers(),
|
||||
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan,
|
||||
ifSequenceNumberEqual, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// GetPageRanges returns the list of valid page ranges for a page blob or snapshot of a page blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-page-ranges.
|
||||
func (pb PageBlobURL) GetPageRanges(ctx context.Context, offset int64, count int64, ac BlobAccessConditions) (*PageList, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return pb.pbClient.GetPageRanges(ctx, nil, nil,
|
||||
httpRange{offset: offset, count: count}.pointers(),
|
||||
ac.LeaseAccessConditions.pointers(),
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// GetPageRangesDiff gets the collection of page ranges that differ between a specified snapshot and this page blob.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-page-ranges.
|
||||
func (pb PageBlobURL) GetPageRangesDiff(ctx context.Context, offset int64, count int64, prevSnapshot string, ac BlobAccessConditions) (*PageList, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return pb.pbClient.GetPageRangesDiff(ctx, nil, nil, &prevSnapshot,
|
||||
httpRange{offset: offset, count: count}.pointers(),
|
||||
ac.LeaseAccessConditions.pointers(),
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
|
||||
nil)
|
||||
}
|
||||
|
||||
// Resize resizes the page blob to the specified size (which must be a multiple of 512).
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-blob-properties.
|
||||
func (pb PageBlobURL) Resize(ctx context.Context, size int64, ac BlobAccessConditions) (*PageBlobsResizeResponse, error) {
|
||||
if size%PageBlobPageBytes != 0 {
|
||||
panic("Size must be a multiple of PageBlobPageBytes (512)")
|
||||
}
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
return pb.pbClient.Resize(ctx, size, nil, ac.LeaseAccessConditions.pointers(),
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
// SetSequenceNumber sets the page blob's sequence number.
|
||||
func (pb PageBlobURL) UpdateSequenceNumber(ctx context.Context, action SequenceNumberActionType, sequenceNumber int64,
|
||||
ac BlobAccessConditions) (*PageBlobsUpdateSequenceNumberResponse, error) {
|
||||
if sequenceNumber < 0 {
|
||||
panic("sequenceNumber must be greater than or equal to 0")
|
||||
}
|
||||
sn := &sequenceNumber
|
||||
if action == SequenceNumberActionIncrement {
|
||||
sn = nil
|
||||
}
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch := ac.HTTPAccessConditions.pointers()
|
||||
return pb.pbClient.UpdateSequenceNumber(ctx, action, nil,
|
||||
ac.LeaseAccessConditions.pointers(), ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch,
|
||||
sn, nil)
|
||||
}
|
||||
|
||||
// StartIncrementalCopy begins an operation to start an incremental copy from one page blob's snapshot to this page blob.
|
||||
// The snapshot is copied such that only the differential changes between the previously copied snapshot are transferred to the destination.
|
||||
// The copied snapshots are complete copies of the original snapshot and can be read or copied from as usual.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/incremental-copy-blob and
|
||||
// https://docs.microsoft.com/en-us/azure/virtual-machines/windows/incremental-snapshots.
|
||||
func (pb PageBlobURL) StartCopyIncremental(ctx context.Context, source url.URL, snapshot string, ac BlobAccessConditions) (*PageBlobsCopyIncrementalResponse, error) {
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers()
|
||||
qp := source.Query()
|
||||
qp.Set("snapshot", snapshot)
|
||||
source.RawQuery = qp.Encode()
|
||||
return pb.pbClient.CopyIncremental(ctx, source.String(), nil, nil,
|
||||
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
|
||||
}
|
||||
|
||||
func (pr PageRange) pointers() *string {
|
||||
if pr.Start < 0 {
|
||||
panic("PageRange's Start value must be greater than or equal to 0")
|
||||
}
|
||||
if pr.End <= 0 {
|
||||
panic("PageRange's End value must be greater than 0")
|
||||
}
|
||||
if pr.Start%PageBlobPageBytes != 0 {
|
||||
panic("PageRange's Start value must be a multiple of 512")
|
||||
}
|
||||
if pr.End%PageBlobPageBytes != (PageBlobPageBytes - 1) {
|
||||
panic("PageRange's End value must be 1 less than a multiple of 512")
|
||||
}
|
||||
if pr.End <= pr.Start {
|
||||
panic("PageRange's End value must be after the start")
|
||||
}
|
||||
endOffset := strconv.FormatInt(int64(pr.End), 10)
|
||||
asString := fmt.Sprintf("bytes=%v-%s", pr.Start, endOffset)
|
||||
return &asString
|
||||
}
|
||||
|
||||
// PageBlobAccessConditions identifies page blob-specific access conditions which you optionally set.
|
||||
type PageBlobAccessConditions struct {
|
||||
// IfSequenceNumberLessThan ensures that the page blob operation succeeds
|
||||
// only if the blob's sequence number is less than a value.
|
||||
// IfSequenceNumberLessThan=0 means no 'IfSequenceNumberLessThan' header specified.
|
||||
// IfSequenceNumberLessThan>0 means 'IfSequenceNumberLessThan' header specified with its value
|
||||
// IfSequenceNumberLessThan==-1 means 'IfSequenceNumberLessThan' header specified with a value of 0
|
||||
IfSequenceNumberLessThan int64
|
||||
|
||||
// IfSequenceNumberLessThanOrEqual ensures that the page blob operation succeeds
|
||||
// only if the blob's sequence number is less than or equal to a value.
|
||||
// IfSequenceNumberLessThanOrEqual=0 means no 'IfSequenceNumberLessThanOrEqual' header specified.
|
||||
// IfSequenceNumberLessThanOrEqual>0 means 'IfSequenceNumberLessThanOrEqual' header specified with its value
|
||||
// IfSequenceNumberLessThanOrEqual=-1 means 'IfSequenceNumberLessThanOrEqual' header specified with a value of 0
|
||||
IfSequenceNumberLessThanOrEqual int64
|
||||
|
||||
// IfSequenceNumberEqual ensures that the page blob operation succeeds
|
||||
// only if the blob's sequence number is equal to a value.
|
||||
// IfSequenceNumberEqual=0 means no 'IfSequenceNumberEqual' header specified.
|
||||
// IfSequenceNumberEqual>0 means 'IfSequenceNumberEqual' header specified with its value
|
||||
// IfSequenceNumberEqual=-1 means 'IfSequenceNumberEqual' header specified with a value of 0
|
||||
IfSequenceNumberEqual int64
|
||||
}
|
||||
|
||||
// pointers is for internal infrastructure. It returns the fields as pointers.
|
||||
func (ac PageBlobAccessConditions) pointers() (snltoe *int64, snlt *int64, sne *int64) {
|
||||
if ac.IfSequenceNumberLessThan < -1 {
|
||||
panic("Ifsequencenumberlessthan can't be less than -1")
|
||||
}
|
||||
if ac.IfSequenceNumberLessThanOrEqual < -1 {
|
||||
panic("IfSequenceNumberLessThanOrEqual can't be less than -1")
|
||||
}
|
||||
if ac.IfSequenceNumberEqual < -1 {
|
||||
panic("IfSequenceNumberEqual can't be less than -1")
|
||||
}
|
||||
|
||||
var zero int64 // Defaults to 0
|
||||
switch ac.IfSequenceNumberLessThan {
|
||||
case -1:
|
||||
snlt = &zero
|
||||
case 0:
|
||||
snlt = nil
|
||||
default:
|
||||
snlt = &ac.IfSequenceNumberLessThan
|
||||
}
|
||||
|
||||
switch ac.IfSequenceNumberLessThanOrEqual {
|
||||
case -1:
|
||||
snltoe = &zero
|
||||
case 0:
|
||||
snltoe = nil
|
||||
default:
|
||||
snltoe = &ac.IfSequenceNumberLessThanOrEqual
|
||||
}
|
||||
switch ac.IfSequenceNumberEqual {
|
||||
case -1:
|
||||
sne = &zero
|
||||
case 0:
|
||||
sne = nil
|
||||
default:
|
||||
sne = &ac.IfSequenceNumberEqual
|
||||
}
|
||||
return
|
||||
}
|
140
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/url_service.go
generated
vendored
140
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/url_service.go
generated
vendored
|
@ -1,140 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
const (
|
||||
// ContainerNameRoot is the special Azure Storage name used to identify a storage account's root container.
|
||||
ContainerNameRoot = "$root"
|
||||
|
||||
// ContainerNameLogs is the special Azure Storage name used to identify a storage account's logs container.
|
||||
ContainerNameLogs = "$logs"
|
||||
)
|
||||
|
||||
// A ServiceURL represents a URL to the Azure Storage Blob service allowing you to manipulate blob containers.
|
||||
type ServiceURL struct {
|
||||
client serviceClient
|
||||
}
|
||||
|
||||
// NewServiceURL creates a ServiceURL object using the specified URL and request policy pipeline.
|
||||
func NewServiceURL(primaryURL url.URL, p pipeline.Pipeline) ServiceURL {
|
||||
if p == nil {
|
||||
panic("p can't be nil")
|
||||
}
|
||||
client := newServiceClient(primaryURL, p)
|
||||
return ServiceURL{client: client}
|
||||
}
|
||||
|
||||
// URL returns the URL endpoint used by the ServiceURL object.
|
||||
func (s ServiceURL) URL() url.URL {
|
||||
return s.client.URL()
|
||||
}
|
||||
|
||||
// String returns the URL as a string.
|
||||
func (s ServiceURL) String() string {
|
||||
u := s.URL()
|
||||
return u.String()
|
||||
}
|
||||
|
||||
// WithPipeline creates a new ServiceURL object identical to the source but with the specified request policy pipeline.
|
||||
func (s ServiceURL) WithPipeline(p pipeline.Pipeline) ServiceURL {
|
||||
return NewServiceURL(s.URL(), p)
|
||||
}
|
||||
|
||||
// NewContainerURL creates a new ContainerURL object by concatenating containerName to the end of
|
||||
// ServiceURL's URL. The new ContainerURL uses the same request policy pipeline as the ServiceURL.
|
||||
// To change the pipeline, create the ContainerURL and then call its WithPipeline method passing in the
|
||||
// desired pipeline object. Or, call this package's NewContainerURL instead of calling this object's
|
||||
// NewContainerURL method.
|
||||
func (s ServiceURL) NewContainerURL(containerName string) ContainerURL {
|
||||
containerURL := appendToURLPath(s.URL(), containerName)
|
||||
return NewContainerURL(containerURL, s.client.Pipeline())
|
||||
}
|
||||
|
||||
// appendToURLPath appends a string to the end of a URL's path (prefixing the string with a '/' if required)
|
||||
func appendToURLPath(u url.URL, name string) url.URL {
|
||||
// e.g. "https://ms.com/a/b/?k1=v1&k2=v2#f"
|
||||
// When you call url.Parse() this is what you'll get:
|
||||
// Scheme: "https"
|
||||
// Opaque: ""
|
||||
// User: nil
|
||||
// Host: "ms.com"
|
||||
// Path: "/a/b/" This should start with a / and it might or might not have a trailing slash
|
||||
// RawPath: ""
|
||||
// ForceQuery: false
|
||||
// RawQuery: "k1=v1&k2=v2"
|
||||
// Fragment: "f"
|
||||
if len(u.Path) == 0 || u.Path[len(u.Path)-1] != '/' {
|
||||
u.Path += "/" // Append "/" to end before appending name
|
||||
}
|
||||
u.Path += name
|
||||
return u
|
||||
}
|
||||
|
||||
// ListContainersFlatSegment returns a single segment of containers starting from the specified Marker. Use an empty
|
||||
// Marker to start enumeration from the beginning. Container names are returned in lexicographic order.
|
||||
// After getting a segment, process it, and then call ListContainersFlatSegment again (passing the the
|
||||
// previously-returned Marker) to get the next segment. For more information, see
|
||||
// https://docs.microsoft.com/rest/api/storageservices/list-containers2.
|
||||
func (s ServiceURL) ListContainersSegment(ctx context.Context, marker Marker, o ListContainersSegmentOptions) (*ListContainersResponse, error) {
|
||||
prefix, include, maxResults := o.pointers()
|
||||
return s.client.ListContainersSegment(ctx, prefix, marker.val, maxResults, include, nil, nil)
|
||||
}
|
||||
|
||||
// ListContainersOptions defines options available when calling ListContainers.
|
||||
type ListContainersSegmentOptions struct {
|
||||
Detail ListContainersDetail // No IncludeType header is produced if ""
|
||||
Prefix string // No Prefix header is produced if ""
|
||||
MaxResults int32 // 0 means unspecified
|
||||
// TODO: update swagger to generate this type?
|
||||
}
|
||||
|
||||
func (o *ListContainersSegmentOptions) pointers() (prefix *string, include ListContainersIncludeType, maxResults *int32) {
|
||||
if o.Prefix != "" {
|
||||
prefix = &o.Prefix
|
||||
}
|
||||
if o.MaxResults != 0 {
|
||||
if o.MaxResults < 0 {
|
||||
panic("MaxResults must be >= 0")
|
||||
}
|
||||
maxResults = &o.MaxResults
|
||||
}
|
||||
include = ListContainersIncludeType(o.Detail.string())
|
||||
return
|
||||
}
|
||||
|
||||
// ListContainersFlatDetail indicates what additional information the service should return with each container.
|
||||
type ListContainersDetail struct {
|
||||
// Tells the service whether to return metadata for each container.
|
||||
Metadata bool
|
||||
}
|
||||
|
||||
// string produces the Include query parameter's value.
|
||||
func (d *ListContainersDetail) string() string {
|
||||
items := make([]string, 0, 1)
|
||||
// NOTE: Multiple strings MUST be appended in alphabetic order or signing the string for authentication fails!
|
||||
if d.Metadata {
|
||||
items = append(items, string(ListContainersIncludeMetadata))
|
||||
}
|
||||
if len(items) > 0 {
|
||||
return strings.Join(items, ",")
|
||||
}
|
||||
return string(ListContainersIncludeNone)
|
||||
}
|
||||
|
||||
func (bsu ServiceURL) GetProperties(ctx context.Context) (*StorageServiceProperties, error) {
|
||||
return bsu.client.GetProperties(ctx, nil, nil)
|
||||
}
|
||||
|
||||
func (bsu ServiceURL) SetProperties(ctx context.Context, properties StorageServiceProperties) (*ServiceSetPropertiesResponse, error) {
|
||||
return bsu.client.SetProperties(ctx, properties, nil, nil)
|
||||
}
|
||||
|
||||
func (bsu ServiceURL) GetStatistics(ctx context.Context) (*StorageServiceStats, error) {
|
||||
return bsu.client.GetStatistics(ctx, nil, nil)
|
||||
}
|
3
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/version.go
generated
vendored
3
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/version.go
generated
vendored
|
@ -1,3 +0,0 @@
|
|||
package azblob
|
||||
|
||||
const serviceLibVersion = "0.1"
|
|
@ -1,55 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// Credential represent any credential type; it is used to create a credential policy Factory.
|
||||
type Credential interface {
|
||||
pipeline.Factory
|
||||
credentialMarker()
|
||||
}
|
||||
|
||||
type credentialFunc pipeline.FactoryFunc
|
||||
|
||||
func (f credentialFunc) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
return f(next, po)
|
||||
}
|
||||
|
||||
// credentialMarker is a package-internal method that exists just to satisfy the Credential interface.
|
||||
func (credentialFunc) credentialMarker() {}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// NewAnonymousCredential creates an anonymous credential for use with HTTP(S) requests that read public resource
|
||||
// or for use with Shared Access Signatures (SAS).
|
||||
func NewAnonymousCredential() Credential {
|
||||
return anonymousCredentialFactory
|
||||
}
|
||||
|
||||
var anonymousCredentialFactory Credential = &anonymousCredentialPolicyFactory{} // Singleton
|
||||
|
||||
// anonymousCredentialPolicyFactory is the credential's policy factory.
|
||||
type anonymousCredentialPolicyFactory struct {
|
||||
}
|
||||
|
||||
// New creates a credential policy object.
|
||||
func (f *anonymousCredentialPolicyFactory) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
return &anonymousCredentialPolicy{next: next}
|
||||
}
|
||||
|
||||
// credentialMarker is a package-internal method that exists just to satisfy the Credential interface.
|
||||
func (*anonymousCredentialPolicyFactory) credentialMarker() {}
|
||||
|
||||
// anonymousCredentialPolicy is the credential's policy object.
|
||||
type anonymousCredentialPolicy struct {
|
||||
next pipeline.Policy
|
||||
}
|
||||
|
||||
// Do implements the credential's policy interface.
|
||||
func (p anonymousCredentialPolicy) Do(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
|
||||
// For anonymous credentials, this is effectively a no-op
|
||||
return p.next.Do(ctx, request)
|
||||
}
|
187
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_credential_shared_key.go
generated
vendored
187
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_credential_shared_key.go
generated
vendored
|
@ -1,187 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// NewSharedKeyCredential creates an immutable SharedKeyCredential containing the
|
||||
// storage account's name and either its primary or secondary key.
|
||||
func NewSharedKeyCredential(accountName, accountKey string) *SharedKeyCredential {
|
||||
bytes, err := base64.StdEncoding.DecodeString(accountKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &SharedKeyCredential{accountName: accountName, accountKey: bytes}
|
||||
}
|
||||
|
||||
// SharedKeyCredential contains an account's name and its primary or secondary key.
|
||||
// It is immutable making it shareable and goroutine-safe.
|
||||
type SharedKeyCredential struct {
|
||||
// Only the NewSharedKeyCredential method should set these; all other methods should treat them as read-only
|
||||
accountName string
|
||||
accountKey []byte
|
||||
}
|
||||
|
||||
// AccountName returns the Storage account's name.
|
||||
func (f SharedKeyCredential) AccountName() string {
|
||||
return f.accountName
|
||||
}
|
||||
|
||||
// New creates a credential policy object.
|
||||
func (f *SharedKeyCredential) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
return pipeline.PolicyFunc(func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
|
||||
// Add a x-ms-date header if it doesn't already exist
|
||||
if d := request.Header.Get(headerXmsDate); d == "" {
|
||||
request.Header[headerXmsDate] = []string{time.Now().UTC().Format(http.TimeFormat)}
|
||||
}
|
||||
stringToSign := f.buildStringToSign(request)
|
||||
signature := f.ComputeHMACSHA256(stringToSign)
|
||||
authHeader := strings.Join([]string{"SharedKey ", f.accountName, ":", signature}, "")
|
||||
request.Header[headerAuthorization] = []string{authHeader}
|
||||
|
||||
response, err := next.Do(ctx, request)
|
||||
if err != nil && response != nil && response.Response() != nil && response.Response().StatusCode == http.StatusForbidden {
|
||||
// Service failed to authenticate request, log it
|
||||
po.Log(pipeline.LogError, "===== HTTP Forbidden status, String-to-Sign:\n"+stringToSign+"\n===============================\n")
|
||||
}
|
||||
return response, err
|
||||
})
|
||||
}
|
||||
|
||||
// credentialMarker is a package-internal method that exists just to satisfy the Credential interface.
|
||||
func (*SharedKeyCredential) credentialMarker() {}
|
||||
|
||||
// Constants ensuring that header names are correctly spelled and consistently cased.
|
||||
const (
|
||||
headerAuthorization = "Authorization"
|
||||
headerCacheControl = "Cache-Control"
|
||||
headerContentEncoding = "Content-Encoding"
|
||||
headerContentDisposition = "Content-Disposition"
|
||||
headerContentLanguage = "Content-Language"
|
||||
headerContentLength = "Content-Length"
|
||||
headerContentMD5 = "Content-MD5"
|
||||
headerContentType = "Content-Type"
|
||||
headerDate = "Date"
|
||||
headerIfMatch = "If-Match"
|
||||
headerIfModifiedSince = "If-Modified-Since"
|
||||
headerIfNoneMatch = "If-None-Match"
|
||||
headerIfUnmodifiedSince = "If-Unmodified-Since"
|
||||
headerRange = "Range"
|
||||
headerUserAgent = "User-Agent"
|
||||
headerXmsDate = "x-ms-date"
|
||||
headerXmsVersion = "x-ms-version"
|
||||
)
|
||||
|
||||
// ComputeHMACSHA256 generates a hash signature for an HTTP request or for a SAS.
|
||||
func (f *SharedKeyCredential) ComputeHMACSHA256(message string) (base64String string) {
|
||||
h := hmac.New(sha256.New, f.accountKey)
|
||||
h.Write([]byte(message))
|
||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
func (f *SharedKeyCredential) buildStringToSign(request pipeline.Request) string {
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services
|
||||
headers := request.Header
|
||||
contentLength := headers.Get(headerContentLength)
|
||||
if contentLength == "0" {
|
||||
contentLength = ""
|
||||
}
|
||||
|
||||
stringToSign := strings.Join([]string{
|
||||
request.Method,
|
||||
headers.Get(headerContentEncoding),
|
||||
headers.Get(headerContentLanguage),
|
||||
contentLength,
|
||||
headers.Get(headerContentMD5),
|
||||
headers.Get(headerContentType),
|
||||
"", // Empty date because x-ms-date is expected (as per web page above)
|
||||
headers.Get(headerIfModifiedSince),
|
||||
headers.Get(headerIfMatch),
|
||||
headers.Get(headerIfNoneMatch),
|
||||
headers.Get(headerIfUnmodifiedSince),
|
||||
headers.Get(headerRange),
|
||||
buildCanonicalizedHeader(headers),
|
||||
f.buildCanonicalizedResource(request.URL),
|
||||
}, "\n")
|
||||
return stringToSign
|
||||
}
|
||||
|
||||
func buildCanonicalizedHeader(headers http.Header) string {
|
||||
cm := map[string][]string{}
|
||||
for k, v := range headers {
|
||||
headerName := strings.TrimSpace(strings.ToLower(k))
|
||||
if strings.HasPrefix(headerName, "x-ms-") {
|
||||
cm[headerName] = v // NOTE: the value must not have any whitespace around it.
|
||||
}
|
||||
}
|
||||
if len(cm) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(cm))
|
||||
for key := range cm {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
ch := bytes.NewBufferString("")
|
||||
for i, key := range keys {
|
||||
if i > 0 {
|
||||
ch.WriteRune('\n')
|
||||
}
|
||||
ch.WriteString(key)
|
||||
ch.WriteRune(':')
|
||||
ch.WriteString(strings.Join(cm[key], ","))
|
||||
}
|
||||
return string(ch.Bytes())
|
||||
}
|
||||
|
||||
func (f *SharedKeyCredential) buildCanonicalizedResource(u *url.URL) string {
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services
|
||||
cr := bytes.NewBufferString("/")
|
||||
cr.WriteString(f.accountName)
|
||||
|
||||
if len(u.Path) > 0 {
|
||||
// Any portion of the CanonicalizedResource string that is derived from
|
||||
// the resource's URI should be encoded exactly as it is in the URI.
|
||||
// -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx
|
||||
cr.WriteString(u.EscapedPath())
|
||||
} else {
|
||||
// a slash is required to indicate the root path
|
||||
cr.WriteString("/")
|
||||
}
|
||||
|
||||
// params is a map[string][]string; param name is key; params values is []string
|
||||
params, err := url.ParseQuery(u.RawQuery) // Returns URL decoded values
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if len(params) > 0 { // There is at least 1 query parameter
|
||||
paramNames := []string{} // We use this to sort the parameter key names
|
||||
for paramName := range params {
|
||||
paramNames = append(paramNames, paramName) // paramNames must be lowercase
|
||||
}
|
||||
sort.Strings(paramNames)
|
||||
|
||||
for _, paramName := range paramNames {
|
||||
paramValues := params[paramName]
|
||||
sort.Strings(paramValues)
|
||||
|
||||
// Join the sorted key values separated by ','
|
||||
// Then prepend "keyName:"; then add this string to the buffer
|
||||
cr.WriteString("\n" + paramName + ":" + strings.Join(paramValues, ","))
|
||||
}
|
||||
}
|
||||
return string(cr.Bytes())
|
||||
}
|
125
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_credential_token.go
generated
vendored
125
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_credential_token.go
generated
vendored
|
@ -1,125 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TokenCredential represents a token credential (which is also a pipeline.Factory).
|
||||
type TokenCredential interface {
|
||||
Credential
|
||||
Token() string
|
||||
SetToken(newToken string)
|
||||
}
|
||||
|
||||
// NewTokenCredential creates a token credential for use with role-based access control (RBAC) access to Azure Storage
|
||||
// resources. You initialize the TokenCredential with an initial token value. If you pass a non-nil value for
|
||||
// tokenRefresher, then the function you pass will be called immediately (so it can refresh and change the
|
||||
// TokenCredential's token value by calling SetToken; your tokenRefresher function must return a time.Duration
|
||||
// indicating how long the TokenCredential object should wait before calling your tokenRefresher function again.
|
||||
func NewTokenCredential(initialToken string, tokenRefresher func(credential TokenCredential) time.Duration) TokenCredential {
|
||||
tc := &tokenCredential{}
|
||||
tc.SetToken(initialToken) // We dont' set it above to guarantee atomicity
|
||||
if tokenRefresher == nil {
|
||||
return tc // If no callback specified, return the simple tokenCredential
|
||||
}
|
||||
|
||||
tcwr := &tokenCredentialWithRefresh{token: tc}
|
||||
tcwr.token.startRefresh(tokenRefresher)
|
||||
runtime.SetFinalizer(tcwr, func(deadTC tokenCredentialWithRefresh) {
|
||||
deadTC.token.stopRefresh()
|
||||
deadTC.token = nil // Sanity (not really required)
|
||||
})
|
||||
return tcwr
|
||||
}
|
||||
|
||||
// tokenCredentialWithRefresh is a wrapper over a token credential.
|
||||
// When this wrapper object gets GC'd, it stops the tokenCredential's timer
|
||||
// which allows the tokenCredential object to also be GC'd.
|
||||
type tokenCredentialWithRefresh struct {
|
||||
token *tokenCredential
|
||||
}
|
||||
|
||||
// credentialMarker is a package-internal method that exists just to satisfy the Credential interface.
|
||||
func (*tokenCredentialWithRefresh) credentialMarker() {}
|
||||
|
||||
// Token returns the current token value
|
||||
func (f *tokenCredentialWithRefresh) Token() string { return f.token.Token() }
|
||||
|
||||
// SetToken changes the current token value
|
||||
func (f *tokenCredentialWithRefresh) SetToken(token string) { f.token.SetToken(token) }
|
||||
|
||||
// New satisfies pipeline.Factory's New method creating a pipeline policy object.
|
||||
func (f *tokenCredentialWithRefresh) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
return f.token.New(next, po)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// tokenCredential is a pipeline.Factory is the credential's policy factory.
|
||||
type tokenCredential struct {
|
||||
token atomic.Value
|
||||
|
||||
// The members below are only used if the user specified a tokenRefresher callback function.
|
||||
timer *time.Timer
|
||||
tokenRefresher func(c TokenCredential) time.Duration
|
||||
lock sync.Mutex
|
||||
stopped bool
|
||||
}
|
||||
|
||||
// credentialMarker is a package-internal method that exists just to satisfy the Credential interface.
|
||||
func (*tokenCredential) credentialMarker() {}
|
||||
|
||||
// Token returns the current token value
|
||||
func (f *tokenCredential) Token() string { return f.token.Load().(string) }
|
||||
|
||||
// SetToken changes the current token value
|
||||
func (f *tokenCredential) SetToken(token string) { f.token.Store(token) }
|
||||
|
||||
// startRefresh calls refresh which immediately calls tokenRefresher
|
||||
// and then starts a timer to call tokenRefresher in the future.
|
||||
func (f *tokenCredential) startRefresh(tokenRefresher func(c TokenCredential) time.Duration) {
|
||||
f.tokenRefresher = tokenRefresher
|
||||
f.stopped = false // In case user calls StartRefresh, StopRefresh, & then StartRefresh again
|
||||
f.refresh()
|
||||
}
|
||||
|
||||
// refresh calls the user's tokenRefresher so they can refresh the token (by
|
||||
// calling SetToken) and then starts another time (based on the returned duration)
|
||||
// in order to refresh the token again in the future.
|
||||
func (f *tokenCredential) refresh() {
|
||||
d := f.tokenRefresher(f) // Invoke the user's refresh callback outside of the lock
|
||||
f.lock.Lock()
|
||||
if !f.stopped {
|
||||
f.timer = time.AfterFunc(d, f.refresh)
|
||||
}
|
||||
f.lock.Unlock()
|
||||
}
|
||||
|
||||
// stopRefresh stops any pending timer and sets stopped field to true to prevent
|
||||
// any new timer from starting.
|
||||
// NOTE: Stopping the timer allows the GC to destroy the tokenCredential object.
|
||||
func (f *tokenCredential) stopRefresh() {
|
||||
f.lock.Lock()
|
||||
f.stopped = true
|
||||
if f.timer != nil {
|
||||
f.timer.Stop()
|
||||
}
|
||||
f.lock.Unlock()
|
||||
}
|
||||
|
||||
// New satisfies pipeline.Factory's New method creating a pipeline policy object.
|
||||
func (f *tokenCredential) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
return pipeline.PolicyFunc(func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
|
||||
if request.URL.Scheme != "https" {
|
||||
panic("Token credentials require a URL using the https protocol scheme.")
|
||||
}
|
||||
request.Header[headerAuthorization] = []string{"Bearer " + f.Token()}
|
||||
return next.Do(ctx, request)
|
||||
})
|
||||
}
|
27
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_mmf_unix.go
generated
vendored
27
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_mmf_unix.go
generated
vendored
|
@ -1,27 +0,0 @@
|
|||
// +build linux darwin freebsd
|
||||
|
||||
package azblob
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type mmf []byte
|
||||
|
||||
func newMMF(file *os.File, writable bool, offset int64, length int) (mmf, error) {
|
||||
prot, flags := syscall.PROT_READ, syscall.MAP_SHARED // Assume read-only
|
||||
if writable {
|
||||
prot, flags = syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED
|
||||
}
|
||||
addr, err := syscall.Mmap(int(file.Fd()), offset, length, prot, flags)
|
||||
return mmf(addr), err
|
||||
}
|
||||
|
||||
func (m *mmf) unmap() {
|
||||
err := syscall.Munmap(*m)
|
||||
*m = nil
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
38
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_mmf_windows.go
generated
vendored
38
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_mmf_windows.go
generated
vendored
|
@ -1,38 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type mmf []byte
|
||||
|
||||
func newMMF(file *os.File, writable bool, offset int64, length int) (mmf, error) {
|
||||
prot, access := uint32(syscall.PAGE_READONLY), uint32(syscall.FILE_MAP_READ) // Assume read-only
|
||||
if writable {
|
||||
prot, access = uint32(syscall.PAGE_READWRITE), uint32(syscall.FILE_MAP_WRITE)
|
||||
}
|
||||
hMMF, errno := syscall.CreateFileMapping(syscall.Handle(file.Fd()), nil, prot, uint32(int64(length)>>32), uint32(int64(length)&0xffffffff), nil)
|
||||
if hMMF == 0 {
|
||||
return nil, os.NewSyscallError("CreateFileMapping", errno)
|
||||
}
|
||||
defer syscall.CloseHandle(hMMF)
|
||||
addr, errno := syscall.MapViewOfFile(hMMF, access, uint32(offset>>32), uint32(offset&0xffffffff), uintptr(length))
|
||||
m := mmf{}
|
||||
h := (*reflect.SliceHeader)(unsafe.Pointer(&m))
|
||||
h.Data = addr
|
||||
h.Len = length
|
||||
h.Cap = h.Len
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m *mmf) unmap() {
|
||||
addr := uintptr(unsafe.Pointer(&(([]byte)(*m)[0])))
|
||||
*m = mmf{}
|
||||
err := syscall.UnmapViewOfFile(addr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
46
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_pipeline.go
generated
vendored
46
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_pipeline.go
generated
vendored
|
@ -1,46 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// PipelineOptions is used to configure a request policy pipeline's retry policy and logging.
|
||||
type PipelineOptions struct {
|
||||
// Log configures the pipeline's logging infrastructure indicating what information is logged and where.
|
||||
Log pipeline.LogOptions
|
||||
|
||||
// Retry configures the built-in retry policy behavior.
|
||||
Retry RetryOptions
|
||||
|
||||
// RequestLog configures the built-in request logging policy.
|
||||
RequestLog RequestLogOptions
|
||||
|
||||
// Telemetry configures the built-in telemetry policy behavior.
|
||||
Telemetry TelemetryOptions
|
||||
}
|
||||
|
||||
// NewPipeline creates a Pipeline using the specified credentials and options.
|
||||
func NewPipeline(c Credential, o PipelineOptions) pipeline.Pipeline {
|
||||
if c == nil {
|
||||
panic("c can't be nil")
|
||||
}
|
||||
|
||||
// Closest to API goes first; closest to the wire goes last
|
||||
f := []pipeline.Factory{
|
||||
NewTelemetryPolicyFactory(o.Telemetry),
|
||||
NewUniqueRequestIDPolicyFactory(),
|
||||
NewRetryPolicyFactory(o.Retry),
|
||||
}
|
||||
|
||||
if _, ok := c.(*anonymousCredentialPolicyFactory); !ok {
|
||||
// For AnonymousCredential, we optimize out the policy factory since it doesn't do anything
|
||||
// NOTE: The credential's policy factory must appear close to the wire so it can sign any
|
||||
// changes made by other factories (like UniqueRequestIDPolicyFactory)
|
||||
f = append(f, c)
|
||||
}
|
||||
f = append(f,
|
||||
pipeline.MethodFactoryMarker(), // indicates at what stage in the pipeline the method factory is invoked
|
||||
NewRequestLogPolicyFactory(o.RequestLog))
|
||||
|
||||
return pipeline.NewPipeline(f, pipeline.Options{HTTPSender: nil, Log: o.Log})
|
||||
}
|
150
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_policy_request_log.go
generated
vendored
150
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_policy_request_log.go
generated
vendored
|
@ -1,150 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// RequestLogOptions configures the retry policy's behavior.
|
||||
type RequestLogOptions struct {
|
||||
// LogWarningIfTryOverThreshold logs a warning if a tried operation takes longer than the specified
|
||||
// duration (-1=no logging; 0=default threshold).
|
||||
LogWarningIfTryOverThreshold time.Duration
|
||||
}
|
||||
|
||||
func (o RequestLogOptions) defaults() RequestLogOptions {
|
||||
if o.LogWarningIfTryOverThreshold == 0 {
|
||||
// It would be good to relate this to https://azure.microsoft.com/en-us/support/legal/sla/storage/v1_2/
|
||||
// But this monitors the time to get the HTTP response; NOT the time to download the response body.
|
||||
o.LogWarningIfTryOverThreshold = 3 * time.Second // Default to 3 seconds
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// NewRequestLogPolicyFactory creates a RequestLogPolicyFactory object configured using the specified options.
|
||||
func NewRequestLogPolicyFactory(o RequestLogOptions) pipeline.Factory {
|
||||
o = o.defaults() // Force defaults to be calculated
|
||||
return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc {
|
||||
// These variables are per-policy; shared by multiple calls to Do
|
||||
var try int32
|
||||
operationStart := time.Now() // If this is the 1st try, record the operation state time
|
||||
return func(ctx context.Context, request pipeline.Request) (response pipeline.Response, err error) {
|
||||
try++ // The first try is #1 (not #0)
|
||||
|
||||
// Log the outgoing request as informational
|
||||
if po.ShouldLog(pipeline.LogInfo) {
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "==> OUTGOING REQUEST (Try=%d)\n", try)
|
||||
pipeline.WriteRequestWithResponse(b, prepareRequestForLogging(request), nil, nil)
|
||||
po.Log(pipeline.LogInfo, b.String())
|
||||
}
|
||||
|
||||
// Set the time for this particular retry operation and then Do the operation.
|
||||
tryStart := time.Now()
|
||||
response, err = next.Do(ctx, request) // Make the request
|
||||
tryEnd := time.Now()
|
||||
tryDuration := tryEnd.Sub(tryStart)
|
||||
opDuration := tryEnd.Sub(operationStart)
|
||||
|
||||
logLevel, forceLog := pipeline.LogInfo, false // Default logging information
|
||||
|
||||
// If the response took too long, we'll upgrade to warning.
|
||||
if o.LogWarningIfTryOverThreshold > 0 && tryDuration > o.LogWarningIfTryOverThreshold {
|
||||
// Log a warning if the try duration exceeded the specified threshold
|
||||
logLevel, forceLog = pipeline.LogWarning, true
|
||||
}
|
||||
|
||||
if err == nil { // We got a response from the service
|
||||
sc := response.Response().StatusCode
|
||||
if ((sc >= 400 && sc <= 499) && sc != http.StatusNotFound && sc != http.StatusConflict && sc != http.StatusPreconditionFailed && sc != http.StatusRequestedRangeNotSatisfiable) || (sc >= 500 && sc <= 599) {
|
||||
logLevel, forceLog = pipeline.LogError, true // Promote to Error any 4xx (except those listed is an error) or any 5xx
|
||||
} else {
|
||||
// For other status codes, we leave the level as is.
|
||||
}
|
||||
} else { // This error did not get an HTTP response from the service; upgrade the severity to Error
|
||||
logLevel, forceLog = pipeline.LogError, true
|
||||
}
|
||||
|
||||
if shouldLog := po.ShouldLog(logLevel); forceLog || shouldLog {
|
||||
// We're going to log this; build the string to log
|
||||
b := &bytes.Buffer{}
|
||||
slow := ""
|
||||
if o.LogWarningIfTryOverThreshold > 0 && tryDuration > o.LogWarningIfTryOverThreshold {
|
||||
slow = fmt.Sprintf("[SLOW >%v]", o.LogWarningIfTryOverThreshold)
|
||||
}
|
||||
fmt.Fprintf(b, "==> REQUEST/RESPONSE (Try=%d/%v%s, OpTime=%v) -- ", try, tryDuration, slow, opDuration)
|
||||
if err != nil { // This HTTP request did not get a response from the service
|
||||
fmt.Fprint(b, "REQUEST ERROR\n")
|
||||
} else {
|
||||
if logLevel == pipeline.LogError {
|
||||
fmt.Fprint(b, "RESPONSE STATUS CODE ERROR\n")
|
||||
} else {
|
||||
fmt.Fprint(b, "RESPONSE SUCCESSFULLY RECEIVED\n")
|
||||
}
|
||||
}
|
||||
|
||||
pipeline.WriteRequestWithResponse(b, prepareRequestForLogging(request), response.Response(), err)
|
||||
if logLevel <= pipeline.LogError {
|
||||
b.Write(stack()) // For errors (or lower levels), we append the stack trace (an expensive operation)
|
||||
}
|
||||
msg := b.String()
|
||||
|
||||
if forceLog {
|
||||
pipeline.ForceLog(logLevel, msg)
|
||||
}
|
||||
if shouldLog {
|
||||
po.Log(logLevel, msg)
|
||||
}
|
||||
}
|
||||
return response, err
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func redactSigQueryParam(rawQuery string) (bool, string) {
|
||||
rawQuery = strings.ToLower(rawQuery) // lowercase the string so we can look for ?sig= and &sig=
|
||||
sigFound := strings.Contains(rawQuery, "?sig=")
|
||||
if !sigFound {
|
||||
sigFound = strings.Contains(rawQuery, "&sig=")
|
||||
if !sigFound {
|
||||
return sigFound, rawQuery // [?|&]sig= not found; return same rawQuery passed in (no memory allocation)
|
||||
}
|
||||
}
|
||||
// [?|&]sig= found, redact its value
|
||||
values, _ := url.ParseQuery(rawQuery)
|
||||
for name := range values {
|
||||
if strings.EqualFold(name, "sig") {
|
||||
values[name] = []string{"REDACTED"}
|
||||
}
|
||||
}
|
||||
return sigFound, values.Encode()
|
||||
}
|
||||
|
||||
func prepareRequestForLogging(request pipeline.Request) *http.Request {
|
||||
req := request
|
||||
if sigFound, rawQuery := redactSigQueryParam(req.URL.RawQuery); sigFound {
|
||||
// Make copy so we don't destroy the query parameters we actually need to send in the request
|
||||
req = request.Copy()
|
||||
req.Request.URL.RawQuery = rawQuery
|
||||
}
|
||||
return req.Request
|
||||
}
|
||||
|
||||
func stack() []byte {
|
||||
buf := make([]byte, 1024)
|
||||
for {
|
||||
n := runtime.Stack(buf, false)
|
||||
if n < len(buf) {
|
||||
return buf[:n]
|
||||
}
|
||||
buf = make([]byte, 2*len(buf))
|
||||
}
|
||||
}
|
318
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_policy_retry.go
generated
vendored
318
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_policy_retry.go
generated
vendored
|
@ -1,318 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
)
|
||||
|
||||
// RetryPolicy tells the pipeline what kind of retry policy to use. See the RetryPolicy* constants.
|
||||
type RetryPolicy int32
|
||||
|
||||
const (
|
||||
// RetryPolicyExponential tells the pipeline to use an exponential back-off retry policy
|
||||
RetryPolicyExponential RetryPolicy = 0
|
||||
|
||||
// RetryPolicyFixed tells the pipeline to use a fixed back-off retry policy
|
||||
RetryPolicyFixed RetryPolicy = 1
|
||||
)
|
||||
|
||||
// RetryOptions configures the retry policy's behavior.
|
||||
type RetryOptions struct {
|
||||
// Policy tells the pipeline what kind of retry policy to use. See the RetryPolicy* constants.\
|
||||
// A value of zero means that you accept our default policy.
|
||||
Policy RetryPolicy
|
||||
|
||||
// MaxTries specifies the maximum number of attempts an operation will be tried before producing an error (0=default).
|
||||
// A value of zero means that you accept our default policy. A value of 1 means 1 try and no retries.
|
||||
MaxTries int32
|
||||
|
||||
// TryTimeout indicates the maximum time allowed for any single try of an HTTP request.
|
||||
// A value of zero means that you accept our default timeout. NOTE: When transferring large amounts
|
||||
// of data, the default TryTimeout will probably not be sufficient. You should override this value
|
||||
// based on the bandwidth available to the host machine and proximity to the Storage service. A good
|
||||
// starting point may be something like (60 seconds per MB of anticipated-payload-size).
|
||||
TryTimeout time.Duration
|
||||
|
||||
// RetryDelay specifies the amount of delay to use before retrying an operation (0=default).
|
||||
// When RetryPolicy is specified as RetryPolicyExponential, the delay increases exponentially
|
||||
// with each retry up to a maximum specified by MaxRetryDelay.
|
||||
// If you specify 0, then you must also specify 0 for MaxRetryDelay.
|
||||
// If you specify RetryDelay, then you must also specify MaxRetryDelay, and MaxRetryDelay should be
|
||||
// equal to or greater than RetryDelay.
|
||||
RetryDelay time.Duration
|
||||
|
||||
// MaxRetryDelay specifies the maximum delay allowed before retrying an operation (0=default).
|
||||
// If you specify 0, then you must also specify 0 for RetryDelay.
|
||||
MaxRetryDelay time.Duration
|
||||
|
||||
// RetryReadsFromSecondaryHost specifies whether the retry policy should retry a read operation against another host.
|
||||
// If RetryReadsFromSecondaryHost is "" (the default) then operations are not retried against another host.
|
||||
// NOTE: Before setting this field, make sure you understand the issues around reading stale & potentially-inconsistent
|
||||
// data at this webpage: https://docs.microsoft.com/en-us/azure/storage/common/storage-designing-ha-apps-with-ragrs
|
||||
RetryReadsFromSecondaryHost string // Comment this our for non-Blob SDKs
|
||||
}
|
||||
|
||||
func (o RetryOptions) retryReadsFromSecondaryHost() string {
|
||||
return o.RetryReadsFromSecondaryHost // This is for the Blob SDK only
|
||||
//return "" // This is for non-blob SDKs
|
||||
}
|
||||
|
||||
func (o RetryOptions) defaults() RetryOptions {
|
||||
if o.Policy != RetryPolicyExponential && o.Policy != RetryPolicyFixed {
|
||||
panic("RetryPolicy must be RetryPolicyExponential or RetryPolicyFixed")
|
||||
}
|
||||
if o.MaxTries < 0 {
|
||||
panic("MaxTries must be >= 0")
|
||||
}
|
||||
if o.TryTimeout < 0 || o.RetryDelay < 0 || o.MaxRetryDelay < 0 {
|
||||
panic("TryTimeout, RetryDelay, and MaxRetryDelay must all be >= 0")
|
||||
}
|
||||
if o.RetryDelay > o.MaxRetryDelay {
|
||||
panic("RetryDelay must be <= MaxRetryDelay")
|
||||
}
|
||||
if (o.RetryDelay == 0 && o.MaxRetryDelay != 0) || (o.RetryDelay != 0 && o.MaxRetryDelay == 0) {
|
||||
panic("Both RetryDelay and MaxRetryDelay must be 0 or neither can be 0")
|
||||
}
|
||||
|
||||
IfDefault := func(current *time.Duration, desired time.Duration) {
|
||||
if *current == time.Duration(0) {
|
||||
*current = desired
|
||||
}
|
||||
}
|
||||
|
||||
// Set defaults if unspecified
|
||||
if o.MaxTries == 0 {
|
||||
o.MaxTries = 4
|
||||
}
|
||||
switch o.Policy {
|
||||
case RetryPolicyExponential:
|
||||
IfDefault(&o.TryTimeout, 1*time.Minute)
|
||||
IfDefault(&o.RetryDelay, 4*time.Second)
|
||||
IfDefault(&o.MaxRetryDelay, 120*time.Second)
|
||||
|
||||
case RetryPolicyFixed:
|
||||
IfDefault(&o.TryTimeout, 1*time.Minute)
|
||||
IfDefault(&o.RetryDelay, 30*time.Second)
|
||||
IfDefault(&o.MaxRetryDelay, 120*time.Second)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o RetryOptions) calcDelay(try int32) time.Duration { // try is >=1; never 0
|
||||
pow := func(number int64, exponent int32) int64 { // pow is nested helper function
|
||||
var result int64 = 1
|
||||
for n := int32(0); n < exponent; n++ {
|
||||
result *= number
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
delay := time.Duration(0)
|
||||
switch o.Policy {
|
||||
case RetryPolicyExponential:
|
||||
delay = time.Duration(pow(2, try-1)-1) * o.RetryDelay
|
||||
|
||||
case RetryPolicyFixed:
|
||||
if try > 1 { // Any try after the 1st uses the fixed delay
|
||||
delay = o.RetryDelay
|
||||
}
|
||||
}
|
||||
|
||||
// Introduce some jitter: [0.0, 1.0) / 2 = [0.0, 0.5) + 0.8 = [0.8, 1.3)
|
||||
delay = time.Duration(delay.Seconds() * (rand.Float64()/2 + 0.8) * float64(time.Second)) // NOTE: We want math/rand; not crypto/rand
|
||||
if delay > o.MaxRetryDelay {
|
||||
delay = o.MaxRetryDelay
|
||||
}
|
||||
return delay
|
||||
}
|
||||
|
||||
// NewRetryPolicyFactory creates a RetryPolicyFactory object configured using the specified options.
|
||||
func NewRetryPolicyFactory(o RetryOptions) pipeline.Factory {
|
||||
o = o.defaults() // Force defaults to be calculated
|
||||
return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc {
|
||||
return func(ctx context.Context, request pipeline.Request) (response pipeline.Response, err error) {
|
||||
// Before each try, we'll select either the primary or secondary URL.
|
||||
primaryTry := int32(0) // This indicates how many tries we've attempted against the primary DC
|
||||
|
||||
// We only consider retrying against a secondary if we have a read request (GET/HEAD) AND this policy has a Secondary URL it can use
|
||||
considerSecondary := (request.Method == http.MethodGet || request.Method == http.MethodHead) && o.retryReadsFromSecondaryHost() != ""
|
||||
|
||||
// Exponential retry algorithm: ((2 ^ attempt) - 1) * delay * random(0.8, 1.2)
|
||||
// When to retry: connection failure or temporary/timeout. NOTE: StorageError considers HTTP 500/503 as temporary & is therefore retryable
|
||||
// If using a secondary:
|
||||
// Even tries go against primary; odd tries go against the secondary
|
||||
// For a primary wait ((2 ^ primaryTries - 1) * delay * random(0.8, 1.2)
|
||||
// If secondary gets a 404, don't fail, retry but future retries are only against the primary
|
||||
// When retrying against a secondary, ignore the retry count and wait (.1 second * random(0.8, 1.2))
|
||||
for try := int32(1); try <= o.MaxTries; try++ {
|
||||
logf("\n=====> Try=%d\n", try)
|
||||
|
||||
// Determine which endpoint to try. It's primary if there is no secondary or if it is an add # attempt.
|
||||
tryingPrimary := !considerSecondary || (try%2 == 1)
|
||||
// Select the correct host and delay
|
||||
if tryingPrimary {
|
||||
primaryTry++
|
||||
delay := o.calcDelay(primaryTry)
|
||||
logf("Primary try=%d, Delay=%v\n", primaryTry, delay)
|
||||
time.Sleep(delay) // The 1st try returns 0 delay
|
||||
} else {
|
||||
delay := time.Second * time.Duration(rand.Float32()/2+0.8)
|
||||
logf("Secondary try=%d, Delay=%v\n", try-primaryTry, delay)
|
||||
time.Sleep(delay) // Delay with some jitter before trying secondary
|
||||
}
|
||||
|
||||
// Clone the original request to ensure that each try starts with the original (unmutated) request.
|
||||
requestCopy := request.Copy()
|
||||
|
||||
// For each try, seek to the beginning of the Body stream. We do this even for the 1st try because
|
||||
// the stream may not be at offset 0 when we first get it and we want the same behavior for the
|
||||
// 1st try as for additional tries.
|
||||
if err = requestCopy.RewindBody(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !tryingPrimary {
|
||||
requestCopy.Request.URL.Host = o.retryReadsFromSecondaryHost()
|
||||
}
|
||||
|
||||
// Set the server-side timeout query parameter "timeout=[seconds]"
|
||||
timeout := int32(o.TryTimeout.Seconds()) // Max seconds per try
|
||||
if deadline, ok := ctx.Deadline(); ok { // If user's ctx has a deadline, make the timeout the smaller of the two
|
||||
t := int32(deadline.Sub(time.Now()).Seconds()) // Duration from now until user's ctx reaches its deadline
|
||||
logf("MaxTryTimeout=%d secs, TimeTilDeadline=%d sec\n", timeout, t)
|
||||
if t < timeout {
|
||||
timeout = t
|
||||
}
|
||||
if timeout < 0 {
|
||||
timeout = 0 // If timeout ever goes negative, set it to zero; this happen while debugging
|
||||
}
|
||||
logf("TryTimeout adjusted to=%d sec\n", timeout)
|
||||
}
|
||||
q := requestCopy.Request.URL.Query()
|
||||
q.Set("timeout", strconv.Itoa(int(timeout+1))) // Add 1 to "round up"
|
||||
requestCopy.Request.URL.RawQuery = q.Encode()
|
||||
logf("Url=%s\n", requestCopy.Request.URL.String())
|
||||
|
||||
// Set the time for this particular retry operation and then Do the operation.
|
||||
tryCtx, tryCancel := context.WithTimeout(ctx, time.Second*time.Duration(timeout))
|
||||
//requestCopy.Body = &deadlineExceededReadCloser{r: requestCopy.Request.Body}
|
||||
response, err = next.Do(tryCtx, requestCopy) // Make the request
|
||||
/*err = improveDeadlineExceeded(err)
|
||||
if err == nil {
|
||||
response.Response().Body = &deadlineExceededReadCloser{r: response.Response().Body}
|
||||
}*/
|
||||
logf("Err=%v, response=%v\n", err, response)
|
||||
|
||||
action := "" // This MUST get changed within the switch code below
|
||||
switch {
|
||||
case ctx.Err() != nil:
|
||||
action = "NoRetry: Op timeout"
|
||||
case !tryingPrimary && response != nil && response.Response().StatusCode == http.StatusNotFound:
|
||||
// If attempt was against the secondary & it returned a StatusNotFound (404), then
|
||||
// the resource was not found. This may be due to replication delay. So, in this
|
||||
// case, we'll never try the secondary again for this operation.
|
||||
considerSecondary = false
|
||||
action = "Retry: Secondary URL returned 404"
|
||||
case err != nil:
|
||||
// NOTE: Protocol Responder returns non-nil if REST API returns invalid status code for the invoked operation
|
||||
if netErr, ok := err.(net.Error); ok && (netErr.Temporary() || netErr.Timeout()) {
|
||||
action = "Retry: net.Error and Temporary() or Timeout()"
|
||||
} else {
|
||||
action = "NoRetry: unrecognized error"
|
||||
}
|
||||
default:
|
||||
action = "NoRetry: successful HTTP request" // no error
|
||||
}
|
||||
|
||||
logf("Action=%s\n", action)
|
||||
// fmt.Println(action + "\n") // This is where we could log the retry operation; action is why we're retrying
|
||||
if action[0] != 'R' { // Retry only if action starts with 'R'
|
||||
if err != nil {
|
||||
tryCancel() // If we're returning an error, cancel this current/last per-retry timeout context
|
||||
} else {
|
||||
// TODO: Right now, we've decided to leak the per-try Context until the user's Context is canceled.
|
||||
// Another option is that we wrap the last per-try context in a body and overwrite the Response's Body field with our wrapper.
|
||||
// So, when the user closes the Body, the our per-try context gets closed too.
|
||||
// Another option, is that the Last Policy do this wrapping for a per-retry context (not for the user's context)
|
||||
_ = tryCancel // So, for now, we don't call cancel: cancel()
|
||||
}
|
||||
break // Don't retry
|
||||
}
|
||||
if response != nil && response.Response() != nil && response.Response().Body != nil {
|
||||
// If we're going to retry and we got a previous response, then flush its body to avoid leaking its TCP connection
|
||||
body := response.Response().Body
|
||||
io.Copy(ioutil.Discard, body)
|
||||
body.Close()
|
||||
}
|
||||
// If retrying, cancel the current per-try timeout context
|
||||
tryCancel()
|
||||
}
|
||||
return response, err // Not retryable or too many retries; return the last response/error
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// According to https://github.com/golang/go/wiki/CompilerOptimizations, the compiler will inline this method and hopefully optimize all calls to it away
|
||||
var logf = func(format string, a ...interface{}) {}
|
||||
|
||||
// Use this version to see the retry method's code path (import "fmt")
|
||||
//var logf = fmt.Printf
|
||||
|
||||
/*
|
||||
type deadlineExceededReadCloser struct {
|
||||
r io.ReadCloser
|
||||
}
|
||||
|
||||
func (r *deadlineExceededReadCloser) Read(p []byte) (int, error) {
|
||||
n, err := 0, io.EOF
|
||||
if r.r != nil {
|
||||
n, err = r.r.Read(p)
|
||||
}
|
||||
return n, improveDeadlineExceeded(err)
|
||||
}
|
||||
func (r *deadlineExceededReadCloser) Seek(offset int64, whence int) (int64, error) {
|
||||
// For an HTTP request, the ReadCloser MUST also implement seek
|
||||
// For an HTTP response, Seek MUST not be called (or this will panic)
|
||||
o, err := r.r.(io.Seeker).Seek(offset, whence)
|
||||
return o, improveDeadlineExceeded(err)
|
||||
}
|
||||
func (r *deadlineExceededReadCloser) Close() error {
|
||||
if c, ok := r.r.(io.Closer); ok {
|
||||
c.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// timeoutError is the internal struct that implements our richer timeout error.
|
||||
type deadlineExceeded struct {
|
||||
responseError
|
||||
}
|
||||
|
||||
var _ net.Error = (*deadlineExceeded)(nil) // Ensure deadlineExceeded implements the net.Error interface at compile time
|
||||
|
||||
// improveDeadlineExceeded creates a timeoutError object that implements the error interface IF cause is a context.DeadlineExceeded error.
|
||||
func improveDeadlineExceeded(cause error) error {
|
||||
// If cause is not DeadlineExceeded, return the same error passed in.
|
||||
if cause != context.DeadlineExceeded {
|
||||
return cause
|
||||
}
|
||||
// Else, convert DeadlineExceeded to our timeoutError which gives a richer string message
|
||||
return &deadlineExceeded{
|
||||
responseError: responseError{
|
||||
ErrorNode: pipeline.ErrorNode{}.Initialize(cause, 3),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Error implements the error interface's Error method to return a string representation of the error.
|
||||
func (e *deadlineExceeded) Error() string {
|
||||
return e.ErrorNode.Error("context deadline exceeded; when creating a pipeline, consider increasing RetryOptions' TryTimeout field")
|
||||
}
|
||||
*/
|
51
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_policy_telemetry.go
generated
vendored
51
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_policy_telemetry.go
generated
vendored
|
@ -1,51 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// TelemetryOptions configures the telemetry policy's behavior.
|
||||
type TelemetryOptions struct {
|
||||
// Value is a string prepended to each request's User-Agent and sent to the service.
|
||||
// The service records the user-agent in logs for diagnostics and tracking of client requests.
|
||||
Value string
|
||||
}
|
||||
|
||||
// NewTelemetryPolicyFactory creates a factory that can create telemetry policy objects
|
||||
// which add telemetry information to outgoing HTTP requests.
|
||||
func NewTelemetryPolicyFactory(o TelemetryOptions) pipeline.Factory {
|
||||
b := &bytes.Buffer{}
|
||||
b.WriteString(o.Value)
|
||||
if b.Len() > 0 {
|
||||
b.WriteRune(' ')
|
||||
}
|
||||
fmt.Fprintf(b, "Azure-Storage/%s %s", serviceLibVersion, platformInfo)
|
||||
telemetryValue := b.String()
|
||||
|
||||
return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc {
|
||||
return func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
|
||||
request.Header.Set("User-Agent", telemetryValue)
|
||||
return next.Do(ctx, request)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// NOTE: the ONLY function that should write to this variable is this func
|
||||
var platformInfo = func() string {
|
||||
// Azure-Storage/version (runtime; os type and version)”
|
||||
// Azure-Storage/1.4.0 (NODE-VERSION v4.5.0; Windows_NT 10.0.14393)'
|
||||
operatingSystem := runtime.GOOS // Default OS string
|
||||
switch operatingSystem {
|
||||
case "windows":
|
||||
operatingSystem = os.Getenv("OS") // Get more specific OS information
|
||||
case "linux": // accept default OS info
|
||||
case "freebsd": // accept default OS info
|
||||
}
|
||||
return fmt.Sprintf("(%s; %s)", runtime.Version(), operatingSystem)
|
||||
}()
|
|
@ -1,24 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
// NewUniqueRequestIDPolicyFactory creates a UniqueRequestIDPolicyFactory object
|
||||
// that sets the request's x-ms-client-request-id header if it doesn't already exist.
|
||||
func NewUniqueRequestIDPolicyFactory() pipeline.Factory {
|
||||
return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc {
|
||||
// This is Policy's Do method:
|
||||
return func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
|
||||
id := request.Header.Get(xMsClientRequestID)
|
||||
if id == "" { // Add a unique request ID if the caller didn't specify one already
|
||||
request.Header.Set(xMsClientRequestID, newUUID().String())
|
||||
}
|
||||
return next.Do(ctx, request)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const xMsClientRequestID = "x-ms-client-request-id"
|
122
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_retry_reader.go
generated
vendored
122
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_retry_reader.go
generated
vendored
|
@ -1,122 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const CountToEnd = 0
|
||||
|
||||
// HTTPGetter is a function type that refers to a method that performs an HTTP GET operation.
|
||||
type HTTPGetter func(ctx context.Context, i HTTPGetterInfo) (*http.Response, error)
|
||||
|
||||
// HTTPGetterInfo is passed to an HTTPGetter function passing it parameters
|
||||
// that should be used to make an HTTP GET request.
|
||||
type HTTPGetterInfo struct {
|
||||
// Offset specifies the start offset that should be used when
|
||||
// creating the HTTP GET request's Range header
|
||||
Offset int64
|
||||
|
||||
// Count specifies the count of bytes that should be used to calculate
|
||||
// the end offset when creating the HTTP GET request's Range header
|
||||
Count int64
|
||||
|
||||
// ETag specifies the resource's etag that should be used when creating
|
||||
// the HTTP GET request's If-Match header
|
||||
ETag ETag
|
||||
}
|
||||
|
||||
// RetryReaderOptions contains properties which can help to decide when to do retry.
|
||||
type RetryReaderOptions struct {
|
||||
// MaxRetryRequests specifies the maximum number of HTTP GET requests that will be made
|
||||
// while reading from a RetryReader. A value of zero means that no additional HTTP
|
||||
// GET requests will be made.
|
||||
MaxRetryRequests int
|
||||
doInjectError bool
|
||||
doInjectErrorRound int
|
||||
}
|
||||
|
||||
// retryReader implements io.ReaderCloser methods.
|
||||
// retryReader tries to read from response, and if there is retriable network error
|
||||
// returned during reading, it will retry according to retry reader option through executing
|
||||
// user defined action with provided data to get a new response, and continue the overall reading process
|
||||
// through reading from the new response.
|
||||
type retryReader struct {
|
||||
ctx context.Context
|
||||
response *http.Response
|
||||
info HTTPGetterInfo
|
||||
countWasBounded bool
|
||||
o RetryReaderOptions
|
||||
getter HTTPGetter
|
||||
}
|
||||
|
||||
// NewRetryReader creates a retry reader.
|
||||
func NewRetryReader(ctx context.Context, initialResponse *http.Response,
|
||||
info HTTPGetterInfo, o RetryReaderOptions, getter HTTPGetter) io.ReadCloser {
|
||||
if getter == nil {
|
||||
panic("getter must not be nil")
|
||||
}
|
||||
if info.Count < 0 {
|
||||
panic("info.Count must be >= 0")
|
||||
}
|
||||
if o.MaxRetryRequests < 0 {
|
||||
panic("o.MaxRetryRequests must be >= 0")
|
||||
}
|
||||
return &retryReader{ctx: ctx, getter: getter, info: info, countWasBounded: info.Count != CountToEnd, response: initialResponse, o: o}
|
||||
}
|
||||
|
||||
func (s *retryReader) Read(p []byte) (n int, err error) {
|
||||
for try := 0; ; try++ {
|
||||
//fmt.Println(try) // Comment out for debugging.
|
||||
if s.countWasBounded && s.info.Count == CountToEnd {
|
||||
// User specified an original count and the remaining bytes are 0, return 0, EOF
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
if s.response == nil { // We don't have a response stream to read from, try to get one.
|
||||
response, err := s.getter(s.ctx, s.info)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Successful GET; this is the network stream we'll read from.
|
||||
s.response = response
|
||||
}
|
||||
n, err := s.response.Body.Read(p) // Read from the stream
|
||||
|
||||
// Injection mechanism for testing.
|
||||
if s.o.doInjectError && try == s.o.doInjectErrorRound {
|
||||
err = &net.DNSError{IsTemporary: true}
|
||||
}
|
||||
|
||||
// We successfully read data or end EOF.
|
||||
if err == nil || err == io.EOF {
|
||||
s.info.Offset += int64(n) // Increments the start offset in case we need to make a new HTTP request in the future
|
||||
if s.info.Count != CountToEnd {
|
||||
s.info.Count -= int64(n) // Decrement the count in case we need to make a new HTTP request in the future
|
||||
}
|
||||
return n, err // Return the return to the caller
|
||||
}
|
||||
s.Close() // Error, close stream
|
||||
s.response = nil // Our stream is no longer good
|
||||
|
||||
// Check the retry count and error code, and decide whether to retry.
|
||||
if try >= s.o.MaxRetryRequests {
|
||||
return n, err // All retries exhausted
|
||||
}
|
||||
|
||||
if netErr, ok := err.(net.Error); ok && (netErr.Timeout() || netErr.Temporary()) {
|
||||
continue
|
||||
// Loop around and try to get and read from new stream.
|
||||
}
|
||||
return n, err // Not retryable, just return
|
||||
}
|
||||
}
|
||||
|
||||
func (s *retryReader) Close() error {
|
||||
if s.response != nil && s.response.Body != nil {
|
||||
return s.response.Body.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
217
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_sas_account.go
generated
vendored
217
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_sas_account.go
generated
vendored
|
@ -1,217 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AccountSASSignatureValues is used to generate a Shared Access Signature (SAS) for an Azure Storage account.
|
||||
// For more information, see https://docs.microsoft.com/rest/api/storageservices/constructing-an-account-sas
|
||||
type AccountSASSignatureValues struct {
|
||||
Version string `param:"sv"` // If not specified, this defaults to SASVersion
|
||||
Protocol SASProtocol `param:"spr"` // See the SASProtocol* constants
|
||||
StartTime time.Time `param:"st"` // Not specified if IsZero
|
||||
ExpiryTime time.Time `param:"se"` // Not specified if IsZero
|
||||
Permissions string `param:"sp"` // Create by initializing a AccountSASPermissions and then call String()
|
||||
IPRange IPRange `param:"sip"`
|
||||
Services string `param:"ss"` // Create by initializing AccountSASServices and then call String()
|
||||
ResourceTypes string `param:"srt"` // Create by initializing AccountSASResourceTypes and then call String()
|
||||
}
|
||||
|
||||
// NewSASQueryParameters uses an account's shared key credential to sign this signature values to produce
|
||||
// the proper SAS query parameters.
|
||||
func (v AccountSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *SharedKeyCredential) SASQueryParameters {
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/Constructing-an-Account-SAS
|
||||
if v.ExpiryTime.IsZero() || v.Permissions == "" || v.ResourceTypes == "" || v.Services == "" {
|
||||
panic("Account SAS is missing at least one of these: ExpiryTime, Permissions, Service, or ResourceType")
|
||||
}
|
||||
if v.Version == "" {
|
||||
v.Version = SASVersion
|
||||
}
|
||||
perms := &AccountSASPermissions{}
|
||||
if err := perms.Parse(v.Permissions); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
v.Permissions = perms.String()
|
||||
|
||||
startTime, expiryTime := FormatTimesForSASSigning(v.StartTime, v.ExpiryTime)
|
||||
|
||||
stringToSign := strings.Join([]string{
|
||||
sharedKeyCredential.AccountName(),
|
||||
v.Permissions,
|
||||
v.Services,
|
||||
v.ResourceTypes,
|
||||
startTime,
|
||||
expiryTime,
|
||||
v.IPRange.String(),
|
||||
string(v.Protocol),
|
||||
v.Version,
|
||||
""}, // That right, the account SAS requires a terminating extra newline
|
||||
"\n")
|
||||
|
||||
signature := sharedKeyCredential.ComputeHMACSHA256(stringToSign)
|
||||
p := SASQueryParameters{
|
||||
// Common SAS parameters
|
||||
version: v.Version,
|
||||
protocol: v.Protocol,
|
||||
startTime: v.StartTime,
|
||||
expiryTime: v.ExpiryTime,
|
||||
permissions: v.Permissions,
|
||||
ipRange: v.IPRange,
|
||||
|
||||
// Account-specific SAS parameters
|
||||
services: v.Services,
|
||||
resourceTypes: v.ResourceTypes,
|
||||
|
||||
// Calculated SAS signature
|
||||
signature: signature,
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// The AccountSASPermissions type simplifies creating the permissions string for an Azure Storage Account SAS.
|
||||
// Initialize an instance of this type and then call its String method to set AccountSASSignatureValues's Permissions field.
|
||||
type AccountSASPermissions struct {
|
||||
Read, Write, Delete, List, Add, Create, Update, Process bool
|
||||
}
|
||||
|
||||
// String produces the SAS permissions string for an Azure Storage account.
|
||||
// Call this method to set AccountSASSignatureValues's Permissions field.
|
||||
func (p AccountSASPermissions) String() string {
|
||||
var buffer bytes.Buffer
|
||||
if p.Read {
|
||||
buffer.WriteRune('r')
|
||||
}
|
||||
if p.Write {
|
||||
buffer.WriteRune('w')
|
||||
}
|
||||
if p.Delete {
|
||||
buffer.WriteRune('d')
|
||||
}
|
||||
if p.List {
|
||||
buffer.WriteRune('l')
|
||||
}
|
||||
if p.Add {
|
||||
buffer.WriteRune('a')
|
||||
}
|
||||
if p.Create {
|
||||
buffer.WriteRune('c')
|
||||
}
|
||||
if p.Update {
|
||||
buffer.WriteRune('u')
|
||||
}
|
||||
if p.Process {
|
||||
buffer.WriteRune('p')
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// Parse initializes the AccountSASPermissions's fields from a string.
|
||||
func (p *AccountSASPermissions) Parse(s string) error {
|
||||
*p = AccountSASPermissions{} // Clear out the flags
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 'r':
|
||||
p.Read = true
|
||||
case 'w':
|
||||
p.Write = true
|
||||
case 'd':
|
||||
p.Delete = true
|
||||
case 'l':
|
||||
p.List = true
|
||||
case 'a':
|
||||
p.Add = true
|
||||
case 'c':
|
||||
p.Create = true
|
||||
case 'u':
|
||||
p.Update = true
|
||||
case 'p':
|
||||
p.Process = true
|
||||
default:
|
||||
return fmt.Errorf("Invalid permission character: '%v'", r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// The AccountSASServices type simplifies creating the services string for an Azure Storage Account SAS.
|
||||
// Initialize an instance of this type and then call its String method to set AccountSASSignatureValues's Services field.
|
||||
type AccountSASServices struct {
|
||||
Blob, Queue, File bool
|
||||
}
|
||||
|
||||
// String produces the SAS services string for an Azure Storage account.
|
||||
// Call this method to set AccountSASSignatureValues's Services field.
|
||||
func (s AccountSASServices) String() string {
|
||||
var buffer bytes.Buffer
|
||||
if s.Blob {
|
||||
buffer.WriteRune('b')
|
||||
}
|
||||
if s.Queue {
|
||||
buffer.WriteRune('q')
|
||||
}
|
||||
if s.File {
|
||||
buffer.WriteRune('f')
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// Parse initializes the AccountSASServices' fields from a string.
|
||||
func (a *AccountSASServices) Parse(s string) error {
|
||||
*a = AccountSASServices{} // Clear out the flags
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 'b':
|
||||
a.Blob = true
|
||||
case 'q':
|
||||
a.Queue = true
|
||||
case 'f':
|
||||
a.File = true
|
||||
default:
|
||||
return fmt.Errorf("Invalid service character: '%v'", r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// The AccountSASResourceTypes type simplifies creating the resource types string for an Azure Storage Account SAS.
|
||||
// Initialize an instance of this type and then call its String method to set AccountSASSignatureValues's ResourceTypes field.
|
||||
type AccountSASResourceTypes struct {
|
||||
Service, Container, Object bool
|
||||
}
|
||||
|
||||
// String produces the SAS resource types string for an Azure Storage account.
|
||||
// Call this method to set AccountSASSignatureValues's ResourceTypes field.
|
||||
func (rt AccountSASResourceTypes) String() string {
|
||||
var buffer bytes.Buffer
|
||||
if rt.Service {
|
||||
buffer.WriteRune('s')
|
||||
}
|
||||
if rt.Container {
|
||||
buffer.WriteRune('c')
|
||||
}
|
||||
if rt.Object {
|
||||
buffer.WriteRune('o')
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// Parse initializes the AccountSASResourceType's fields from a string.
|
||||
func (rt *AccountSASResourceTypes) Parse(s string) error {
|
||||
*rt = AccountSASResourceTypes{} // Clear out the flags
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 's':
|
||||
rt.Service = true
|
||||
case 'q':
|
||||
rt.Container = true
|
||||
case 'o':
|
||||
rt.Object = true
|
||||
default:
|
||||
return fmt.Errorf("Invalid resource type: '%v'", r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
211
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_sas_query_params.go
generated
vendored
211
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_sas_query_params.go
generated
vendored
|
@ -1,211 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SASVersion indicates the SAS version.
|
||||
const SASVersion = ServiceVersion
|
||||
|
||||
type SASProtocol string
|
||||
|
||||
const (
|
||||
// SASProtocolHTTPS can be specified for a SAS protocol
|
||||
SASProtocolHTTPS SASProtocol = "https"
|
||||
|
||||
// SASProtocolHTTPSandHTTP can be specified for a SAS protocol
|
||||
SASProtocolHTTPSandHTTP SASProtocol = "https,http"
|
||||
)
|
||||
|
||||
// FormatTimesForSASSigning converts a time.Time to a snapshotTimeFormat string suitable for a
|
||||
// SASField's StartTime or ExpiryTime fields. Returns "" if value.IsZero().
|
||||
func FormatTimesForSASSigning(startTime, expiryTime time.Time) (string, string) {
|
||||
ss := ""
|
||||
if !startTime.IsZero() {
|
||||
ss = startTime.Format(SASTimeFormat) // "yyyy-MM-ddTHH:mm:ssZ"
|
||||
}
|
||||
se := ""
|
||||
if !expiryTime.IsZero() {
|
||||
se = expiryTime.Format(SASTimeFormat) // "yyyy-MM-ddTHH:mm:ssZ"
|
||||
}
|
||||
return ss, se
|
||||
}
|
||||
|
||||
// SASTimeFormat represents the format of a SAS start or expiry time. Use it when formatting/parsing a time.Time.
|
||||
const SASTimeFormat = "2006-01-02T15:04:05Z" //"2017-07-27T00:00:00Z" // ISO 8601
|
||||
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
|
||||
// A SASQueryParameters object represents the components that make up an Azure Storage SAS' query parameters.
|
||||
// You parse a map of query parameters into its fields by calling NewSASQueryParameters(). You add the components
|
||||
// to a query parameter map by calling AddToValues().
|
||||
// NOTE: Changing any field requires computing a new SAS signature using a XxxSASSignatureValues type.
|
||||
//
|
||||
// This type defines the components used by all Azure Storage resources (Containers, Blobs, Files, & Queues).
|
||||
type SASQueryParameters struct {
|
||||
// All members are immutable or values so copies of this struct are goroutine-safe.
|
||||
version string `param:"sv"`
|
||||
services string `param:"ss"`
|
||||
resourceTypes string `param:"srt"`
|
||||
protocol SASProtocol `param:"spr"`
|
||||
startTime time.Time `param:"st"`
|
||||
expiryTime time.Time `param:"se"`
|
||||
ipRange IPRange `param:"sip"`
|
||||
identifier string `param:"si"`
|
||||
resource string `param:"sr"`
|
||||
permissions string `param:"sp"`
|
||||
signature string `param:"sig"`
|
||||
}
|
||||
|
||||
func (p *SASQueryParameters) Version() string {
|
||||
return p.version
|
||||
}
|
||||
|
||||
func (p *SASQueryParameters) Services() string {
|
||||
return p.services
|
||||
}
|
||||
func (p *SASQueryParameters) ResourceTypes() string {
|
||||
return p.resourceTypes
|
||||
}
|
||||
func (p *SASQueryParameters) Protocol() SASProtocol {
|
||||
return p.protocol
|
||||
}
|
||||
func (p *SASQueryParameters) StartTime() time.Time {
|
||||
return p.startTime
|
||||
}
|
||||
func (p *SASQueryParameters) ExpiryTime() time.Time {
|
||||
return p.expiryTime
|
||||
}
|
||||
|
||||
func (p *SASQueryParameters) IPRange() IPRange {
|
||||
return p.ipRange
|
||||
}
|
||||
|
||||
func (p *SASQueryParameters) Identifier() string {
|
||||
return p.identifier
|
||||
}
|
||||
|
||||
func (p *SASQueryParameters) Resource() string {
|
||||
return p.resource
|
||||
}
|
||||
func (p *SASQueryParameters) Permissions() string {
|
||||
return p.permissions
|
||||
}
|
||||
|
||||
func (p *SASQueryParameters) Signature() string {
|
||||
return p.signature
|
||||
}
|
||||
|
||||
// IPRange represents a SAS IP range's start IP and (optionally) end IP.
|
||||
type IPRange struct {
|
||||
Start net.IP // Not specified if length = 0
|
||||
End net.IP // Not specified if length = 0
|
||||
}
|
||||
|
||||
// String returns a string representation of an IPRange.
|
||||
func (ipr *IPRange) String() string {
|
||||
if len(ipr.Start) == 0 {
|
||||
return ""
|
||||
}
|
||||
start := ipr.Start.String()
|
||||
if len(ipr.End) == 0 {
|
||||
return start
|
||||
}
|
||||
return start + "-" + ipr.End.String()
|
||||
}
|
||||
|
||||
// NewSASQueryParameters creates and initializes a SASQueryParameters object based on the
|
||||
// query parameter map's passed-in values. If deleteSASParametersFromValues is true,
|
||||
// all SAS-related query parameters are removed from the passed-in map. If
|
||||
// deleteSASParametersFromValues is false, the map passed-in map is unaltered.
|
||||
func newSASQueryParameters(values url.Values, deleteSASParametersFromValues bool) SASQueryParameters {
|
||||
p := SASQueryParameters{}
|
||||
for k, v := range values {
|
||||
val := v[0]
|
||||
isSASKey := true
|
||||
switch strings.ToLower(k) {
|
||||
case "sv":
|
||||
p.version = val
|
||||
case "ss":
|
||||
p.services = val
|
||||
case "srt":
|
||||
p.resourceTypes = val
|
||||
case "spr":
|
||||
p.protocol = SASProtocol(val)
|
||||
case "st":
|
||||
p.startTime, _ = time.Parse(SASTimeFormat, val)
|
||||
case "se":
|
||||
p.expiryTime, _ = time.Parse(SASTimeFormat, val)
|
||||
case "sip":
|
||||
dashIndex := strings.Index(val, "-")
|
||||
if dashIndex == -1 {
|
||||
p.ipRange.Start = net.ParseIP(val)
|
||||
} else {
|
||||
p.ipRange.Start = net.ParseIP(val[:dashIndex])
|
||||
p.ipRange.End = net.ParseIP(val[dashIndex+1:])
|
||||
}
|
||||
case "si":
|
||||
p.identifier = val
|
||||
case "sr":
|
||||
p.resource = val
|
||||
case "sp":
|
||||
p.permissions = val
|
||||
case "sig":
|
||||
p.signature = val
|
||||
default:
|
||||
isSASKey = false // We didn't recognize the query parameter
|
||||
}
|
||||
if isSASKey && deleteSASParametersFromValues {
|
||||
delete(values, k)
|
||||
}
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// AddToValues adds the SAS components to the specified query parameters map.
|
||||
func (p *SASQueryParameters) addToValues(v url.Values) url.Values {
|
||||
if p.version != "" {
|
||||
v.Add("sv", p.version)
|
||||
}
|
||||
if p.services != "" {
|
||||
v.Add("ss", p.services)
|
||||
}
|
||||
if p.resourceTypes != "" {
|
||||
v.Add("srt", p.resourceTypes)
|
||||
}
|
||||
if p.protocol != "" {
|
||||
v.Add("spr", string(p.protocol))
|
||||
}
|
||||
if !p.startTime.IsZero() {
|
||||
v.Add("st", p.startTime.Format(SASTimeFormat))
|
||||
}
|
||||
if !p.expiryTime.IsZero() {
|
||||
v.Add("se", p.expiryTime.Format(SASTimeFormat))
|
||||
}
|
||||
if len(p.ipRange.Start) > 0 {
|
||||
v.Add("sip", p.ipRange.String())
|
||||
}
|
||||
if p.identifier != "" {
|
||||
v.Add("si", p.identifier)
|
||||
}
|
||||
if p.resource != "" {
|
||||
v.Add("sr", p.resource)
|
||||
}
|
||||
if p.permissions != "" {
|
||||
v.Add("sp", p.permissions)
|
||||
}
|
||||
if p.signature != "" {
|
||||
v.Add("sig", p.signature)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Encode encodes the SAS query parameters into URL encoded form sorted by key.
|
||||
func (p *SASQueryParameters) Encode() string {
|
||||
v := url.Values{}
|
||||
p.addToValues(v)
|
||||
return v.Encode()
|
||||
}
|
131
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_service_codes_common.go
generated
vendored
131
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_service_codes_common.go
generated
vendored
|
@ -1,131 +0,0 @@
|
|||
package azblob
|
||||
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/common-rest-api-error-codes
|
||||
|
||||
const (
|
||||
// ServiceCodeNone is the default value. It indicates that the error was related to the service or that the service didn't return a code.
|
||||
ServiceCodeNone ServiceCodeType = ""
|
||||
|
||||
// ServiceCodeAccountAlreadyExists means the specified account already exists.
|
||||
ServiceCodeAccountAlreadyExists ServiceCodeType = "AccountAlreadyExists"
|
||||
|
||||
// ServiceCodeAccountBeingCreated means the specified account is in the process of being created (403).
|
||||
ServiceCodeAccountBeingCreated ServiceCodeType = "AccountBeingCreated"
|
||||
|
||||
// ServiceCodeAccountIsDisabled means the specified account is disabled (403).
|
||||
ServiceCodeAccountIsDisabled ServiceCodeType = "AccountIsDisabled"
|
||||
|
||||
// ServiceCodeAuthenticationFailed means the server failed to authenticate the request. Make sure the value of the Authorization header is formed correctly including the signature (403).
|
||||
ServiceCodeAuthenticationFailed ServiceCodeType = "AuthenticationFailed"
|
||||
|
||||
// ServiceCodeConditionHeadersNotSupported means the condition headers are not supported (400).
|
||||
ServiceCodeConditionHeadersNotSupported ServiceCodeType = "ConditionHeadersNotSupported"
|
||||
|
||||
// ServiceCodeConditionNotMet means the condition specified in the conditional header(s) was not met for a read/write operation (304/412).
|
||||
ServiceCodeConditionNotMet ServiceCodeType = "ConditionNotMet"
|
||||
|
||||
// ServiceCodeEmptyMetadataKey means the key for one of the metadata key-value pairs is empty (400).
|
||||
ServiceCodeEmptyMetadataKey ServiceCodeType = "EmptyMetadataKey"
|
||||
|
||||
// ServiceCodeInsufficientAccountPermissions means read operations are currently disabled or Write operations are not allowed or The account being accessed does not have sufficient permissions to execute this operation (403).
|
||||
ServiceCodeInsufficientAccountPermissions ServiceCodeType = "InsufficientAccountPermissions"
|
||||
|
||||
// ServiceCodeInternalError means the server encountered an internal error. Please retry the request (500).
|
||||
ServiceCodeInternalError ServiceCodeType = "InternalError"
|
||||
|
||||
// ServiceCodeInvalidAuthenticationInfo means the authentication information was not provided in the correct format. Verify the value of Authorization header (400).
|
||||
ServiceCodeInvalidAuthenticationInfo ServiceCodeType = "InvalidAuthenticationInfo"
|
||||
|
||||
// ServiceCodeInvalidHeaderValue means the value provided for one of the HTTP headers was not in the correct format (400).
|
||||
ServiceCodeInvalidHeaderValue ServiceCodeType = "InvalidHeaderValue"
|
||||
|
||||
// ServiceCodeInvalidHTTPVerb means the HTTP verb specified was not recognized by the server (400).
|
||||
ServiceCodeInvalidHTTPVerb ServiceCodeType = "InvalidHttpVerb"
|
||||
|
||||
// ServiceCodeInvalidInput means one of the request inputs is not valid (400).
|
||||
ServiceCodeInvalidInput ServiceCodeType = "InvalidInput"
|
||||
|
||||
// ServiceCodeInvalidMd5 means the MD5 value specified in the request is invalid. The MD5 value must be 128 bits and Base64-encoded (400).
|
||||
ServiceCodeInvalidMd5 ServiceCodeType = "InvalidMd5"
|
||||
|
||||
// ServiceCodeInvalidMetadata means the specified metadata is invalid. It includes characters that are not permitted (400).
|
||||
ServiceCodeInvalidMetadata ServiceCodeType = "InvalidMetadata"
|
||||
|
||||
// ServiceCodeInvalidQueryParameterValue means an invalid value was specified for one of the query parameters in the request URI (400).
|
||||
ServiceCodeInvalidQueryParameterValue ServiceCodeType = "InvalidQueryParameterValue"
|
||||
|
||||
// ServiceCodeInvalidRange means the range specified is invalid for the current size of the resource (416).
|
||||
ServiceCodeInvalidRange ServiceCodeType = "InvalidRange"
|
||||
|
||||
// ServiceCodeInvalidResourceName means the specified resource name contains invalid characters (400).
|
||||
ServiceCodeInvalidResourceName ServiceCodeType = "InvalidResourceName"
|
||||
|
||||
// ServiceCodeInvalidURI means the requested URI does not represent any resource on the server (400).
|
||||
ServiceCodeInvalidURI ServiceCodeType = "InvalidUri"
|
||||
|
||||
// ServiceCodeInvalidXMLDocument means the specified XML is not syntactically valid (400).
|
||||
ServiceCodeInvalidXMLDocument ServiceCodeType = "InvalidXmlDocument"
|
||||
|
||||
// ServiceCodeInvalidXMLNodeValue means the value provided for one of the XML nodes in the request body was not in the correct format (400).
|
||||
ServiceCodeInvalidXMLNodeValue ServiceCodeType = "InvalidXmlNodeValue"
|
||||
|
||||
// ServiceCodeMd5Mismatch means the MD5 value specified in the request did not match the MD5 value calculated by the server (400).
|
||||
ServiceCodeMd5Mismatch ServiceCodeType = "Md5Mismatch"
|
||||
|
||||
// ServiceCodeMetadataTooLarge means the size of the specified metadata exceeds the maximum size permitted (400).
|
||||
ServiceCodeMetadataTooLarge ServiceCodeType = "MetadataTooLarge"
|
||||
|
||||
// ServiceCodeMissingContentLengthHeader means the Content-Length header was not specified (411).
|
||||
ServiceCodeMissingContentLengthHeader ServiceCodeType = "MissingContentLengthHeader"
|
||||
|
||||
// ServiceCodeMissingRequiredQueryParameter means a required query parameter was not specified for this request (400).
|
||||
ServiceCodeMissingRequiredQueryParameter ServiceCodeType = "MissingRequiredQueryParameter"
|
||||
|
||||
// ServiceCodeMissingRequiredHeader means a required HTTP header was not specified (400).
|
||||
ServiceCodeMissingRequiredHeader ServiceCodeType = "MissingRequiredHeader"
|
||||
|
||||
// ServiceCodeMissingRequiredXMLNode means a required XML node was not specified in the request body (400).
|
||||
ServiceCodeMissingRequiredXMLNode ServiceCodeType = "MissingRequiredXmlNode"
|
||||
|
||||
// ServiceCodeMultipleConditionHeadersNotSupported means multiple condition headers are not supported (400).
|
||||
ServiceCodeMultipleConditionHeadersNotSupported ServiceCodeType = "MultipleConditionHeadersNotSupported"
|
||||
|
||||
// ServiceCodeOperationTimedOut means the operation could not be completed within the permitted time (500).
|
||||
ServiceCodeOperationTimedOut ServiceCodeType = "OperationTimedOut"
|
||||
|
||||
// ServiceCodeOutOfRangeInput means one of the request inputs is out of range (400).
|
||||
ServiceCodeOutOfRangeInput ServiceCodeType = "OutOfRangeInput"
|
||||
|
||||
// ServiceCodeOutOfRangeQueryParameterValue means a query parameter specified in the request URI is outside the permissible range (400).
|
||||
ServiceCodeOutOfRangeQueryParameterValue ServiceCodeType = "OutOfRangeQueryParameterValue"
|
||||
|
||||
// ServiceCodeRequestBodyTooLarge means the size of the request body exceeds the maximum size permitted (413).
|
||||
ServiceCodeRequestBodyTooLarge ServiceCodeType = "RequestBodyTooLarge"
|
||||
|
||||
// ServiceCodeResourceTypeMismatch means the specified resource type does not match the type of the existing resource (409).
|
||||
ServiceCodeResourceTypeMismatch ServiceCodeType = "ResourceTypeMismatch"
|
||||
|
||||
// ServiceCodeRequestURLFailedToParse means the url in the request could not be parsed (400).
|
||||
ServiceCodeRequestURLFailedToParse ServiceCodeType = "RequestUrlFailedToParse"
|
||||
|
||||
// ServiceCodeResourceAlreadyExists means the specified resource already exists (409).
|
||||
ServiceCodeResourceAlreadyExists ServiceCodeType = "ResourceAlreadyExists"
|
||||
|
||||
// ServiceCodeResourceNotFound means the specified resource does not exist (404).
|
||||
ServiceCodeResourceNotFound ServiceCodeType = "ResourceNotFound"
|
||||
|
||||
// ServiceCodeServerBusy means the server is currently unable to receive requests. Please retry your request or Ingress/egress is over the account limit or operations per second is over the account limit (503).
|
||||
ServiceCodeServerBusy ServiceCodeType = "ServerBusy"
|
||||
|
||||
// ServiceCodeUnsupportedHeader means one of the HTTP headers specified in the request is not supported (400).
|
||||
ServiceCodeUnsupportedHeader ServiceCodeType = "UnsupportedHeader"
|
||||
|
||||
// ServiceCodeUnsupportedXMLNode means one of the XML nodes specified in the request body is not supported (400).
|
||||
ServiceCodeUnsupportedXMLNode ServiceCodeType = "UnsupportedXmlNode"
|
||||
|
||||
// ServiceCodeUnsupportedQueryParameter means one of the query parameters specified in the request URI is not supported (400).
|
||||
ServiceCodeUnsupportedQueryParameter ServiceCodeType = "UnsupportedQueryParameter"
|
||||
|
||||
// ServiceCodeUnsupportedHTTPVerb means the resource doesn't support the specified HTTP verb (405).
|
||||
ServiceCodeUnsupportedHTTPVerb ServiceCodeType = "UnsupportedHttpVerb"
|
||||
)
|
110
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_storage_error.go
generated
vendored
110
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_storage_error.go
generated
vendored
|
@ -1,110 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// wire up our custom error handling constructor
|
||||
responseErrorFactory = newStorageError
|
||||
}
|
||||
|
||||
// ServiceCodeType is a string identifying a storage service error.
|
||||
// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/status-and-error-codes2
|
||||
type ServiceCodeType string
|
||||
|
||||
// StorageError identifies a responder-generated network or response parsing error.
|
||||
type StorageError interface {
|
||||
// ResponseError implements error's Error(), net.Error's Temporary() and Timeout() methods & Response().
|
||||
ResponseError
|
||||
|
||||
// ServiceCode returns a service error code. Your code can use this to make error recovery decisions.
|
||||
ServiceCode() ServiceCodeType
|
||||
}
|
||||
|
||||
// storageError is the internal struct that implements the public StorageError interface.
|
||||
type storageError struct {
|
||||
responseError
|
||||
serviceCode ServiceCodeType
|
||||
details map[string]string
|
||||
}
|
||||
|
||||
// newStorageError creates an error object that implements the error interface.
|
||||
func newStorageError(cause error, response *http.Response, description string) error {
|
||||
return &storageError{
|
||||
responseError: responseError{
|
||||
ErrorNode: pipeline.ErrorNode{}.Initialize(cause, 3),
|
||||
response: response,
|
||||
description: description,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ServiceCode returns service-error information. The caller may examine these values but should not modify any of them.
|
||||
func (e *storageError) ServiceCode() ServiceCodeType { return e.serviceCode }
|
||||
|
||||
// Error implements the error interface's Error method to return a string representation of the error.
|
||||
func (e *storageError) Error() string {
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "===== RESPONSE ERROR (ServiceCode=%s) =====\n", e.serviceCode)
|
||||
fmt.Fprintf(b, "Description=%s, Details: ", e.description)
|
||||
if len(e.details) == 0 {
|
||||
b.WriteString("(none)\n")
|
||||
} else {
|
||||
b.WriteRune('\n')
|
||||
keys := make([]string, 0, len(e.details))
|
||||
// Alphabetize the details
|
||||
for k := range e.details {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
fmt.Fprintf(b, " %s: %+v\n", k, e.details[k])
|
||||
}
|
||||
}
|
||||
req := pipeline.Request{Request: e.response.Request}.Copy() // Make a copy of the response's request
|
||||
pipeline.WriteRequestWithResponse(b, prepareRequestForLogging(req), e.response, nil)
|
||||
return e.ErrorNode.Error(b.String())
|
||||
}
|
||||
|
||||
// Temporary returns true if the error occurred due to a temporary condition (including an HTTP status of 500 or 503).
|
||||
func (e *storageError) Temporary() bool {
|
||||
if e.response != nil {
|
||||
if (e.response.StatusCode == http.StatusInternalServerError) || (e.response.StatusCode == http.StatusServiceUnavailable) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return e.ErrorNode.Temporary()
|
||||
}
|
||||
|
||||
// UnmarshalXML performs custom unmarshalling of XML-formatted Azure storage request errors.
|
||||
func (e *storageError) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
|
||||
tokName := ""
|
||||
var t xml.Token
|
||||
for t, err = d.Token(); err == nil; t, err = d.Token() {
|
||||
switch tt := t.(type) {
|
||||
case xml.StartElement:
|
||||
tokName = tt.Name.Local
|
||||
break
|
||||
case xml.CharData:
|
||||
switch tokName {
|
||||
case "Code":
|
||||
e.serviceCode = ServiceCodeType(tt)
|
||||
case "Message":
|
||||
e.description = string(tt)
|
||||
default:
|
||||
if e.details == nil {
|
||||
e.details = map[string]string{}
|
||||
}
|
||||
e.details[tokName] = string(tt)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
61
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_util_validate.go
generated
vendored
61
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_util_validate.go
generated
vendored
|
@ -1,61 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// httpRange defines a range of bytes within an HTTP resource, starting at offset and
|
||||
// ending at offset+count. A zero-value httpRange indicates the entire resource. An httpRange
|
||||
// which has an offset but na zero value count indicates from the offset to the resource's end.
|
||||
type httpRange struct {
|
||||
offset int64
|
||||
count int64
|
||||
}
|
||||
|
||||
func (r httpRange) pointers() *string {
|
||||
if r.offset == 0 && r.count == 0 { // Do common case first for performance
|
||||
return nil // No specified range
|
||||
}
|
||||
if r.offset < 0 {
|
||||
panic("The range offset must be >= 0")
|
||||
}
|
||||
if r.count < 0 {
|
||||
panic("The range count must be >= 0")
|
||||
}
|
||||
endOffset := "" // if count == 0
|
||||
if r.count > 0 {
|
||||
endOffset = strconv.FormatInt((r.offset+r.count)-1, 10)
|
||||
}
|
||||
dataRange := fmt.Sprintf("bytes=%v-%s", r.offset, endOffset)
|
||||
return &dataRange
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
func validateSeekableStreamAt0AndGetCount(body io.ReadSeeker) int64 {
|
||||
if body == nil { // nil body's are "logically" seekable to 0 and are 0 bytes long
|
||||
return 0
|
||||
}
|
||||
validateSeekableStreamAt0(body)
|
||||
count, err := body.Seek(0, io.SeekEnd)
|
||||
if err != nil {
|
||||
panic("failed to seek stream")
|
||||
}
|
||||
body.Seek(0, io.SeekStart)
|
||||
return count
|
||||
}
|
||||
|
||||
func validateSeekableStreamAt0(body io.ReadSeeker) {
|
||||
if body == nil { // nil body's are "logically" seekable to 0
|
||||
return
|
||||
}
|
||||
if pos, err := body.Seek(0, io.SeekCurrent); pos != 0 || err != nil {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
panic(errors.New("stream must be set to position 0"))
|
||||
}
|
||||
}
|
80
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_uuid.go
generated
vendored
80
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zc_uuid.go
generated
vendored
|
@ -1,80 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// The UUID reserved variants.
|
||||
const (
|
||||
reservedNCS byte = 0x80
|
||||
reservedRFC4122 byte = 0x40
|
||||
reservedMicrosoft byte = 0x20
|
||||
reservedFuture byte = 0x00
|
||||
)
|
||||
|
||||
// A UUID representation compliant with specification in RFC 4122 document.
|
||||
type uuid [16]byte
|
||||
|
||||
// NewUUID returns a new uuid using RFC 4122 algorithm.
|
||||
func newUUID() (u uuid) {
|
||||
u = uuid{}
|
||||
// Set all bits to randomly (or pseudo-randomly) chosen values.
|
||||
_, err := rand.Read(u[:])
|
||||
if err != nil {
|
||||
panic("ran.Read failed")
|
||||
}
|
||||
u[8] = (u[8] | reservedRFC4122) & 0x7F // u.setVariant(ReservedRFC4122)
|
||||
|
||||
var version byte = 4
|
||||
u[6] = (u[6] & 0xF) | (version << 4) // u.setVersion(4)
|
||||
return
|
||||
}
|
||||
|
||||
// String returns an unparsed version of the generated UUID sequence.
|
||||
func (u uuid) String() string {
|
||||
return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:])
|
||||
}
|
||||
|
||||
// ParseUUID parses a string formatted as "003020100-0504-0706-0809-0a0b0c0d0e0f"
|
||||
// or "{03020100-0504-0706-0809-0a0b0c0d0e0f}" into a UUID.
|
||||
func parseUUID(uuidStr string) uuid {
|
||||
char := func(hexString string) byte {
|
||||
i, _ := strconv.ParseUint(hexString, 16, 8)
|
||||
return byte(i)
|
||||
}
|
||||
if uuidStr[0] == '{' {
|
||||
uuidStr = uuidStr[1:] // Skip over the '{'
|
||||
}
|
||||
// 03020100 - 05 04 - 07 06 - 08 09 - 0a 0b 0c 0d 0e 0f
|
||||
// 1 11 1 11 11 1 12 22 2 22 22 22 33 33 33
|
||||
// 01234567 8 90 12 3 45 67 8 90 12 3 45 67 89 01 23 45
|
||||
uuidVal := uuid{
|
||||
char(uuidStr[0:2]),
|
||||
char(uuidStr[2:4]),
|
||||
char(uuidStr[4:6]),
|
||||
char(uuidStr[6:8]),
|
||||
|
||||
char(uuidStr[9:11]),
|
||||
char(uuidStr[11:13]),
|
||||
|
||||
char(uuidStr[14:16]),
|
||||
char(uuidStr[16:18]),
|
||||
|
||||
char(uuidStr[19:21]),
|
||||
char(uuidStr[21:23]),
|
||||
|
||||
char(uuidStr[24:26]),
|
||||
char(uuidStr[26:28]),
|
||||
char(uuidStr[28:30]),
|
||||
char(uuidStr[30:32]),
|
||||
char(uuidStr[32:34]),
|
||||
char(uuidStr[34:36]),
|
||||
}
|
||||
return uuidVal
|
||||
}
|
||||
|
||||
func (u uuid) bytes() []byte {
|
||||
return u[:]
|
||||
}
|
89
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zt_doc.go
generated
vendored
89
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zt_doc.go
generated
vendored
|
@ -1,89 +0,0 @@
|
|||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
||||
// Use of this source code is governed by an MIT
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package azblob allows you to manipulate Azure Storage containers and blobs objects.
|
||||
|
||||
URL Types
|
||||
|
||||
The most common types you'll work with are the XxxURL types. The methods of these types make requests
|
||||
against the Azure Storage Service.
|
||||
|
||||
- ServiceURL's methods perform operations on a storage account.
|
||||
- ContainerURL's methods perform operations on an account's container.
|
||||
- BlockBlobURL's methods perform operations on a container's block blob.
|
||||
- AppendBlobURL's methods perform operations on a container's append blob.
|
||||
- PageBlobURL's methods perform operations on a container's page blob.
|
||||
- BlobURL's methods perform operations on a container's blob regardless of the blob's type.
|
||||
|
||||
Internally, each XxxURL object contains a URL and a request pipeline. The URL indicates the endpoint where each HTTP
|
||||
request is sent and the pipeline indicates how the outgoing HTTP request and incoming HTTP response is processed.
|
||||
The pipeline specifies things like retry policies, logging, deserialization of HTTP response payloads, and more.
|
||||
|
||||
Pipelines are threadsafe and may be shared by multiple XxxURL objects. When you create a ServiceURL, you pass
|
||||
an initial pipeline. When you call ServiceURL's NewContainerURL method, the new ContainerURL object has its own
|
||||
URL but it shares the same pipeline as the parent ServiceURL object.
|
||||
|
||||
To work with a blob, call one of ContainerURL's 4 NewXxxBlobURL methods depending on how you want to treat the blob.
|
||||
To treat the blob as a block blob, append blob, or page blob, call NewBlockBlobURL, NewAppendBlobURL, or NewPageBlobURL
|
||||
respectively. These three types are all identical except for the methods they expose; each type exposes the methods
|
||||
relevant to the type of blob represented. If you're not sure how you want to treat a blob, you can call NewBlobURL;
|
||||
this returns an object whose methods are relevant to any kind of blob. When you call ContainerURL's NewXxxBlobURL,
|
||||
the new XxxBlobURL object has its own URL but it shares the same pipeline as the parent ContainerURL object. You
|
||||
can easily switch between blob types (method sets) by calling a ToXxxBlobURL method.
|
||||
|
||||
If you'd like to use a different pipeline with a ServiceURL, ContainerURL, or XxxBlobURL object, then call the XxxURL
|
||||
object's WithPipeline method passing in the desired pipeline. The WithPipeline methods create a new XxxURL object
|
||||
with the same URL as the original but with the specified pipeline.
|
||||
|
||||
Note that XxxURL objects use little memory, are goroutine-safe, and many objects share the same pipeline. This means that
|
||||
XxxURL objects share a lot of system resources making them very efficient.
|
||||
|
||||
All of XxxURL's methods that make HTTP requests return rich error handling information so you can discern network failures,
|
||||
transient failures, timeout failures, service failures, etc. See the StorageError interface for more information and an
|
||||
example of how to do deal with errors.
|
||||
|
||||
URL and Shared Access Signature Manipulation
|
||||
|
||||
The library includes a BlobURLParts type for deconstructing and reconstructing URLs. And you can use the following types
|
||||
for generating and parsing Shared Access Signature (SAS)
|
||||
- Use the AccountSASSignatureValues type to create a SAS for a storage account.
|
||||
- Use the BlobSASSignatureValues type to create a SAS for a container or blob.
|
||||
- Use the SASQueryParameters type to turn signature values in to query parameres or to parse query parameters.
|
||||
|
||||
To generate a SAS, you must use the SharedKeyCredential type.
|
||||
|
||||
Credentials
|
||||
|
||||
When creating a request pipeline, you must specify one of this package's credential types.
|
||||
- Call the NewAnonymousCredential function for requests that contain a Shared Access Signature (SAS).
|
||||
- Call the NewSharedKeyCredential function (with an account name & key) to access any account resources. You must also use this
|
||||
to generate Shared Access Signatures.
|
||||
|
||||
HTTP Request Policy Factories
|
||||
|
||||
This package defines several request policy factories for use with the pipeline package.
|
||||
Most applications will not use these factories directly; instead, the NewPipeline
|
||||
function creates these factories, initializes them (via the PipelineOptions type)
|
||||
and returns a pipeline object for use by the XxxURL objects.
|
||||
|
||||
However, for advanced scenarios, developers can access these policy factories directly
|
||||
and even create their own and then construct their own pipeline in order to affect HTTP
|
||||
requests and responses performed by the XxxURL objects. For example, developers can
|
||||
introduce their own logging, random failures, request recording & playback for fast
|
||||
testing, HTTP request pacing, alternate retry mechanisms, metering, metrics, etc. The
|
||||
possibilities are endless!
|
||||
|
||||
Below are the request pipeline policy factory functions that are provided with this
|
||||
package:
|
||||
- NewRetryPolicyFactory Enables rich retry semantics for failed HTTP requests.
|
||||
- NewRequestLogPolicyFactory Enables rich logging support for HTTP requests/responses & failures.
|
||||
- NewTelemetryPolicyFactory Enables simple modification of the HTTP request's User-Agent header so each request reports the SDK version & language/runtime making the requests.
|
||||
- NewUniqueRequestIDPolicyFactory Adds a x-ms-client-request-id header with a unique UUID value to an HTTP request to help with diagnosing failures.
|
||||
|
||||
Also, note that all the NewXxxCredential functions return request policy factory objects which get injected into the pipeline.
|
||||
*/
|
||||
package azblob
|
||||
|
||||
// TokenCredential Use this to access resources using Role-Based Access Control (RBAC).
|
1217
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zt_examples_test.go
generated
vendored
1217
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zt_examples_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
322
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zt_highlevel_test.go
generated
vendored
322
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zt_highlevel_test.go
generated
vendored
|
@ -1,322 +0,0 @@
|
|||
package azblob_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/azure-storage-blob-go/2017-07-29/azblob"
|
||||
chk "gopkg.in/check.v1"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
// create a test file
|
||||
func generateFile(fileName string, fileSize int) []byte {
|
||||
// generate random data
|
||||
_, bigBuff := getRandomDataAndReader(fileSize)
|
||||
|
||||
// write to file and return the data
|
||||
ioutil.WriteFile(fileName, bigBuff, 0666)
|
||||
return bigBuff
|
||||
}
|
||||
|
||||
func performUploadStreamToBlockBlobTest(c *chk.C, blobSize, bufferSize, maxBuffers int) {
|
||||
// Set up test container
|
||||
bsu := getBSU()
|
||||
containerURL, _ := createNewContainer(c, bsu)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
// Set up test blob
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
// Create some data to test the upload stream
|
||||
blobContentReader, blobData := getRandomDataAndReader(blobSize)
|
||||
|
||||
// Perform UploadStreamToBlockBlob
|
||||
uploadResp, err := azblob.UploadStreamToBlockBlob(ctx, blobContentReader, blobURL,
|
||||
azblob.UploadStreamToBlockBlobOptions{BufferSize: bufferSize, MaxBuffers: maxBuffers})
|
||||
|
||||
// Assert that upload was successful
|
||||
c.Assert(err, chk.Equals, nil)
|
||||
c.Assert(uploadResp.Response().StatusCode, chk.Equals, 201)
|
||||
|
||||
// Download the blob to verify
|
||||
downloadResponse, err := blobURL.Download(ctx, 0, 0, azblob.BlobAccessConditions{}, false)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
// Assert that the content is correct
|
||||
actualBlobData, err := ioutil.ReadAll(downloadResponse.Response().Body)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(len(actualBlobData), chk.Equals, blobSize)
|
||||
c.Assert(actualBlobData, chk.DeepEquals, blobData)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadStreamToBlockBlobInChunks(c *chk.C) {
|
||||
blobSize := 8 * 1024
|
||||
bufferSize := 1024
|
||||
maxBuffers := 3
|
||||
performUploadStreamToBlockBlobTest(c, blobSize, bufferSize, maxBuffers)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadStreamToBlockBlobSingleBuffer(c *chk.C) {
|
||||
blobSize := 8 * 1024
|
||||
bufferSize := 1024
|
||||
maxBuffers := 1
|
||||
performUploadStreamToBlockBlobTest(c, blobSize, bufferSize, maxBuffers)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadStreamToBlockBlobSingleIO(c *chk.C) {
|
||||
blobSize := 1024
|
||||
bufferSize := 8 * 1024
|
||||
maxBuffers := 3
|
||||
performUploadStreamToBlockBlobTest(c, blobSize, bufferSize, maxBuffers)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadStreamToBlockBlobEmpty(c *chk.C) {
|
||||
blobSize := 0
|
||||
bufferSize := 8 * 1024
|
||||
maxBuffers := 3
|
||||
performUploadStreamToBlockBlobTest(c, blobSize, bufferSize, maxBuffers)
|
||||
}
|
||||
|
||||
func performUploadAndDownloadFileTest(c *chk.C, fileSize, blockSize, parallelism, downloadOffset, downloadCount int) {
|
||||
// Set up file to upload
|
||||
fileName := "BigFile.bin"
|
||||
fileData := generateFile(fileName, fileSize)
|
||||
|
||||
// Open the file to upload
|
||||
file, err := os.Open(fileName)
|
||||
c.Assert(err, chk.Equals, nil)
|
||||
defer file.Close()
|
||||
defer os.Remove(fileName)
|
||||
|
||||
// Set up test container
|
||||
bsu := getBSU()
|
||||
containerURL, _ := createNewContainer(c, bsu)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
// Set up test blob
|
||||
blockBlobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
// Upload the file to a block blob
|
||||
response, err := azblob.UploadFileToBlockBlob(context.Background(), file, blockBlobURL,
|
||||
azblob.UploadToBlockBlobOptions{
|
||||
BlockSize: int64(blockSize),
|
||||
Parallelism: uint16(parallelism),
|
||||
// If Progress is non-nil, this function is called periodically as bytes are uploaded.
|
||||
Progress: func(bytesTransferred int64) {
|
||||
c.Assert(bytesTransferred > 0 && bytesTransferred <= int64(fileSize), chk.Equals, true)
|
||||
},
|
||||
})
|
||||
c.Assert(err, chk.Equals, nil)
|
||||
c.Assert(response.Response().StatusCode, chk.Equals, 201)
|
||||
|
||||
// Set up file to download the blob to
|
||||
destFileName := "BigFile-downloaded.bin"
|
||||
destFile, err := os.Create(destFileName)
|
||||
c.Assert(err, chk.Equals, nil)
|
||||
defer destFile.Close()
|
||||
defer os.Remove(destFileName)
|
||||
|
||||
// Perform download
|
||||
err = azblob.DownloadBlobToFile(context.Background(), blockBlobURL.BlobURL, int64(downloadOffset), int64(downloadCount),
|
||||
azblob.BlobAccessConditions{}, destFile,
|
||||
azblob.DownloadFromBlobOptions{
|
||||
BlockSize: int64(blockSize),
|
||||
Parallelism: uint16(parallelism),
|
||||
// If Progress is non-nil, this function is called periodically as bytes are uploaded.
|
||||
Progress: func(bytesTransferred int64) {
|
||||
c.Assert(bytesTransferred > 0 && bytesTransferred <= int64(fileSize), chk.Equals, true)
|
||||
},})
|
||||
|
||||
// Assert download was successful
|
||||
c.Assert(err, chk.Equals, nil)
|
||||
|
||||
// Assert downloaded data is consistent
|
||||
var destBuffer []byte
|
||||
if downloadCount == azblob.CountToEnd {
|
||||
destBuffer = make([]byte, fileSize - downloadOffset)
|
||||
} else {
|
||||
destBuffer = make([]byte, downloadCount)
|
||||
}
|
||||
|
||||
n, err := destFile.Read(destBuffer)
|
||||
c.Assert(err, chk.Equals, nil)
|
||||
|
||||
if downloadOffset == 0 && downloadCount == 0 {
|
||||
c.Assert(destBuffer, chk.DeepEquals, fileData)
|
||||
} else {
|
||||
if downloadCount == 0 {
|
||||
c.Assert(n, chk.Equals, fileSize - downloadOffset)
|
||||
c.Assert(destBuffer, chk.DeepEquals, fileData[downloadOffset:])
|
||||
} else {
|
||||
c.Assert(n, chk.Equals, downloadCount)
|
||||
c.Assert(destBuffer, chk.DeepEquals, fileData[downloadOffset: downloadOffset + downloadCount])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadAndDownloadFileInChunks(c *chk.C) {
|
||||
fileSize := 8 * 1024
|
||||
blockSize := 1024
|
||||
parallelism := 3
|
||||
performUploadAndDownloadFileTest(c, fileSize, blockSize, parallelism, 0, 0)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadAndDownloadFileSingleIO(c *chk.C) {
|
||||
fileSize := 1024
|
||||
blockSize := 2048
|
||||
parallelism := 3
|
||||
performUploadAndDownloadFileTest(c, fileSize, blockSize, parallelism, 0, 0)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadAndDownloadFileSingleRoutine(c *chk.C) {
|
||||
fileSize := 8 * 1024
|
||||
blockSize := 1024
|
||||
parallelism := 1
|
||||
performUploadAndDownloadFileTest(c, fileSize, blockSize, parallelism, 0, 0)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadAndDownloadFileEmpty(c *chk.C) {
|
||||
fileSize := 0
|
||||
blockSize := 1024
|
||||
parallelism := 3
|
||||
performUploadAndDownloadFileTest(c, fileSize, blockSize, parallelism, 0, 0)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadAndDownloadFileNonZeroOffset(c *chk.C) {
|
||||
fileSize := 8 * 1024
|
||||
blockSize := 1024
|
||||
parallelism := 3
|
||||
downloadOffset := 1000
|
||||
downloadCount := 0
|
||||
performUploadAndDownloadFileTest(c, fileSize, blockSize, parallelism, downloadOffset, downloadCount)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadAndDownloadFileNonZeroCount(c *chk.C) {
|
||||
fileSize := 8 * 1024
|
||||
blockSize := 1024
|
||||
parallelism := 3
|
||||
downloadOffset := 0
|
||||
downloadCount := 6000
|
||||
performUploadAndDownloadFileTest(c, fileSize, blockSize, parallelism, downloadOffset, downloadCount)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadAndDownloadFileNonZeroOffsetAndCount(c *chk.C) {
|
||||
fileSize := 8 * 1024
|
||||
blockSize := 1024
|
||||
parallelism := 3
|
||||
downloadOffset := 1000
|
||||
downloadCount := 6000
|
||||
performUploadAndDownloadFileTest(c, fileSize, blockSize, parallelism, downloadOffset, downloadCount)
|
||||
}
|
||||
|
||||
func performUploadAndDownloadBufferTest(c *chk.C, blobSize, blockSize, parallelism, downloadOffset, downloadCount int) {
|
||||
// Set up buffer to upload
|
||||
_, bytesToUpload := getRandomDataAndReader(blobSize)
|
||||
|
||||
// Set up test container
|
||||
bsu := getBSU()
|
||||
containerURL, _ := createNewContainer(c, bsu)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
// Set up test blob
|
||||
blockBlobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
// Pass the Context, stream, stream size, block blob URL, and options to StreamToBlockBlob
|
||||
response, err := azblob.UploadBufferToBlockBlob(context.Background(), bytesToUpload, blockBlobURL,
|
||||
azblob.UploadToBlockBlobOptions{
|
||||
BlockSize: int64(blockSize),
|
||||
Parallelism: uint16(parallelism),
|
||||
// If Progress is non-nil, this function is called periodically as bytes are uploaded.
|
||||
Progress: func(bytesTransferred int64) {
|
||||
c.Assert(bytesTransferred > 0 && bytesTransferred <= int64(blobSize), chk.Equals, true)
|
||||
},
|
||||
})
|
||||
c.Assert(err, chk.Equals, nil)
|
||||
c.Assert(response.Response().StatusCode, chk.Equals, 201)
|
||||
|
||||
// Set up buffer to download the blob to
|
||||
var destBuffer []byte
|
||||
if downloadCount == azblob.CountToEnd {
|
||||
destBuffer = make([]byte, blobSize - downloadOffset)
|
||||
} else {
|
||||
destBuffer = make([]byte, downloadCount)
|
||||
}
|
||||
|
||||
// Download the blob to a buffer
|
||||
err = azblob.DownloadBlobToBuffer(context.Background(), blockBlobURL.BlobURL, int64(downloadOffset), int64(downloadCount),
|
||||
azblob.BlobAccessConditions{}, destBuffer, azblob.DownloadFromBlobOptions{
|
||||
BlockSize: int64(blockSize),
|
||||
Parallelism: uint16(parallelism),
|
||||
// If Progress is non-nil, this function is called periodically as bytes are uploaded.
|
||||
Progress: func(bytesTransferred int64) {
|
||||
c.Assert(bytesTransferred > 0 && bytesTransferred <= int64(blobSize), chk.Equals, true)
|
||||
},
|
||||
})
|
||||
|
||||
c.Assert(err, chk.Equals, nil)
|
||||
|
||||
if downloadOffset == 0 && downloadCount == 0 {
|
||||
c.Assert(destBuffer, chk.DeepEquals, bytesToUpload)
|
||||
} else {
|
||||
if downloadCount == 0 {
|
||||
c.Assert(destBuffer, chk.DeepEquals, bytesToUpload[downloadOffset:])
|
||||
} else {
|
||||
c.Assert(destBuffer, chk.DeepEquals, bytesToUpload[downloadOffset: downloadOffset + downloadCount])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadAndDownloadBufferInChunks(c *chk.C) {
|
||||
blobSize := 8 * 1024
|
||||
blockSize := 1024
|
||||
parallelism := 3
|
||||
performUploadAndDownloadBufferTest(c, blobSize, blockSize, parallelism, 0, 0)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadAndDownloadBufferSingleIO(c *chk.C) {
|
||||
blobSize := 1024
|
||||
blockSize := 8 * 1024
|
||||
parallelism := 3
|
||||
performUploadAndDownloadBufferTest(c, blobSize, blockSize, parallelism, 0, 0)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadAndDownloadBufferSingleRoutine(c *chk.C) {
|
||||
blobSize := 8 * 1024
|
||||
blockSize := 1024
|
||||
parallelism := 1
|
||||
performUploadAndDownloadBufferTest(c, blobSize, blockSize, parallelism, 0, 0)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestUploadAndDownloadBufferEmpty(c *chk.C) {
|
||||
blobSize := 0
|
||||
blockSize := 1024
|
||||
parallelism := 3
|
||||
performUploadAndDownloadBufferTest(c, blobSize, blockSize, parallelism, 0, 0)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestDownloadBufferWithNonZeroOffset(c *chk.C) {
|
||||
blobSize := 8 * 1024
|
||||
blockSize := 1024
|
||||
parallelism := 3
|
||||
downloadOffset := 1000
|
||||
downloadCount := 0
|
||||
performUploadAndDownloadBufferTest(c, blobSize, blockSize, parallelism, downloadOffset, downloadCount)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestDownloadBufferWithNonZeroCount(c *chk.C) {
|
||||
blobSize := 8 * 1024
|
||||
blockSize := 1024
|
||||
parallelism := 3
|
||||
downloadOffset := 0
|
||||
downloadCount := 6000
|
||||
performUploadAndDownloadBufferTest(c, blobSize, blockSize, parallelism, downloadOffset, downloadCount)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestDownloadBufferWithNonZeroOffsetAndCount(c *chk.C) {
|
||||
blobSize := 8 * 1024
|
||||
blockSize := 1024
|
||||
parallelism := 3
|
||||
downloadOffset := 2000
|
||||
downloadCount := 6 * 1024
|
||||
performUploadAndDownloadBufferTest(c, blobSize, blockSize, parallelism, downloadOffset, downloadCount)
|
||||
}
|
204
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zt_policy_retry_test.go
generated
vendored
204
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zt_policy_retry_test.go
generated
vendored
|
@ -1,204 +0,0 @@
|
|||
package azblob_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
chk "gopkg.in/check.v1"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"github.com/Azure/azure-storage-blob-go/2017-07-29/azblob"
|
||||
)
|
||||
|
||||
// For testing docs, see: https://labix.org/gocheck
|
||||
// To test a specific test: go test -check.f MyTestSuite
|
||||
|
||||
type retryTestScenario int32
|
||||
|
||||
const (
|
||||
// Retry until success. Max reties hit. Operation time out prevents additional retries
|
||||
retryTestScenarioRetryUntilSuccess retryTestScenario = 1
|
||||
retryTestScenarioRetryUntilOperationCancel retryTestScenario = 2
|
||||
retryTestScenarioRetryUntilMaxRetries retryTestScenario = 3
|
||||
)
|
||||
|
||||
func (s *aztestsSuite) TestRetryTestScenarioUntilSuccess(c *chk.C) {
|
||||
testRetryTestScenario(c, retryTestScenarioRetryUntilSuccess)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestRetryTestScenarioUntilOperationCancel(c *chk.C) {
|
||||
testRetryTestScenario(c, retryTestScenarioRetryUntilOperationCancel)
|
||||
}
|
||||
func (s *aztestsSuite) TestRetryTestScenarioUntilMaxRetries(c *chk.C) {
|
||||
testRetryTestScenario(c, retryTestScenarioRetryUntilMaxRetries)
|
||||
}
|
||||
func newRetryTestPolicyFactory(c *chk.C, scenario retryTestScenario, maxRetries int32, cancel context.CancelFunc) *retryTestPolicyFactory {
|
||||
return &retryTestPolicyFactory{c: c, scenario: scenario, maxRetries: maxRetries, cancel: cancel}
|
||||
}
|
||||
|
||||
type retryTestPolicyFactory struct {
|
||||
c *chk.C
|
||||
scenario retryTestScenario
|
||||
maxRetries int32
|
||||
cancel context.CancelFunc
|
||||
try int32
|
||||
}
|
||||
|
||||
func (f *retryTestPolicyFactory) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy {
|
||||
f.try = 0 // Reset this for each test
|
||||
return &retryTestPolicy{factory: f, next: next}
|
||||
}
|
||||
|
||||
type retryTestPolicy struct {
|
||||
next pipeline.Policy
|
||||
factory *retryTestPolicyFactory
|
||||
}
|
||||
|
||||
type retryError struct {
|
||||
temporary, timeout bool
|
||||
}
|
||||
|
||||
func (e *retryError) Temporary() bool { return e.temporary }
|
||||
func (e *retryError) Timeout() bool { return e.timeout }
|
||||
func (e *retryError) Error() string {
|
||||
return fmt.Sprintf("Temporary=%t, Timeout=%t", e.Temporary(), e.Timeout())
|
||||
}
|
||||
|
||||
type httpResponse struct {
|
||||
response *http.Response
|
||||
}
|
||||
|
||||
func (r *httpResponse) Response() *http.Response { return r.response }
|
||||
|
||||
func (p *retryTestPolicy) Do(ctx context.Context, request pipeline.Request) (response pipeline.Response, err error) {
|
||||
c := p.factory.c
|
||||
p.factory.try++ // Increment the try
|
||||
c.Assert(p.factory.try <= p.factory.maxRetries, chk.Equals, true) // Ensure # of tries < MaxRetries
|
||||
req := request.Request
|
||||
|
||||
// Validate the expected pre-conditions for each try
|
||||
expectedHost := "PrimaryDC"
|
||||
if p.factory.try%2 == 0 {
|
||||
if p.factory.scenario != retryTestScenarioRetryUntilSuccess || p.factory.try <= 4 {
|
||||
expectedHost = "SecondaryDC"
|
||||
}
|
||||
}
|
||||
c.Assert(req.URL.Host, chk.Equals, expectedHost) // Ensure we got the expected primary/secondary DC
|
||||
|
||||
// Ensure that any headers & query parameters this method adds (later) are removed/reset for each try
|
||||
c.Assert(req.Header.Get("TestHeader"), chk.Equals, "") // Ensure our "TestHeader" is not in the HTTP request
|
||||
values := req.URL.Query()
|
||||
c.Assert(len(values["TestQueryParam"]), chk.Equals, 0) // TestQueryParam shouldn't be in the HTTP request
|
||||
|
||||
if seeker, ok := req.Body.(io.ReadSeeker); !ok {
|
||||
c.Fail() // Body must be an io.ReadSeeker
|
||||
} else {
|
||||
pos, err := seeker.Seek(0, io.SeekCurrent)
|
||||
c.Assert(err, chk.IsNil) // Ensure that body was seekable
|
||||
c.Assert(pos, chk.Equals, int64(0)) // Ensure body seeked back to position 0
|
||||
}
|
||||
|
||||
// Add a query param & header; these not be here on the next try
|
||||
values["TestQueryParam"] = []string{"TestQueryParamValue"}
|
||||
req.Header.Set("TestHeader", "TestValue") // Add a header this not exist with each try
|
||||
b := []byte{0}
|
||||
n, err := req.Body.Read(b)
|
||||
c.Assert(n, chk.Equals, 1) // Read failed
|
||||
|
||||
switch p.factory.scenario {
|
||||
case retryTestScenarioRetryUntilSuccess:
|
||||
switch p.factory.try {
|
||||
case 1:
|
||||
if deadline, ok := ctx.Deadline(); ok {
|
||||
time.Sleep(time.Until(deadline) + time.Second) // Let the context timeout expire
|
||||
}
|
||||
err = ctx.Err()
|
||||
case 2:
|
||||
err = &retryError{temporary: true}
|
||||
case 3:
|
||||
err = &retryError{timeout: true}
|
||||
case 4:
|
||||
response = &httpResponse{response: &http.Response{StatusCode: http.StatusNotFound}}
|
||||
case 5:
|
||||
err = &retryError{temporary: true} // These attempts all fail but we're making sure we never see the secondary DC again
|
||||
case 6:
|
||||
response = &httpResponse{response: &http.Response{StatusCode: http.StatusOK}} // Stop retries with valid response
|
||||
default:
|
||||
c.Fail() // Retries should have stopped so we shouldn't get here
|
||||
}
|
||||
case retryTestScenarioRetryUntilOperationCancel:
|
||||
switch p.factory.try {
|
||||
case 1:
|
||||
p.factory.cancel()
|
||||
err = context.Canceled
|
||||
default:
|
||||
c.Fail() // Retries should have stopped so we shouldn't get here
|
||||
}
|
||||
case retryTestScenarioRetryUntilMaxRetries:
|
||||
err = &retryError{temporary: true} // Keep retrying until maxRetries is hit
|
||||
}
|
||||
return response, err // Return the response & err
|
||||
}
|
||||
|
||||
func testRetryTestScenario(c *chk.C, scenario retryTestScenario) {
|
||||
u, _ := url.Parse("http://PrimaryDC")
|
||||
retryOptions := azblob.RetryOptions{
|
||||
Policy: azblob.RetryPolicyExponential,
|
||||
MaxTries: 6,
|
||||
TryTimeout: 2 * time.Second,
|
||||
RetryDelay: 1 * time.Second,
|
||||
MaxRetryDelay: 4 * time.Second,
|
||||
RetryReadsFromSecondaryHost: "SecondaryDC",
|
||||
}
|
||||
ctx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(ctx, 64 /*2^MaxTries(6)*/ *retryOptions.TryTimeout)
|
||||
retrytestPolicyFactory := newRetryTestPolicyFactory(c, scenario, retryOptions.MaxTries, cancel)
|
||||
factories := [...]pipeline.Factory{
|
||||
azblob.NewRetryPolicyFactory(retryOptions),
|
||||
retrytestPolicyFactory,
|
||||
}
|
||||
p := pipeline.NewPipeline(factories[:], pipeline.Options{})
|
||||
request, err := pipeline.NewRequest(http.MethodGet, *u, strings.NewReader("TestData"))
|
||||
response, err := p.Do(ctx, nil, request)
|
||||
switch scenario {
|
||||
case retryTestScenarioRetryUntilSuccess:
|
||||
if err != nil || response == nil || response.Response() == nil || response.Response().StatusCode != http.StatusOK {
|
||||
c.Fail() // Operation didn't run to success
|
||||
}
|
||||
case retryTestScenarioRetryUntilMaxRetries:
|
||||
c.Assert(err, chk.NotNil) // Ensure we ended with an error
|
||||
c.Assert(response, chk.IsNil) // Ensure we ended without a valid response
|
||||
c.Assert(retrytestPolicyFactory.try, chk.Equals, retryOptions.MaxTries) // Ensure the operation ends with the exact right number of tries
|
||||
case retryTestScenarioRetryUntilOperationCancel:
|
||||
c.Assert(err, chk.Equals, context.Canceled) // Ensure we ended due to cancellation
|
||||
c.Assert(response, chk.IsNil) // Ensure we ended without a valid response
|
||||
c.Assert(retrytestPolicyFactory.try <= retryOptions.MaxTries, chk.Equals, true) // Ensure we didn't end due to reaching max tries
|
||||
}
|
||||
cancel()
|
||||
}
|
||||
|
||||
/*
|
||||
Fail primary; retry should be on secondary URL - maybe do this twice
|
||||
Fail secondary; and never see primary again
|
||||
|
||||
Make sure any mutations are lost on each retry
|
||||
Make sure body is reset on each retry
|
||||
|
||||
Timeout a try; should retry (unless no more)
|
||||
timeout an operation; should not retry
|
||||
check timeout query param; should be try timeout
|
||||
|
||||
Return Temporary() = true; should retry (unless max)
|
||||
Return Timeout() true; should retry (unless max)
|
||||
|
||||
Secondary try returns 404; no more tries against secondary
|
||||
|
||||
error where Temporary() and Timeout() return false; no retry
|
||||
error where Temporary() & Timeout don't exist; no retry
|
||||
no error; no retry; return success, nil
|
||||
*/
|
201
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zt_retry_reader_test.go
generated
vendored
201
vendor/github.com/Azure/azure-storage-blob-go/2017-07-29/azblob/zt_retry_reader_test.go
generated
vendored
|
@ -1,201 +0,0 @@
|
|||
package azblob_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
chk "gopkg.in/check.v1"
|
||||
"github.com/Azure/azure-storage-blob-go/2017-07-29/azblob"
|
||||
)
|
||||
|
||||
// Testings for RetryReader
|
||||
// This reader return one byte through each Read call
|
||||
type perByteReader struct {
|
||||
RandomBytes []byte // Random generated bytes
|
||||
|
||||
byteCount int // Bytes can be returned before EOF
|
||||
currentByteIndex int // Bytes that have already been returned.
|
||||
doInjectError bool
|
||||
doInjectErrorByteIndex int
|
||||
doInjectTimes int
|
||||
injectedError error
|
||||
}
|
||||
|
||||
func newPerByteReader(byteCount int) *perByteReader {
|
||||
perByteReader := perByteReader{
|
||||
byteCount: byteCount,
|
||||
}
|
||||
|
||||
perByteReader.RandomBytes = make([]byte, byteCount)
|
||||
rand.Read(perByteReader.RandomBytes)
|
||||
|
||||
return &perByteReader
|
||||
}
|
||||
|
||||
func (r *perByteReader) Read(b []byte) (n int, err error) {
|
||||
if r.doInjectError && r.doInjectErrorByteIndex == r.currentByteIndex && r.doInjectTimes > 0 {
|
||||
r.doInjectTimes--
|
||||
return 0, r.injectedError
|
||||
}
|
||||
|
||||
if r.currentByteIndex < r.byteCount {
|
||||
n = copy(b, r.RandomBytes[r.currentByteIndex:r.currentByteIndex+1])
|
||||
r.currentByteIndex += n
|
||||
return
|
||||
}
|
||||
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
func (r *perByteReader) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Test normal retry succeed, note initial response not provided.
|
||||
func (r *aztestsSuite) TestRetryReaderReadWithRetry(c *chk.C) {
|
||||
byteCount := 1
|
||||
body := newPerByteReader(byteCount)
|
||||
body.doInjectError = true
|
||||
body.doInjectErrorByteIndex = 0
|
||||
body.doInjectTimes = 1
|
||||
body.injectedError = &net.DNSError{IsTemporary: true}
|
||||
|
||||
getter := func(ctx context.Context, info azblob.HTTPGetterInfo) (*http.Response, error) {
|
||||
r := http.Response{}
|
||||
body.currentByteIndex = int(info.Offset)
|
||||
r.Body = body
|
||||
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
httpGetterInfo := azblob.HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}
|
||||
initResponse, err := getter(context.Background(), httpGetterInfo)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
retryReader := azblob.NewRetryReader(context.Background(), initResponse, httpGetterInfo, azblob.RetryReaderOptions{MaxRetryRequests: 1}, getter)
|
||||
|
||||
// should fail and succeed through retry
|
||||
can := make([]byte, 1)
|
||||
n, err := retryReader.Read(can)
|
||||
c.Assert(n, chk.Equals, 1)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
// should return EOF
|
||||
n, err = retryReader.Read(can)
|
||||
c.Assert(n, chk.Equals, 0)
|
||||
c.Assert(err, chk.Equals, io.EOF)
|
||||
}
|
||||
|
||||
// Test normal retry fail as retry Count not enough.
|
||||
func (r *aztestsSuite) TestRetryReaderReadNegativeNormalFail(c *chk.C) {
|
||||
byteCount := 1
|
||||
body := newPerByteReader(byteCount)
|
||||
body.doInjectError = true
|
||||
body.doInjectErrorByteIndex = 0
|
||||
body.doInjectTimes = 2
|
||||
body.injectedError = &net.DNSError{IsTemporary: true}
|
||||
|
||||
startResponse := http.Response{}
|
||||
startResponse.Body = body
|
||||
|
||||
getter := func(ctx context.Context, info azblob.HTTPGetterInfo) (*http.Response, error) {
|
||||
r := http.Response{}
|
||||
body.currentByteIndex = int(info.Offset)
|
||||
r.Body = body
|
||||
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
retryReader := azblob.NewRetryReader(context.Background(), &startResponse, azblob.HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}, azblob.RetryReaderOptions{MaxRetryRequests: 1}, getter)
|
||||
|
||||
// should fail
|
||||
can := make([]byte, 1)
|
||||
n, err := retryReader.Read(can)
|
||||
c.Assert(n, chk.Equals, 0)
|
||||
c.Assert(err, chk.Equals, body.injectedError)
|
||||
}
|
||||
|
||||
// Test boundary case when Count equals to 0 and fail.
|
||||
func (r *aztestsSuite) TestRetryReaderReadCount0(c *chk.C) {
|
||||
byteCount := 1
|
||||
body := newPerByteReader(byteCount)
|
||||
body.doInjectError = true
|
||||
body.doInjectErrorByteIndex = 1
|
||||
body.doInjectTimes = 1
|
||||
body.injectedError = &net.DNSError{IsTemporary: true}
|
||||
|
||||
startResponse := http.Response{}
|
||||
startResponse.Body = body
|
||||
|
||||
getter := func(ctx context.Context, info azblob.HTTPGetterInfo) (*http.Response, error) {
|
||||
r := http.Response{}
|
||||
body.currentByteIndex = int(info.Offset)
|
||||
r.Body = body
|
||||
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
retryReader := azblob.NewRetryReader(context.Background(), &startResponse, azblob.HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}, azblob.RetryReaderOptions{MaxRetryRequests: 1}, getter)
|
||||
|
||||
// should consume the only byte
|
||||
can := make([]byte, 1)
|
||||
n, err := retryReader.Read(can)
|
||||
c.Assert(n, chk.Equals, 1)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
// should not read when Count=0, and should return EOF
|
||||
n, err = retryReader.Read(can)
|
||||
c.Assert(n, chk.Equals, 0)
|
||||
c.Assert(err, chk.Equals, io.EOF)
|
||||
}
|
||||
|
||||
func (r *aztestsSuite) TestRetryReaderReadNegativeNonRetriableError(c *chk.C) {
|
||||
byteCount := 1
|
||||
body := newPerByteReader(byteCount)
|
||||
body.doInjectError = true
|
||||
body.doInjectErrorByteIndex = 0
|
||||
body.doInjectTimes = 1
|
||||
body.injectedError = fmt.Errorf("not retriable error")
|
||||
|
||||
startResponse := http.Response{}
|
||||
startResponse.Body = body
|
||||
|
||||
getter := func(ctx context.Context, info azblob.HTTPGetterInfo) (*http.Response, error) {
|
||||
r := http.Response{}
|
||||
body.currentByteIndex = int(info.Offset)
|
||||
r.Body = body
|
||||
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
retryReader := azblob.NewRetryReader(context.Background(), &startResponse, azblob.HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}, azblob.RetryReaderOptions{MaxRetryRequests: 2}, getter)
|
||||
|
||||
dest := make([]byte, 1)
|
||||
_, err := retryReader.Read(dest)
|
||||
c.Assert(err, chk.Equals, body.injectedError)
|
||||
}
|
||||
|
||||
func (r *aztestsSuite) TestRetryReaderNewRetryReaderDefaultNegativePanic(c *chk.C) {
|
||||
startResponse := http.Response{}
|
||||
|
||||
// Check getter
|
||||
c.Assert(func() { _ = azblob.NewRetryReader(context.Background(), &startResponse, azblob.HTTPGetterInfo{}, azblob.RetryReaderOptions{}, nil) }, chk.Panics, "getter must not be nil")
|
||||
|
||||
getter := func(ctx context.Context, info azblob.HTTPGetterInfo) (*http.Response, error) { return nil, nil }
|
||||
// Check info.Count
|
||||
c.Assert(func() {
|
||||
_ = azblob.NewRetryReader(context.Background(), &startResponse, azblob.HTTPGetterInfo{Count: -1}, azblob.RetryReaderOptions{}, getter)
|
||||
}, chk.Panics, "info.Count must be >= 0")
|
||||
|
||||
// Check o.MaxRetryRequests
|
||||
c.Assert(func() {
|
||||
_ = azblob.NewRetryReader(context.Background(), &startResponse, azblob.HTTPGetterInfo{}, azblob.RetryReaderOptions{MaxRetryRequests: -1}, getter)
|
||||
}, chk.Panics, "o.MaxRetryRequests must be >= 0")
|
||||
|
||||
}
|
||||
|
||||
// End testings for RetryReader
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue