vendor: update to latest versions of everything

This commit is contained in:
Nick Craig-Wood 2018-10-25 16:35:30 +01:00
parent c0ca93ae6f
commit c514cb752d
240 changed files with 21602 additions and 15254 deletions

View file

@ -32,6 +32,21 @@ Early in the next release cycle update the vendored dependencies
* git add new files * git add new files
* git commit -a -v * git commit -a -v
If `make update` fails with errors like this:
```
# github.com/cpuguy83/go-md2man/md2man
../../../../pkg/mod/github.com/cpuguy83/go-md2man@v1.0.8/md2man/md2man.go:11:16: undefined: blackfriday.EXTENSION_NO_INTRA_EMPHASIS
../../../../pkg/mod/github.com/cpuguy83/go-md2man@v1.0.8/md2man/md2man.go:12:16: undefined: blackfriday.EXTENSION_TABLES
```
Can be fixed with
* GO111MODULE=on go get -u github.com/russross/blackfriday@v1.5.2
* GO111MODULE=on go mod tidy
* GO111MODULE=on go mod vendor
Making a point release. If rclone needs a point release due to some Making a point release. If rclone needs a point release due to some
horrendous bug, then horrendous bug, then
* git branch v1.XX v1.XX-fixes * git branch v1.XX v1.XX-fixes

View file

@ -22,7 +22,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/Azure/azure-storage-blob-go/2018-03-28/azblob" "github.com/Azure/azure-storage-blob-go/azblob"
"github.com/ncw/rclone/fs" "github.com/ncw/rclone/fs"
"github.com/ncw/rclone/fs/accounting" "github.com/ncw/rclone/fs/accounting"
"github.com/ncw/rclone/fs/config/configmap" "github.com/ncw/rclone/fs/config/configmap"
@ -1368,7 +1368,7 @@ func (o *Object) SetTier(tier string) error {
blob := o.getBlobReference() blob := o.getBlobReference()
ctx := context.Background() ctx := context.Background()
err := o.fs.pacer.Call(func() (bool, error) { err := o.fs.pacer.Call(func() (bool, error) {
_, err := blob.SetTier(ctx, desiredAccessTier) _, err := blob.SetTier(ctx, desiredAccessTier, azblob.LeaseAccessConditions{})
return o.fs.shouldRetry(err) return o.fs.shouldRetry(err)
}) })

33
go.mod
View file

@ -2,27 +2,25 @@ module github.com/ncw/rclone
require ( require (
bazil.org/fuse v0.0.0-20180421153158-65cc252bf669 bazil.org/fuse v0.0.0-20180421153158-65cc252bf669
cloud.google.com/go v0.28.0 // indirect cloud.google.com/go v0.31.0 // indirect
github.com/Azure/azure-pipeline-go v0.1.8 // indirect github.com/Azure/azure-storage-blob-go v0.0.0-20181023070848-cf01652132cc
github.com/Azure/azure-storage-blob-go v0.0.0-20180906215025-bb46532f68b7
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78
github.com/Unknwon/goconfig v0.0.0-20180308125533-ef1e4c783f8f github.com/Unknwon/goconfig v0.0.0-20180308125533-ef1e4c783f8f
github.com/a8m/tree v0.0.0-20180321023834-3cf936ce15d6 github.com/a8m/tree v0.0.0-20180321023834-3cf936ce15d6
github.com/abbot/go-http-auth v0.4.0 github.com/abbot/go-http-auth v0.4.0
github.com/aws/aws-sdk-go v1.15.39 github.com/aws/aws-sdk-go v1.15.62
github.com/billziss-gh/cgofuse v1.1.0 github.com/billziss-gh/cgofuse v1.1.0
github.com/coreos/bbolt v0.0.0-20180318001526-af9db2027c98 github.com/coreos/bbolt v0.0.0-20180318001526-af9db2027c98
github.com/cpuguy83/go-md2man v1.0.8 // indirect github.com/cpuguy83/go-md2man v1.0.8 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/djherbis/times v1.0.1 github.com/djherbis/times v1.0.1
github.com/dropbox/dropbox-sdk-go-unofficial v4.1.0+incompatible github.com/dropbox/dropbox-sdk-go-unofficial v4.1.0+incompatible
github.com/go-ini/ini v1.38.2 // indirect
github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9 // indirect github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9 // indirect
github.com/goftp/server v0.0.0-20180914132916-1fd52c8552f1 github.com/goftp/server v0.0.0-20180914132916-1fd52c8552f1
github.com/google/go-querystring v1.0.0 // indirect github.com/google/go-querystring v1.0.0 // indirect
github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c // indirect github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jlaffaye/ftp v0.0.0-20180808211605-3f6433f7eae3 github.com/jlaffaye/ftp v0.0.0-20181011150954-fe787349a520
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
github.com/jtolds/gls v4.2.1+incompatible // indirect github.com/jtolds/gls v4.2.1+incompatible // indirect
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 // indirect github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 // indirect
@ -30,7 +28,7 @@ require (
github.com/kr/pretty v0.1.0 // indirect github.com/kr/pretty v0.1.0 // indirect
github.com/mattn/go-runewidth v0.0.3 // indirect github.com/mattn/go-runewidth v0.0.3 // indirect
github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2 github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2
github.com/ncw/swift v1.0.41 github.com/ncw/swift v1.0.42
github.com/nsf/termbox-go v0.0.0-20180819125858-b66b20ab708e github.com/nsf/termbox-go v0.0.0-20180819125858-b66b20ab708e
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
@ -39,27 +37,26 @@ require (
github.com/pkg/sftp v1.8.3 github.com/pkg/sftp v1.8.3
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46 github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46
github.com/russross/blackfriday v1.5.1 // indirect github.com/russross/blackfriday v1.5.2 // indirect
github.com/sevlyar/go-daemon v0.1.4 github.com/sevlyar/go-daemon v0.1.4
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c
github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf // indirect github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a // indirect github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a // indirect
github.com/spf13/cobra v0.0.3 github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.2 github.com/spf13/pflag v1.0.3
github.com/stretchr/testify v1.2.2 github.com/stretchr/testify v1.2.2
github.com/t3rm1n4l/go-mega v0.0.0-20180817194457-854bf31d998b github.com/t3rm1n4l/go-mega v0.0.0-20180817194457-854bf31d998b
github.com/xanzy/ssh-agent v0.2.0 github.com/xanzy/ssh-agent v0.2.0
github.com/yunify/qingstor-sdk-go v2.2.15+incompatible github.com/yunify/qingstor-sdk-go v2.2.15+incompatible
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b golang.org/x/crypto v0.0.0-20181025113841-85e1b3f9139a
golang.org/x/net v0.0.0-20180921000356-2f5d2388922f golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f // indirect golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f // indirect
golang.org/x/sys v0.0.0-20180920110915-d641721ec2de golang.org/x/sys v0.0.0-20181025063200-d989b31c8746
golang.org/x/text v0.3.0 golang.org/x/text v0.3.0
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2
google.golang.org/api v0.0.0-20180921000521-920bb1beccf7 google.golang.org/api v0.0.0-20181025000501-39567f0042a0
google.golang.org/appengine v1.2.0 // indirect google.golang.org/appengine v1.2.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/ini.v1 v1.38.2 // indirect gopkg.in/yaml.v2 v2.2.1
gopkg.in/yaml.v2 v2.2.1 // indirect
) )

62
go.sum
View file

@ -1,11 +1,11 @@
bazil.org/fuse v0.0.0-20180421153158-65cc252bf669 h1:FNCRpXiquG1aoyqcIWVFmpTSKVcx2bQD38uZZeGtdlw= bazil.org/fuse v0.0.0-20180421153158-65cc252bf669 h1:FNCRpXiquG1aoyqcIWVFmpTSKVcx2bQD38uZZeGtdlw=
bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
cloud.google.com/go v0.28.0 h1:KZ/88LWSw8NxMkjdQyX7LQSGR9PkHr4PaVuNm8zgFq0= cloud.google.com/go v0.31.0 h1:o9K5MWWt2wk+d9jkGn2DAZ7Q9nUdnFLOpK9eIkDwONQ=
cloud.google.com/go v0.28.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/Azure/azure-pipeline-go v0.1.8 h1:KmVRa8oFMaargVesEuuEoiLCQ4zCCwQ8QX/xg++KS20= github.com/Azure/azure-pipeline-go v0.1.8 h1:KmVRa8oFMaargVesEuuEoiLCQ4zCCwQ8QX/xg++KS20=
github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
github.com/Azure/azure-storage-blob-go v0.0.0-20180906215025-bb46532f68b7 h1:/dp3cg/uwEn3nCIvapCpvwMLMCW34Z9U/UOeTroS6p0= github.com/Azure/azure-storage-blob-go v0.0.0-20181023070848-cf01652132cc h1:BElWmFfsryQD72OcovStKpkIcd4e9ozSkdsTNQDSHGk=
github.com/Azure/azure-storage-blob-go v0.0.0-20180906215025-bb46532f68b7/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY= github.com/Azure/azure-storage-blob-go v0.0.0-20181023070848-cf01652132cc/go.mod h1:oGfmITT1V6x//CswqY2gtAHND+xIP64/qL7a5QJix0Y=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Unknwon/goconfig v0.0.0-20180308125533-ef1e4c783f8f h1:2h0zBHX3qNDltgnb2FiMJWYTcqJVDdUeHQU2/5CTc5w= github.com/Unknwon/goconfig v0.0.0-20180308125533-ef1e4c783f8f h1:2h0zBHX3qNDltgnb2FiMJWYTcqJVDdUeHQU2/5CTc5w=
@ -14,8 +14,8 @@ github.com/a8m/tree v0.0.0-20180321023834-3cf936ce15d6 h1:UCQe3W9LxwL2ff5r0PqQfS
github.com/a8m/tree v0.0.0-20180321023834-3cf936ce15d6/go.mod h1:FSdwKX97koS5efgm8WevNf7XS3PqtyFkKDDXrz778cg= github.com/a8m/tree v0.0.0-20180321023834-3cf936ce15d6/go.mod h1:FSdwKX97koS5efgm8WevNf7XS3PqtyFkKDDXrz778cg=
github.com/abbot/go-http-auth v0.4.0 h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0= github.com/abbot/go-http-auth v0.4.0 h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0=
github.com/abbot/go-http-auth v0.4.0/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM= github.com/abbot/go-http-auth v0.4.0/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM=
github.com/aws/aws-sdk-go v1.15.39 h1:MUxm375zGxxVhgL5NNCIDuwn4SkMQsX8CQWD+zLULcw= github.com/aws/aws-sdk-go v1.15.62 h1:07s1rZRzXJWlrTvHR8ZZb6DjoQTFnxqraE7y5teA8Og=
github.com/aws/aws-sdk-go v1.15.39/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.15.62/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
github.com/billziss-gh/cgofuse v1.1.0 h1:tATn9ZDvuPcOVlvR4tJitGHgAqy1y18+4mKmRfdfjec= github.com/billziss-gh/cgofuse v1.1.0 h1:tATn9ZDvuPcOVlvR4tJitGHgAqy1y18+4mKmRfdfjec=
github.com/billziss-gh/cgofuse v1.1.0/go.mod h1:LJjoaUojlVjgo5GQoEJTcJNqZJeRU0nCR84CyxKt2YM= github.com/billziss-gh/cgofuse v1.1.0/go.mod h1:LJjoaUojlVjgo5GQoEJTcJNqZJeRU0nCR84CyxKt2YM=
github.com/coreos/bbolt v0.0.0-20180318001526-af9db2027c98 h1:0gQU5Ebjs1V8Ow5bBzxZzr0peNjJILSkSb30IfZtshQ= github.com/coreos/bbolt v0.0.0-20180318001526-af9db2027c98 h1:0gQU5Ebjs1V8Ow5bBzxZzr0peNjJILSkSb30IfZtshQ=
@ -28,9 +28,6 @@ github.com/djherbis/times v1.0.1 h1:nVRrVOTFd2r0C7wCQdIDz/fqt8yO0EEzr5f6aXfXiS0=
github.com/djherbis/times v1.0.1/go.mod h1:CGMZlo255K5r4Yw0b9RRfFQpM2y7uOmxg4jm9HsaVf8= github.com/djherbis/times v1.0.1/go.mod h1:CGMZlo255K5r4Yw0b9RRfFQpM2y7uOmxg4jm9HsaVf8=
github.com/dropbox/dropbox-sdk-go-unofficial v4.1.0+incompatible h1:ZFvUIiBbGhDY5zF8yjLoWhUAYs7uDodUpbvTS5oelDE= github.com/dropbox/dropbox-sdk-go-unofficial v4.1.0+incompatible h1:ZFvUIiBbGhDY5zF8yjLoWhUAYs7uDodUpbvTS5oelDE=
github.com/dropbox/dropbox-sdk-go-unofficial v4.1.0+incompatible/go.mod h1:lr+LhMM3F6Y3lW1T9j2U5l7QeuWm87N9+PPXo3yH4qY= github.com/dropbox/dropbox-sdk-go-unofficial v4.1.0+incompatible/go.mod h1:lr+LhMM3F6Y3lW1T9j2U5l7QeuWm87N9+PPXo3yH4qY=
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-ini/ini v1.38.2 h1:6Hl/z3p3iFkA0dlDfzYxuFuUGD+kaweypF6btsR2/Q4=
github.com/go-ini/ini v1.38.2/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9 h1:cC0Hbb+18DJ4i6ybqDybvj4wdIDS4vnD0QEci98PgM8= github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9 h1:cC0Hbb+18DJ4i6ybqDybvj4wdIDS4vnD0QEci98PgM8=
github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9/go.mod h1:GpOj6zuVBG3Inr9qjEnuVTgBlk2lZ1S9DcoFiXWyKss= github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9/go.mod h1:GpOj6zuVBG3Inr9qjEnuVTgBlk2lZ1S9DcoFiXWyKss=
github.com/goftp/server v0.0.0-20180914132916-1fd52c8552f1 h1:WjgeEHEDLGx56ndxS6FYi6qFjZGajSVHPuEPdpJ60cI= github.com/goftp/server v0.0.0-20180914132916-1fd52c8552f1 h1:WjgeEHEDLGx56ndxS6FYi6qFjZGajSVHPuEPdpJ60cI=
@ -39,12 +36,12 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c h1:16eHWuMGvCjSfgRJKqIzapE78onvvTbdi1rMkU00lZw= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jlaffaye/ftp v0.0.0-20180808211605-3f6433f7eae3 h1:UHMAxHSQqPxQi/55JSaFYbV0eqjoxlT9NYTS2AuGklQ= github.com/jlaffaye/ftp v0.0.0-20181011150954-fe787349a520 h1:VFHAQNYcjE5grUH5XOA6NPRFURBIcVt4A6R9G4fwH5c=
github.com/jlaffaye/ftp v0.0.0-20180808211605-3f6433f7eae3/go.mod h1:lli8NYPQOFy3O++YmYbqVgOcQ1JPCwdOy+5zSjKJ9qY= github.com/jlaffaye/ftp v0.0.0-20181011150954-fe787349a520/go.mod h1:lli8NYPQOFy3O++YmYbqVgOcQ1JPCwdOy+5zSjKJ9qY=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
@ -64,8 +61,8 @@ github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8Bz
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2 h1:VlXvEx6JbFp7F9iz92zXP2Ew+9VupSpfybr+TxmjdH0= github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2 h1:VlXvEx6JbFp7F9iz92zXP2Ew+9VupSpfybr+TxmjdH0=
github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2/go.mod h1:MLIrzg7gp/kzVBxRE1olT7CWYMCklcUWU+ekoxOD9x0= github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2/go.mod h1:MLIrzg7gp/kzVBxRE1olT7CWYMCklcUWU+ekoxOD9x0=
github.com/ncw/swift v1.0.41 h1:kfoTVQKt1A4n0m1Q3YWku9OoXfpo06biqVfi73yseBs= github.com/ncw/swift v1.0.42 h1:ztvRb6hs52IHOcaYt73f9lXYLIeIuWgdooRDhdyllGI=
github.com/ncw/swift v1.0.41/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/ncw/swift v1.0.42/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
github.com/nsf/termbox-go v0.0.0-20180819125858-b66b20ab708e h1:fvw0uluMptljaRKSU8459cJ4bmi3qUYyMs5kzpic2fY= github.com/nsf/termbox-go v0.0.0-20180819125858-b66b20ab708e h1:fvw0uluMptljaRKSU8459cJ4bmi3qUYyMs5kzpic2fY=
github.com/nsf/termbox-go v0.0.0-20180819125858-b66b20ab708e/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= github.com/nsf/termbox-go v0.0.0-20180819125858-b66b20ab708e/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd h1:+iAPaTbi1gZpcpDwe/BW1fx7Xoesv69hLNGPheoyhBs= github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd h1:+iAPaTbi1gZpcpDwe/BW1fx7Xoesv69hLNGPheoyhBs=
@ -82,20 +79,20 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46 h1:w2CpS5muK+jyydnmlkqpAhzKmHmMBzBkfYUDjQNS1Dk= github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46 h1:w2CpS5muK+jyydnmlkqpAhzKmHmMBzBkfYUDjQNS1Dk=
github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46/go.mod h1:U2bmx0hDj8EyDdcxmD5t3XHDnBFnyNNc22n1R4008eM= github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46/go.mod h1:U2bmx0hDj8EyDdcxmD5t3XHDnBFnyNNc22n1R4008eM=
github.com/russross/blackfriday v1.5.1 h1:B8ZN6pD4PVofmlDCDUdELeYrbsVIDM/bpjW3v3zgcRc= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.1/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sevlyar/go-daemon v0.1.4 h1:Ayxp/9SNHwPBjV+kKbnHl2ch6rhxTu08jfkGkoxgULQ= github.com/sevlyar/go-daemon v0.1.4 h1:Ayxp/9SNHwPBjV+kKbnHl2ch6rhxTu08jfkGkoxgULQ=
github.com/sevlyar/go-daemon v0.1.4/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE= github.com/sevlyar/go-daemon v0.1.4/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE=
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c h1:fyKiXKO1/I/B6Y2U8T7WdQGWzwehOuGIrljPtt7YTTI= github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c h1:fyKiXKO1/I/B6Y2U8T7WdQGWzwehOuGIrljPtt7YTTI=
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf h1:6V1qxN6Usn4jy8unvggSJz/NC790tefw8Zdy6OZS5co= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a h1:JSvGDIbmil4Ui/dDdFBExb7/cmkNjyX5F97oglmvCDo= github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a h1:JSvGDIbmil4Ui/dDdFBExb7/cmkNjyX5F97oglmvCDo=
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.2 h1:Fy0orTDgHdbnzHcsOgfCN4LtHf0ec3wwtiwJqwvf3Gc= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/t3rm1n4l/go-mega v0.0.0-20180817194457-854bf31d998b h1:Yt/fB2INfWb29Vcya4X0BNCLmObKmDdt0o0IndFzEY8= github.com/t3rm1n4l/go-mega v0.0.0-20180817194457-854bf31d998b h1:Yt/fB2INfWb29Vcya4X0BNCLmObKmDdt0o0IndFzEY8=
@ -104,30 +101,29 @@ github.com/xanzy/ssh-agent v0.2.0 h1:Adglfbi5p9Z0BmK2oKU9nTG+zKfniSfnaMYB+ULd+Ro
github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8= github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8=
github.com/yunify/qingstor-sdk-go v2.2.15+incompatible h1:/Z0q3/eSMoPYAuRmhjWtuGSmVVciFC6hfm3yfCKuvz0= github.com/yunify/qingstor-sdk-go v2.2.15+incompatible h1:/Z0q3/eSMoPYAuRmhjWtuGSmVVciFC6hfm3yfCKuvz0=
github.com/yunify/qingstor-sdk-go v2.2.15+incompatible/go.mod h1:w6wqLDQ5bBTzxGJ55581UrSwLrsTAsdo9N6yX/8d9RY= github.com/yunify/qingstor-sdk-go v2.2.15+incompatible/go.mod h1:w6wqLDQ5bBTzxGJ55581UrSwLrsTAsdo9N6yX/8d9RY=
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b h1:2b9XGzhjiYsYPnKXoEfL7klWZQIt8IfyRCz62gCqqlQ= golang.org/x/crypto v0.0.0-20181025113841-85e1b3f9139a h1:Pg1/+l4/QV6z7N506eGnLiJ/Rl4IJf1FwYQKvP51OjA=
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181025113841-85e1b3f9139a/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180921000356-2f5d2388922f h1:QM2QVxvDoW9PFSPp/zy9FgxJLfaWTZlS61KEPtBwacM= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519 h1:x6rhz8Y9CjbgQkccRGmELH6K+LJj7tOoh3XWeC1yaQM=
golang.org/x/net v0.0.0-20180921000356-2f5d2388922f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4 h1:99CA0JJbUX4ozCnLon680Jc9e0T1i8HCaLVJMwtI8Hc=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180920110915-d641721ec2de h1:soC2mvPVpAV+Ld2qtpNn1eq25WTn76uIGNV23bofu6Q= golang.org/x/sys v0.0.0-20181025063200-d989b31c8746 h1:zTiiIq2XH/ldZGPA59ILL7NbDlz/btn3iJvO7H57mY8=
golang.org/x/sys v0.0.0-20180920110915-d641721ec2de/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181025063200-d989b31c8746/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 h1:+DCIGbF/swA92ohVg0//6X2IVY3KZs6p9mix0ziNYJM= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 h1:+DCIGbF/swA92ohVg0//6X2IVY3KZs6p9mix0ziNYJM=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
google.golang.org/api v0.0.0-20180921000521-920bb1beccf7 h1:XKT3Wlpn+o6Car1ot74Z4R+R9CeRfITCLZb0Q9/mpx4= google.golang.org/api v0.0.0-20181025000501-39567f0042a0 h1:6a8YRrm+EJS4Y9FGTkLfE2iKneLzRQG5CfJCfJ9AfS0=
google.golang.org/api v0.0.0-20180921000521-920bb1beccf7/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181025000501-39567f0042a0/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/appengine v1.2.0 h1:S0iUepdCWODXRvtE+gcRDd15L+k+k1AiHlMiMjefH24= google.golang.org/appengine v1.2.0 h1:S0iUepdCWODXRvtE+gcRDd15L+k+k1AiHlMiMjefH24=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/ini.v1 v1.38.2 h1:dGcbywv4RufeGeiMycPT/plKB5FtmLKLnWKwBiLhUA4=
gopkg.in/ini.v1 v1.38.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View file

@ -1,3 +0,0 @@
package azblob
const serviceLibVersion = "0.1"

View file

@ -11,9 +11,6 @@ const targetAndMorpherMustNotBeNil = "target and morpher must not be nil"
// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function. // AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function.
func atomicMorphInt32(target *int32, morpher atomicMorpherInt32) interface{} { func atomicMorphInt32(target *int32, morpher atomicMorpherInt32) interface{} {
if target == nil || morpher == nil {
panic(targetAndMorpherMustNotBeNil)
}
for { for {
currentVal := atomic.LoadInt32(target) currentVal := atomic.LoadInt32(target)
desiredVal, morphResult := morpher(currentVal) desiredVal, morphResult := morpher(currentVal)
@ -30,9 +27,6 @@ type atomicMorpherUint32 func(startVal uint32) (val uint32, morphResult interfac
// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function. // AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function.
func atomicMorphUint32(target *uint32, morpher atomicMorpherUint32) interface{} { func atomicMorphUint32(target *uint32, morpher atomicMorpherUint32) interface{} {
if target == nil || morpher == nil {
panic(targetAndMorpherMustNotBeNil)
}
for { for {
currentVal := atomic.LoadUint32(target) currentVal := atomic.LoadUint32(target)
desiredVal, morphResult := morpher(currentVal) desiredVal, morphResult := morpher(currentVal)
@ -49,9 +43,6 @@ 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. // AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function.
func atomicMorphInt64(target *int64, morpher atomicMorpherInt64) interface{} { func atomicMorphInt64(target *int64, morpher atomicMorpherInt64) interface{} {
if target == nil || morpher == nil {
panic(targetAndMorpherMustNotBeNil)
}
for { for {
currentVal := atomic.LoadInt64(target) currentVal := atomic.LoadInt64(target)
desiredVal, morphResult := morpher(currentVal) desiredVal, morphResult := morpher(currentVal)
@ -68,9 +59,6 @@ type atomicMorpherUint64 func(startVal uint64) (val uint64, morphResult interfac
// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function. // AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function.
func atomicMorphUint64(target *uint64, morpher atomicMorpherUint64) interface{} { func atomicMorphUint64(target *uint64, morpher atomicMorpherUint64) interface{} {
if target == nil || morpher == nil {
panic(targetAndMorpherMustNotBeNil)
}
for { for {
currentVal := atomic.LoadUint64(target) currentVal := atomic.LoadUint64(target)
desiredVal, morphResult := morpher(currentVal) desiredVal, morphResult := morpher(currentVal)

View file

@ -3,7 +3,6 @@ package azblob
import ( import (
"context" "context"
"encoding/base64" "encoding/base64"
"fmt"
"io" "io"
"net/http" "net/http"
@ -63,12 +62,6 @@ type UploadToBlockBlobOptions struct {
// UploadBufferToBlockBlob uploads a buffer in blocks to a block blob. // UploadBufferToBlockBlob uploads a buffer in blocks to a block blob.
func UploadBufferToBlockBlob(ctx context.Context, b []byte, func UploadBufferToBlockBlob(ctx context.Context, b []byte,
blockBlobURL BlockBlobURL, o UploadToBlockBlobOptions) (CommonResponse, error) { 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))
}
bufferSize := int64(len(b)) bufferSize := int64(len(b))
if o.BlockSize == 0 { if o.BlockSize == 0 {
// If bufferSize > (BlockBlobMaxStageBlockBytes * BlockBlobMaxBlocks), then error // If bufferSize > (BlockBlobMaxStageBlockBytes * BlockBlobMaxBlocks), then error
@ -97,9 +90,6 @@ func UploadBufferToBlockBlob(ctx context.Context, b []byte,
} }
var numBlocks = uint16(((bufferSize - 1) / o.BlockSize) + 1) var numBlocks = uint16(((bufferSize - 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 blockIDList := make([]string, numBlocks) // Base-64 encoded block IDs
progress := int64(0) progress := int64(0)
@ -187,22 +177,10 @@ type DownloadFromBlobOptions struct {
// downloadBlobToBuffer downloads an Azure blob to a buffer with parallel. // downloadBlobToBuffer downloads an Azure blob to a buffer with parallel.
func downloadBlobToBuffer(ctx context.Context, blobURL BlobURL, offset int64, count int64, func downloadBlobToBuffer(ctx context.Context, blobURL BlobURL, offset int64, count int64,
b []byte, o DownloadFromBlobOptions, initialDownloadResponse *DownloadResponse) error { 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 { if o.BlockSize == 0 {
o.BlockSize = BlobDefaultDownloadBlockSize 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 count == CountToEnd { // If size not specified, calculate it
if initialDownloadResponse != nil { if initialDownloadResponse != nil {
count = initialDownloadResponse.ContentLength() - offset // if we have the length, use it count = initialDownloadResponse.ContentLength() - offset // if we have the length, use it
@ -216,10 +194,6 @@ func downloadBlobToBuffer(ctx context.Context, blobURL BlobURL, offset int64, co
} }
} }
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. // Prepare and do parallel download.
progress := int64(0) progress := int64(0)
progressLock := &sync.Mutex{} progressLock := &sync.Mutex{}
@ -268,12 +242,7 @@ func DownloadBlobToBuffer(ctx context.Context, blobURL BlobURL, offset int64, co
// Offset and count are optional, pass 0 for both to download the entire blob. // 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, func DownloadBlobToFile(ctx context.Context, blobURL BlobURL, offset int64, count int64,
file *os.File, o DownloadFromBlobOptions) error { file *os.File, o DownloadFromBlobOptions) error {
// 1. Validate parameters. // 1. Calculate the size of the destination file
if file == nil {
panic("file must not be nil")
}
// 2. Calculate the size of the destination file
var size int64 var size int64
if count == CountToEnd { if count == CountToEnd {
@ -287,7 +256,7 @@ func DownloadBlobToFile(ctx context.Context, blobURL BlobURL, offset int64, coun
size = count size = count
} }
// 3. Compare and try to resize local file's size if it doesn't match Azure blob's size. // 2. Compare and try to resize local file's size if it doesn't match Azure blob's size.
stat, err := file.Stat() stat, err := file.Stat()
if err != nil { if err != nil {
return err return err
@ -299,7 +268,7 @@ func DownloadBlobToFile(ctx context.Context, blobURL BlobURL, offset int64, coun
} }
if size > 0 { if size > 0 {
// 4. Set mmap and call downloadBlobToBuffer. // 3. Set mmap and call downloadBlobToBuffer.
m, err := newMMF(file, true, 0, int(size)) m, err := newMMF(file, true, 0, int(size))
if err != nil { if err != nil {
return err return err
@ -407,10 +376,14 @@ func (t *uploadStreamToBlockBlobOptions) start(ctx context.Context) (interface{}
} }
func (t *uploadStreamToBlockBlobOptions) chunk(ctx context.Context, num uint32, buffer []byte) error { func (t *uploadStreamToBlockBlobOptions) chunk(ctx context.Context, num uint32, buffer []byte) error {
if num == 0 && len(buffer) < t.o.BufferSize { if num == 0 {
// If whole payload fits in 1 block, don't stage it; End will upload it with 1 I/O operation
t.firstBlock = buffer t.firstBlock = buffer
return nil
// If whole payload fits in 1 block, don't stage it; End will upload it with 1 I/O operation
// If the payload is exactly the same size as the buffer, there may be more content coming in.
if len(buffer) < t.o.BufferSize {
return nil
}
} }
// Else, upload a staged block... // Else, upload a staged block...
atomicMorphUint32(&t.maxBlockNum, func(startVal uint32) (val uint32, morphResult interface{}) { atomicMorphUint32(&t.maxBlockNum, func(startVal uint32) (val uint32, morphResult interface{}) {
@ -426,7 +399,9 @@ func (t *uploadStreamToBlockBlobOptions) chunk(ctx context.Context, num uint32,
} }
func (t *uploadStreamToBlockBlobOptions) end(ctx context.Context) (interface{}, error) { func (t *uploadStreamToBlockBlobOptions) end(ctx context.Context) (interface{}, error) {
if t.maxBlockNum == 0 { // If the first block had the exact same size as the buffer
// we would have staged it as a block thinking that there might be more data coming
if t.maxBlockNum == 0 && len(t.firstBlock) != t.o.BufferSize {
// If whole payload fits in 1 block (block #0), upload it with 1 I/O operation // 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), return t.b.Upload(ctx, bytes.NewReader(t.firstBlock),
t.o.BlobHTTPHeaders, t.o.Metadata, t.o.AccessConditions) t.o.BlobHTTPHeaders, t.o.Metadata, t.o.AccessConditions)

View file

@ -54,8 +54,8 @@ func isIPEndpointStyle(host string) bool {
// query parameters remain in the UnparsedParams field. This method overwrites all fields in the BlobURLParts object. // query parameters remain in the UnparsedParams field. This method overwrites all fields in the BlobURLParts object.
func NewBlobURLParts(u url.URL) BlobURLParts { func NewBlobURLParts(u url.URL) BlobURLParts {
up := BlobURLParts{ up := BlobURLParts{
Scheme: u.Scheme, Scheme: u.Scheme,
Host: u.Host, Host: u.Host,
} }
// Find the container & blob names (if any) // Find the container & blob names (if any)

View file

@ -28,17 +28,13 @@ type BlobSASSignatureValues struct {
// NewSASQueryParameters uses an account's shared key credential to sign this signature values to produce // NewSASQueryParameters uses an account's shared key credential to sign this signature values to produce
// the proper SAS query parameters. // the proper SAS query parameters.
func (v BlobSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *SharedKeyCredential) SASQueryParameters { func (v BlobSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *SharedKeyCredential) (SASQueryParameters, error) {
if sharedKeyCredential == nil {
panic("sharedKeyCredential can't be nil")
}
resource := "c" resource := "c"
if v.BlobName == "" { if v.BlobName == "" {
// Make sure the permission characters are in the correct order // Make sure the permission characters are in the correct order
perms := &ContainerSASPermissions{} perms := &ContainerSASPermissions{}
if err := perms.Parse(v.Permissions); err != nil { if err := perms.Parse(v.Permissions); err != nil {
panic(err) return SASQueryParameters{}, err
} }
v.Permissions = perms.String() v.Permissions = perms.String()
} else { } else {
@ -46,7 +42,7 @@ func (v BlobSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *Share
// Make sure the permission characters are in the correct order // Make sure the permission characters are in the correct order
perms := &BlobSASPermissions{} perms := &BlobSASPermissions{}
if err := perms.Parse(v.Permissions); err != nil { if err := perms.Parse(v.Permissions); err != nil {
panic(err) return SASQueryParameters{}, err
} }
v.Permissions = perms.String() v.Permissions = perms.String()
} }
@ -89,7 +85,7 @@ func (v BlobSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *Share
// Calculated SAS signature // Calculated SAS signature
signature: signature, signature: signature,
} }
return p return p, nil
} }
// getCanonicalName computes the canonical name for a container or blob resource for SAS signing. // getCanonicalName computes the canonical name for a container or blob resource for SAS signing.

View file

@ -59,7 +59,11 @@ func (ab AppendBlobURL) Create(ctx context.Context, h BlobHTTPHeaders, metadata
func (ab AppendBlobURL) AppendBlock(ctx context.Context, body io.ReadSeeker, ac AppendBlobAccessConditions, transactionalMD5 []byte) (*AppendBlobAppendBlockResponse, error) { func (ab AppendBlobURL) AppendBlock(ctx context.Context, body io.ReadSeeker, ac AppendBlobAccessConditions, transactionalMD5 []byte) (*AppendBlobAppendBlockResponse, error) {
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
ifAppendPositionEqual, ifMaxSizeLessThanOrEqual := ac.AppendPositionAccessConditions.pointers() ifAppendPositionEqual, ifMaxSizeLessThanOrEqual := ac.AppendPositionAccessConditions.pointers()
return ab.abClient.AppendBlock(ctx, body, validateSeekableStreamAt0AndGetCount(body), nil, count, err := validateSeekableStreamAt0AndGetCount(body)
if err != nil {
return nil, err
}
return ab.abClient.AppendBlock(ctx, body, count, nil,
transactionalMD5, ac.LeaseAccessConditions.pointers(), transactionalMD5, ac.LeaseAccessConditions.pointers(),
ifMaxSizeLessThanOrEqual, ifAppendPositionEqual, ifMaxSizeLessThanOrEqual, ifAppendPositionEqual,
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
@ -90,12 +94,6 @@ type AppendPositionAccessConditions struct {
// pointers is for internal infrastructure. It returns the fields as pointers. // pointers is for internal infrastructure. It returns the fields as pointers.
func (ac AppendPositionAccessConditions) pointers() (iape *int64, imsltoe *int64) { func (ac AppendPositionAccessConditions) 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 var zero int64 // defaults to 0
switch ac.IfAppendPositionEqual { switch ac.IfAppendPositionEqual {
case -1: case -1:

View file

@ -14,9 +14,6 @@ type BlobURL struct {
// NewBlobURL creates a BlobURL object using the specified URL and request policy pipeline. // NewBlobURL creates a BlobURL object using the specified URL and request policy pipeline.
func NewBlobURL(url url.URL, p pipeline.Pipeline) BlobURL { func NewBlobURL(url url.URL, p pipeline.Pipeline) BlobURL {
if p == nil {
panic("p can't be nil")
}
blobClient := newBlobClient(url, p) blobClient := newBlobClient(url, p)
return BlobURL{blobClient: blobClient} return BlobURL{blobClient: blobClient}
} }
@ -34,9 +31,6 @@ func (b BlobURL) String() string {
// WithPipeline creates a new BlobURL object identical to the source but with the specified request policy pipeline. // 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 { func (b BlobURL) WithPipeline(p pipeline.Pipeline) BlobURL {
if p == nil {
panic("p can't be nil")
}
return NewBlobURL(b.blobClient.URL(), p) return NewBlobURL(b.blobClient.URL(), p)
} }
@ -108,8 +102,8 @@ func (b BlobURL) Undelete(ctx context.Context) (*BlobUndeleteResponse, error) {
// bandwidth of the blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation // bandwidth of the blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation
// does not update the blob's ETag. // 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. // 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) (*BlobSetTierResponse, error) { func (b BlobURL) SetTier(ctx context.Context, tier AccessTierType, lac LeaseAccessConditions) (*BlobSetTierResponse, error) {
return b.blobClient.SetTier(ctx, tier, nil, nil) return b.blobClient.SetTier(ctx, tier, nil, nil, lac.pointers())
} }
// GetBlobProperties returns the blob's properties. // GetBlobProperties returns the blob's properties.

View file

@ -30,9 +30,6 @@ type BlockBlobURL struct {
// NewBlockBlobURL creates a BlockBlobURL object using the specified URL and request policy pipeline. // NewBlockBlobURL creates a BlockBlobURL object using the specified URL and request policy pipeline.
func NewBlockBlobURL(url url.URL, p pipeline.Pipeline) BlockBlobURL { func NewBlockBlobURL(url url.URL, p pipeline.Pipeline) BlockBlobURL {
if p == nil {
panic("p can't be nil")
}
blobClient := newBlobClient(url, p) blobClient := newBlobClient(url, p)
bbClient := newBlockBlobClient(url, p) bbClient := newBlockBlobClient(url, p)
return BlockBlobURL{BlobURL: BlobURL{blobClient: blobClient}, bbClient: bbClient} return BlockBlobURL{BlobURL: BlobURL{blobClient: blobClient}, bbClient: bbClient}
@ -60,7 +57,11 @@ func (bb BlockBlobURL) WithSnapshot(snapshot string) BlockBlobURL {
// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-blob. // 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) (*BlockBlobUploadResponse, error) { func (bb BlockBlobURL) Upload(ctx context.Context, body io.ReadSeeker, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions) (*BlockBlobUploadResponse, error) {
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
return bb.bbClient.Upload(ctx, body, validateSeekableStreamAt0AndGetCount(body), nil, count, err := validateSeekableStreamAt0AndGetCount(body)
if err != nil {
return nil, err
}
return bb.bbClient.Upload(ctx, body, count, nil,
&h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5, &h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5,
&h.CacheControl, metadata, ac.LeaseAccessConditions.pointers(), &h.CacheControl, metadata, ac.LeaseAccessConditions.pointers(),
&h.ContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, &h.ContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag,
@ -71,7 +72,11 @@ func (bb BlockBlobURL) Upload(ctx context.Context, body io.ReadSeeker, h BlobHTT
// Note that the http client closes the body stream after the request is sent to the service. // 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. // 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, transactionalMD5 []byte) (*BlockBlobStageBlockResponse, error) { func (bb BlockBlobURL) StageBlock(ctx context.Context, base64BlockID string, body io.ReadSeeker, ac LeaseAccessConditions, transactionalMD5 []byte) (*BlockBlobStageBlockResponse, error) {
return bb.bbClient.StageBlock(ctx, base64BlockID, validateSeekableStreamAt0AndGetCount(body), body, transactionalMD5, nil, ac.pointers(), nil) count, err := validateSeekableStreamAt0AndGetCount(body)
if err != nil {
return nil, err
}
return bb.bbClient.StageBlock(ctx, base64BlockID, count, body, transactionalMD5, nil, ac.pointers(), nil)
} }
// StageBlockFromURL copies the specified block from a source URL to the block blob's "staging area" to be later committed by a call to CommitBlockList. // StageBlockFromURL copies the specified block from a source URL to the block blob's "staging area" to be later committed by a call to CommitBlockList.

View file

@ -3,6 +3,7 @@ package azblob
import ( import (
"bytes" "bytes"
"context" "context"
"errors"
"fmt" "fmt"
"net/url" "net/url"
@ -16,9 +17,6 @@ type ContainerURL struct {
// NewContainerURL creates a ContainerURL object using the specified URL and request policy pipeline. // NewContainerURL creates a ContainerURL object using the specified URL and request policy pipeline.
func NewContainerURL(url url.URL, p pipeline.Pipeline) ContainerURL { func NewContainerURL(url url.URL, p pipeline.Pipeline) ContainerURL {
if p == nil {
panic("p can't be nil")
}
client := newContainerClient(url, p) client := newContainerClient(url, p)
return ContainerURL{client: client} return ContainerURL{client: client}
} }
@ -89,7 +87,7 @@ func (c ContainerURL) Create(ctx context.Context, metadata Metadata, publicAcces
// For more information, see https://docs.microsoft.com/rest/api/storageservices/delete-container. // For more information, see https://docs.microsoft.com/rest/api/storageservices/delete-container.
func (c ContainerURL) Delete(ctx context.Context, ac ContainerAccessConditions) (*ContainerDeleteResponse, error) { func (c ContainerURL) Delete(ctx context.Context, ac ContainerAccessConditions) (*ContainerDeleteResponse, error) {
if ac.IfMatch != ETagNone || ac.IfNoneMatch != ETagNone { 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") return nil, errors.New("the IfMatch and IfNoneMatch access conditions must have their default values because they are ignored by the service")
} }
ifModifiedSince, ifUnmodifiedSince, _, _ := ac.ModifiedAccessConditions.pointers() ifModifiedSince, ifUnmodifiedSince, _, _ := ac.ModifiedAccessConditions.pointers()
@ -109,7 +107,7 @@ func (c ContainerURL) GetProperties(ctx context.Context, ac LeaseAccessCondition
// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-container-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) { func (c ContainerURL) SetMetadata(ctx context.Context, metadata Metadata, ac ContainerAccessConditions) (*ContainerSetMetadataResponse, error) {
if !ac.IfUnmodifiedSince.IsZero() || ac.IfMatch != ETagNone || ac.IfNoneMatch != ETagNone { 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") return nil, errors.New("the IfUnmodifiedSince, IfMatch, and IfNoneMatch must have their default values because they are ignored by the blob service")
} }
ifModifiedSince, _, _, _ := ac.ModifiedAccessConditions.pointers() ifModifiedSince, _, _, _ := ac.ModifiedAccessConditions.pointers()
return c.client.SetMetadata(ctx, nil, ac.LeaseAccessConditions.pointers(), metadata, ifModifiedSince, nil) return c.client.SetMetadata(ctx, nil, ac.LeaseAccessConditions.pointers(), metadata, ifModifiedSince, nil)
@ -181,7 +179,7 @@ func (p *AccessPolicyPermission) Parse(s string) error {
func (c ContainerURL) SetAccessPolicy(ctx context.Context, accessType PublicAccessType, si []SignedIdentifier, func (c ContainerURL) SetAccessPolicy(ctx context.Context, accessType PublicAccessType, si []SignedIdentifier,
ac ContainerAccessConditions) (*ContainerSetAccessPolicyResponse, error) { ac ContainerAccessConditions) (*ContainerSetAccessPolicyResponse, error) {
if ac.IfMatch != ETagNone || ac.IfNoneMatch != ETagNone { 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") return nil, errors.New("the IfMatch and IfNoneMatch access conditions must have their default values because they are ignored by the service")
} }
ifModifiedSince, ifUnmodifiedSince, _, _ := ac.ModifiedAccessConditions.pointers() ifModifiedSince, ifUnmodifiedSince, _, _ := ac.ModifiedAccessConditions.pointers()
return c.client.SetAccessPolicy(ctx, si, nil, ac.LeaseAccessConditions.pointers(), return c.client.SetAccessPolicy(ctx, si, nil, ac.LeaseAccessConditions.pointers(),
@ -241,7 +239,7 @@ func (c ContainerURL) ListBlobsFlatSegment(ctx context.Context, marker Marker, o
// For more information, see https://docs.microsoft.com/rest/api/storageservices/list-blobs. // 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) (*ListBlobsHierarchySegmentResponse, error) { func (c ContainerURL) ListBlobsHierarchySegment(ctx context.Context, marker Marker, delimiter string, o ListBlobsSegmentOptions) (*ListBlobsHierarchySegmentResponse, error) {
if o.Details.Snapshots { if o.Details.Snapshots {
panic("snapshots are not supported in this listing operation") return nil, errors.New("snapshots are not supported in this listing operation")
} }
prefix, include, maxResults := o.pointers() prefix, include, maxResults := o.pointers()
return c.client.ListBlobHierarchySegment(ctx, delimiter, prefix, marker.val, maxResults, include, nil, nil) return c.client.ListBlobHierarchySegment(ctx, delimiter, prefix, marker.val, maxResults, include, nil, nil)
@ -264,9 +262,6 @@ func (o *ListBlobsSegmentOptions) pointers() (prefix *string, include []ListBlob
} }
include = o.Details.slice() include = o.Details.slice()
if o.MaxResults != 0 { if o.MaxResults != 0 {
if o.MaxResults < 0 {
panic("MaxResults must be >= 0")
}
maxResults = &o.MaxResults maxResults = &o.MaxResults
} }
return return

View file

@ -26,9 +26,6 @@ type PageBlobURL struct {
// NewPageBlobURL creates a PageBlobURL object using the specified URL and request policy pipeline. // NewPageBlobURL creates a PageBlobURL object using the specified URL and request policy pipeline.
func NewPageBlobURL(url url.URL, p pipeline.Pipeline) PageBlobURL { func NewPageBlobURL(url url.URL, p pipeline.Pipeline) PageBlobURL {
if p == nil {
panic("p can't be nil")
}
blobClient := newBlobClient(url, p) blobClient := newBlobClient(url, p)
pbClient := newPageBlobClient(url, p) pbClient := newPageBlobClient(url, p)
return PageBlobURL{BlobURL: BlobURL{blobClient: blobClient}, pbClient: pbClient} return PageBlobURL{BlobURL: BlobURL{blobClient: blobClient}, pbClient: pbClient}
@ -50,9 +47,6 @@ func (pb PageBlobURL) WithSnapshot(snapshot string) PageBlobURL {
// Create creates a page blob of the specified length. Call PutPage to upload data data to a page blob. // 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. // 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) (*PageBlobCreateResponse, error) { func (pb PageBlobURL) Create(ctx context.Context, size int64, sequenceNumber int64, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions) (*PageBlobCreateResponse, error) {
if sequenceNumber < 0 {
panic("sequenceNumber must be greater than or equal to 0")
}
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
return pb.pbClient.Create(ctx, 0, size, nil, return pb.pbClient.Create(ctx, 0, size, nil,
&h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5, &h.CacheControl, &h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5, &h.CacheControl,
@ -65,7 +59,10 @@ func (pb PageBlobURL) Create(ctx context.Context, size int64, sequenceNumber int
// Note that the http client closes the body stream after the request is sent to the service. // 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. // 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 PageBlobAccessConditions, transactionalMD5 []byte) (*PageBlobUploadPagesResponse, error) { func (pb PageBlobURL) UploadPages(ctx context.Context, offset int64, body io.ReadSeeker, ac PageBlobAccessConditions, transactionalMD5 []byte) (*PageBlobUploadPagesResponse, error) {
count := validateSeekableStreamAt0AndGetCount(body) count, err := validateSeekableStreamAt0AndGetCount(body)
if err != nil {
return nil, err
}
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual := ac.SequenceNumberAccessConditions.pointers() ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual := ac.SequenceNumberAccessConditions.pointers()
return pb.pbClient.UploadPages(ctx, body, count, transactionalMD5, nil, return pb.pbClient.UploadPages(ctx, body, count, transactionalMD5, nil,
@ -111,9 +108,6 @@ func (pb PageBlobURL) GetPageRangesDiff(ctx context.Context, offset int64, count
// Resize resizes the page blob to the specified size (which must be a multiple of 512). // 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. // 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) (*PageBlobResizeResponse, error) { func (pb PageBlobURL) Resize(ctx context.Context, size int64, ac BlobAccessConditions) (*PageBlobResizeResponse, error) {
if size%PageBlobPageBytes != 0 {
panic("Size must be a multiple of PageBlobPageBytes (512)")
}
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers() ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.ModifiedAccessConditions.pointers()
return pb.pbClient.Resize(ctx, size, nil, ac.LeaseAccessConditions.pointers(), return pb.pbClient.Resize(ctx, size, nil, ac.LeaseAccessConditions.pointers(),
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
@ -122,9 +116,6 @@ func (pb PageBlobURL) Resize(ctx context.Context, size int64, ac BlobAccessCondi
// SetSequenceNumber sets the page blob's sequence number. // SetSequenceNumber sets the page blob's sequence number.
func (pb PageBlobURL) UpdateSequenceNumber(ctx context.Context, action SequenceNumberActionType, sequenceNumber int64, func (pb PageBlobURL) UpdateSequenceNumber(ctx context.Context, action SequenceNumberActionType, sequenceNumber int64,
ac BlobAccessConditions) (*PageBlobUpdateSequenceNumberResponse, error) { ac BlobAccessConditions) (*PageBlobUpdateSequenceNumberResponse, error) {
if sequenceNumber < 0 {
panic("sequenceNumber must be greater than or equal to 0")
}
sn := &sequenceNumber sn := &sequenceNumber
if action == SequenceNumberActionIncrement { if action == SequenceNumberActionIncrement {
sn = nil sn = nil
@ -145,26 +136,11 @@ func (pb PageBlobURL) StartCopyIncremental(ctx context.Context, source url.URL,
qp := source.Query() qp := source.Query()
qp.Set("snapshot", snapshot) qp.Set("snapshot", snapshot)
source.RawQuery = qp.Encode() source.RawQuery = qp.Encode()
return pb.pbClient.CopyIncremental(ctx, source.String(), nil, nil, return pb.pbClient.CopyIncremental(ctx, source.String(), nil,
ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil)
} }
func (pr PageRange) pointers() *string { 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) endOffset := strconv.FormatInt(int64(pr.End), 10)
asString := fmt.Sprintf("bytes=%v-%s", pr.Start, endOffset) asString := fmt.Sprintf("bytes=%v-%s", pr.Start, endOffset)
return &asString return &asString
@ -202,16 +178,6 @@ type SequenceNumberAccessConditions struct {
// pointers is for internal infrastructure. It returns the fields as pointers. // pointers is for internal infrastructure. It returns the fields as pointers.
func (ac SequenceNumberAccessConditions) pointers() (snltoe *int64, snlt *int64, sne *int64) { func (ac SequenceNumberAccessConditions) 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 var zero int64 // Defaults to 0
switch ac.IfSequenceNumberLessThan { switch ac.IfSequenceNumberLessThan {
case -1: case -1:

View file

@ -23,9 +23,6 @@ type ServiceURL struct {
// NewServiceURL creates a ServiceURL object using the specified URL and request policy pipeline. // NewServiceURL creates a ServiceURL object using the specified URL and request policy pipeline.
func NewServiceURL(primaryURL url.URL, p pipeline.Pipeline) ServiceURL { func NewServiceURL(primaryURL url.URL, p pipeline.Pipeline) ServiceURL {
if p == nil {
panic("p can't be nil")
}
client := newServiceClient(primaryURL, p) client := newServiceClient(primaryURL, p)
return ServiceURL{client: client} return ServiceURL{client: client}
} }
@ -99,9 +96,6 @@ func (o *ListContainersSegmentOptions) pointers() (prefix *string, include ListC
prefix = &o.Prefix prefix = &o.Prefix
} }
if o.MaxResults != 0 { if o.MaxResults != 0 {
if o.MaxResults < 0 {
panic("MaxResults must be >= 0")
}
maxResults = &o.MaxResults maxResults = &o.MaxResults
} }
include = ListContainersIncludeType(o.Detail.string()) include = ListContainersIncludeType(o.Detail.string())

View file

@ -0,0 +1,3 @@
package azblob
const serviceLibVersion = "0.3"

View file

@ -6,6 +6,7 @@ import (
"crypto/hmac" "crypto/hmac"
"crypto/sha256" "crypto/sha256"
"encoding/base64" "encoding/base64"
"errors"
"net/http" "net/http"
"net/url" "net/url"
"sort" "sort"
@ -45,7 +46,10 @@ func (f *SharedKeyCredential) New(next pipeline.Policy, po *pipeline.PolicyOptio
if d := request.Header.Get(headerXmsDate); d == "" { if d := request.Header.Get(headerXmsDate); d == "" {
request.Header[headerXmsDate] = []string{time.Now().UTC().Format(http.TimeFormat)} request.Header[headerXmsDate] = []string{time.Now().UTC().Format(http.TimeFormat)}
} }
stringToSign := f.buildStringToSign(request) stringToSign, err := f.buildStringToSign(request)
if err != nil {
return nil, err
}
signature := f.ComputeHMACSHA256(stringToSign) signature := f.ComputeHMACSHA256(stringToSign)
authHeader := strings.Join([]string{"SharedKey ", f.accountName, ":", signature}, "") authHeader := strings.Join([]string{"SharedKey ", f.accountName, ":", signature}, "")
request.Header[headerAuthorization] = []string{authHeader} request.Header[headerAuthorization] = []string{authHeader}
@ -90,7 +94,7 @@ func (f *SharedKeyCredential) ComputeHMACSHA256(message string) (base64String st
return base64.StdEncoding.EncodeToString(h.Sum(nil)) return base64.StdEncoding.EncodeToString(h.Sum(nil))
} }
func (f *SharedKeyCredential) buildStringToSign(request pipeline.Request) string { func (f *SharedKeyCredential) buildStringToSign(request pipeline.Request) (string, error) {
// https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services // https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services
headers := request.Header headers := request.Header
contentLength := headers.Get(headerContentLength) contentLength := headers.Get(headerContentLength)
@ -98,6 +102,11 @@ func (f *SharedKeyCredential) buildStringToSign(request pipeline.Request) string
contentLength = "" contentLength = ""
} }
canonicalizedResource, err := f.buildCanonicalizedResource(request.URL)
if err != nil {
return "", err
}
stringToSign := strings.Join([]string{ stringToSign := strings.Join([]string{
request.Method, request.Method,
headers.Get(headerContentEncoding), headers.Get(headerContentEncoding),
@ -112,9 +121,9 @@ func (f *SharedKeyCredential) buildStringToSign(request pipeline.Request) string
headers.Get(headerIfUnmodifiedSince), headers.Get(headerIfUnmodifiedSince),
headers.Get(headerRange), headers.Get(headerRange),
buildCanonicalizedHeader(headers), buildCanonicalizedHeader(headers),
f.buildCanonicalizedResource(request.URL), canonicalizedResource,
}, "\n") }, "\n")
return stringToSign return stringToSign, nil
} }
func buildCanonicalizedHeader(headers http.Header) string { func buildCanonicalizedHeader(headers http.Header) string {
@ -146,7 +155,7 @@ func buildCanonicalizedHeader(headers http.Header) string {
return string(ch.Bytes()) return string(ch.Bytes())
} }
func (f *SharedKeyCredential) buildCanonicalizedResource(u *url.URL) string { func (f *SharedKeyCredential) buildCanonicalizedResource(u *url.URL) (string, error) {
// https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services // https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services
cr := bytes.NewBufferString("/") cr := bytes.NewBufferString("/")
cr.WriteString(f.accountName) cr.WriteString(f.accountName)
@ -164,7 +173,7 @@ func (f *SharedKeyCredential) buildCanonicalizedResource(u *url.URL) string {
// params is a map[string][]string; param name is key; params values is []string // params is a map[string][]string; param name is key; params values is []string
params, err := url.ParseQuery(u.RawQuery) // Returns URL decoded values params, err := url.ParseQuery(u.RawQuery) // Returns URL decoded values
if err != nil { if err != nil {
panic(err) return "", errors.New("parsing query parameters must succeed, otherwise there might be serious problems in the SDK/generated code")
} }
if len(params) > 0 { // There is at least 1 query parameter if len(params) > 0 { // There is at least 1 query parameter
@ -183,5 +192,5 @@ func (f *SharedKeyCredential) buildCanonicalizedResource(u *url.URL) string {
cr.WriteString("\n" + paramName + ":" + strings.Join(paramValues, ",")) cr.WriteString("\n" + paramName + ":" + strings.Join(paramValues, ","))
} }
} }
return string(cr.Bytes()) return string(cr.Bytes()), nil
} }

View file

@ -2,6 +2,7 @@ package azblob
import ( import (
"context" "context"
"errors"
"sync/atomic" "sync/atomic"
"runtime" "runtime"
@ -127,7 +128,8 @@ func (f *tokenCredential) stopRefresh() {
func (f *tokenCredential) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy { 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) { return pipeline.PolicyFunc(func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
if request.URL.Scheme != "https" { if request.URL.Scheme != "https" {
panic("Token credentials require a URL using the https protocol scheme.") // HTTPS must be used, otherwise the tokens are at the risk of being exposed
return nil, errors.New("token credentials require a URL using the https protocol scheme")
} }
request.Header[headerAuthorization] = []string{"Bearer " + f.Token()} request.Header[headerAuthorization] = []string{"Bearer " + f.Token()}
return next.Do(ctx, request) return next.Do(ctx, request)

View file

@ -1,4 +1,4 @@
// +build linux darwin freebsd // +build linux darwin freebsd openbsd netbsd
package azblob package azblob
@ -22,6 +22,6 @@ func (m *mmf) unmap() {
err := syscall.Munmap(*m) err := syscall.Munmap(*m)
*m = nil *m = nil
if err != nil { if err != nil {
panic(err) panic("if we are unable to unmap the memory-mapped file, there is serious concern for memory corruption")
} }
} }

View file

@ -33,6 +33,6 @@ func (m *mmf) unmap() {
*m = mmf{} *m = mmf{}
err := syscall.UnmapViewOfFile(addr) err := syscall.UnmapViewOfFile(addr)
if err != nil { if err != nil {
panic(err) panic("if we are unable to unmap the memory-mapped file, there is serious concern for memory corruption")
} }
} }

View file

@ -21,10 +21,6 @@ type PipelineOptions struct {
// NewPipeline creates a Pipeline using the specified credentials and options. // NewPipeline creates a Pipeline using the specified credentials and options.
func NewPipeline(c Credential, o PipelineOptions) pipeline.Pipeline { 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 // Closest to API goes first; closest to the wire goes last
f := []pipeline.Factory{ f := []pipeline.Factory{
NewTelemetryPolicyFactory(o.Telemetry), NewTelemetryPolicyFactory(o.Telemetry),

View file

@ -2,6 +2,7 @@ package azblob
import ( import (
"context" "context"
"errors"
"io" "io"
"io/ioutil" "io/ioutil"
"math/rand" "math/rand"
@ -67,21 +68,12 @@ func (o RetryOptions) retryReadsFromSecondaryHost() string {
} }
func (o RetryOptions) defaults() RetryOptions { func (o RetryOptions) defaults() RetryOptions {
if o.Policy != RetryPolicyExponential && o.Policy != RetryPolicyFixed { // We assume the following:
panic("RetryPolicy must be RetryPolicyExponential or RetryPolicyFixed") // 1. o.Policy should either be RetryPolicyExponential or RetryPolicyFixed
} // 2. o.MaxTries >= 0
if o.MaxTries < 0 { // 3. o.TryTimeout, o.RetryDelay, and o.MaxRetryDelay >=0
panic("MaxTries must be >= 0") // 4. o.RetryDelay <= o.MaxRetryDelay
} // 5. Both o.RetryDelay and o.MaxRetryDelay must be 0 or neither can 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) { IfDefault := func(current *time.Duration, desired time.Duration) {
if *current == time.Duration(0) { if *current == time.Duration(0) {
@ -176,9 +168,11 @@ func NewRetryPolicyFactory(o RetryOptions) pipeline.Factory {
// For each try, seek to the beginning of the Body stream. We do this even for the 1st try because // 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 // 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. // 1st try as for additional tries.
if err = requestCopy.RewindBody(); err != nil { err = requestCopy.RewindBody()
panic(err) if err != nil {
return nil, errors.New("we must be able to seek on the Body Stream, otherwise retries would cause data corruption")
} }
if !tryingPrimary { if !tryingPrimary {
requestCopy.Request.URL.Host = o.retryReadsFromSecondaryHost() requestCopy.Request.URL.Host = o.retryReadsFromSecondaryHost()
} }
@ -264,9 +258,8 @@ func NewRetryPolicyFactory(o RetryOptions) pipeline.Factory {
// as for client, the response should not be nil if request is sent and the operations is executed successfully. // as for client, the response should not be nil if request is sent and the operations is executed successfully.
// Another option, is that execute the cancel function when response or response.Response() is nil, // Another option, is that execute the cancel function when response or response.Response() is nil,
// as in this case, current per-try has nothing to do in future. // as in this case, current per-try has nothing to do in future.
panic("invalid state, response should not be nil when the operation is executed successfully") return nil, errors.New("invalid state, response should not be nil when the operation is executed successfully")
} }
response.Response().Body = &contextCancelReadCloser{cf: tryCancel, body: response.Response().Body} response.Response().Body = &contextCancelReadCloser{cf: tryCancel, body: response.Response().Body}
} }
break // Don't retry break // Don't retry

View file

@ -55,15 +55,6 @@ type retryReader struct {
// NewRetryReader creates a retry reader. // NewRetryReader creates a retry reader.
func NewRetryReader(ctx context.Context, initialResponse *http.Response, func NewRetryReader(ctx context.Context, initialResponse *http.Response,
info HTTPGetterInfo, o RetryReaderOptions, getter HTTPGetter) io.ReadCloser { 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} return &retryReader{ctx: ctx, getter: getter, info: info, countWasBounded: info.Count != CountToEnd, response: initialResponse, o: o}
} }

View file

@ -2,6 +2,7 @@ package azblob
import ( import (
"bytes" "bytes"
"errors"
"fmt" "fmt"
"strings" "strings"
"time" "time"
@ -22,17 +23,17 @@ type AccountSASSignatureValues struct {
// NewSASQueryParameters uses an account's shared key credential to sign this signature values to produce // NewSASQueryParameters uses an account's shared key credential to sign this signature values to produce
// the proper SAS query parameters. // the proper SAS query parameters.
func (v AccountSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *SharedKeyCredential) SASQueryParameters { func (v AccountSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *SharedKeyCredential) (SASQueryParameters, error) {
// https://docs.microsoft.com/en-us/rest/api/storageservices/Constructing-an-Account-SAS // https://docs.microsoft.com/en-us/rest/api/storageservices/Constructing-an-Account-SAS
if v.ExpiryTime.IsZero() || v.Permissions == "" || v.ResourceTypes == "" || v.Services == "" { 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") return SASQueryParameters{}, errors.New("account SAS is missing at least one of these: ExpiryTime, Permissions, Service, or ResourceType")
} }
if v.Version == "" { if v.Version == "" {
v.Version = SASVersion v.Version = SASVersion
} }
perms := &AccountSASPermissions{} perms := &AccountSASPermissions{}
if err := perms.Parse(v.Permissions); err != nil { if err := perms.Parse(v.Permissions); err != nil {
panic(err) return SASQueryParameters{}, err
} }
v.Permissions = perms.String() v.Permissions = perms.String()
@ -68,7 +69,7 @@ func (v AccountSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *Sh
// Calculated SAS signature // Calculated SAS signature
signature: signature, signature: signature,
} }
return p return p, nil
} }
// The AccountSASPermissions type simplifies creating the permissions string for an Azure Storage Account SAS. // The AccountSASPermissions type simplifies creating the permissions string for an Azure Storage Account SAS.

View file

@ -19,12 +19,6 @@ func (r httpRange) pointers() *string {
if r.offset == 0 && r.count == CountToEnd { // Do common case first for performance if r.offset == 0 && r.count == CountToEnd { // Do common case first for performance
return nil // No specified range 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 == CountToEnd (0) endOffset := "" // if count == CountToEnd (0)
if r.count > 0 { if r.count > 0 {
endOffset = strconv.FormatInt((r.offset+r.count)-1, 10) endOffset = strconv.FormatInt((r.offset+r.count)-1, 10)
@ -35,27 +29,36 @@ func (r httpRange) pointers() *string {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func validateSeekableStreamAt0AndGetCount(body io.ReadSeeker) int64 { func validateSeekableStreamAt0AndGetCount(body io.ReadSeeker) (int64, error) {
if body == nil { // nil body's are "logically" seekable to 0 and are 0 bytes long if body == nil { // nil body's are "logically" seekable to 0 and are 0 bytes long
return 0 return 0, nil
} }
validateSeekableStreamAt0(body)
err := validateSeekableStreamAt0(body)
if err != nil {
return 0, err
}
count, err := body.Seek(0, io.SeekEnd) count, err := body.Seek(0, io.SeekEnd)
if err != nil { if err != nil {
panic("failed to seek stream") return 0, errors.New("body stream must be seekable")
} }
body.Seek(0, io.SeekStart) body.Seek(0, io.SeekStart)
return count return count, nil
} }
func validateSeekableStreamAt0(body io.ReadSeeker) { // return an error if body is not a valid seekable stream at 0
func validateSeekableStreamAt0(body io.ReadSeeker) error {
if body == nil { // nil body's are "logically" seekable to 0 if body == nil { // nil body's are "logically" seekable to 0
return return nil
} }
if pos, err := body.Seek(0, io.SeekCurrent); pos != 0 || err != nil { if pos, err := body.Seek(0, io.SeekCurrent); pos != 0 || err != nil {
// Help detect programmer error
if err != nil { if err != nil {
panic(err) return errors.New("body stream must be seekable")
} }
panic(errors.New("stream must be set to position 0")) return errors.New("body stream must be set to position 0")
} }
return nil
} }

View file

@ -21,10 +21,7 @@ type uuid [16]byte
func newUUID() (u uuid) { func newUUID() (u uuid) {
u = uuid{} u = uuid{}
// Set all bits to randomly (or pseudo-randomly) chosen values. // Set all bits to randomly (or pseudo-randomly) chosen values.
_, err := rand.Read(u[:]) rand.Read(u[:])
if err != nil {
panic("ran.Read failed")
}
u[8] = (u[8] | reservedRFC4122) & 0x7F // u.setVariant(ReservedRFC4122) u[8] = (u[8] | reservedRFC4122) & 0x7F // u.setVariant(ReservedRFC4122)
var version byte = 4 var version byte = 4

View file

@ -34,7 +34,7 @@ func newAppendBlobClient(url url.URL, p pipeline.Pipeline) appendBlobClient {
// information, see <a // information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> transactionalContentMD5 is specify the transactional md5 for the body, to // Timeouts for Blob Service Operations.</a> transactionalContentMD5 is specify the transactional md5 for the body, to
// be validated by the service. leaseID is if specified, the operation only succeeds if the container's lease is active // be validated by the service. leaseID is if specified, the operation only succeeds if the resource's lease is active
// and matches this ID. maxSize is optional conditional header. The max length in bytes permitted for the append blob. // 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 // 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 // the value specified in this header, the request will fail with MaxBlobSizeConditionNotMet error (HTTP status code
@ -43,11 +43,11 @@ func newAppendBlobClient(url url.URL, p pipeline.Pipeline) appendBlobClient {
// this number. If it is not, the request will fail with the AppendPositionConditionNotMet error (HTTP status code 412 // 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 // - 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 // 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 // it has not been modified since the specified date/time. ifMatch 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. // 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 // 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. // logs when storage analytics logging is enabled.
func (client appendBlobClient) AppendBlock(ctx context.Context, body io.ReadSeeker, contentLength int64, timeout *int32, transactionalContentMD5 []byte, leaseID *string, maxSize *int64, appendPosition *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*AppendBlobAppendBlockResponse, error) { func (client appendBlobClient) AppendBlock(ctx context.Context, body io.ReadSeeker, contentLength int64, timeout *int32, transactionalContentMD5 []byte, leaseID *string, maxSize *int64, appendPosition *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*AppendBlobAppendBlockResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: body, {targetValue: body,
constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}}, constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}},
@ -56,7 +56,7 @@ func (client appendBlobClient) AppendBlock(ctx context.Context, body io.ReadSeek
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.appendBlockPreparer(body, contentLength, timeout, transactionalContentMD5, leaseID, maxSize, appendPosition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.appendBlockPreparer(body, contentLength, timeout, transactionalContentMD5, leaseID, maxSize, appendPosition, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -68,7 +68,7 @@ func (client appendBlobClient) AppendBlock(ctx context.Context, body io.ReadSeek
} }
// appendBlockPreparer prepares the AppendBlock request. // appendBlockPreparer prepares the AppendBlock request.
func (client appendBlobClient) appendBlockPreparer(body io.ReadSeeker, contentLength int64, timeout *int32, transactionalContentMD5 []byte, leaseID *string, maxSize *int64, appendPosition *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client appendBlobClient) appendBlockPreparer(body io.ReadSeeker, contentLength int64, timeout *int32, transactionalContentMD5 []byte, leaseID *string, maxSize *int64, appendPosition *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, body) req, err := pipeline.NewRequest("PUT", client.url, body)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -98,8 +98,8 @@ func (client appendBlobClient) appendBlockPreparer(body io.ReadSeeker, contentLe
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -139,22 +139,22 @@ func (client appendBlobClient) appendBlockResponder(resp pipeline.Response) (pip
// destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified // 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, 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 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 // Metadata for more information. leaseID is if specified, the operation only succeeds if the resource's lease is
// active and matches this ID. blobContentDisposition is optional. Sets the blob's Content-Disposition header. // 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 // 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 // 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. // since the specified date/time. ifMatch 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 // 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 // client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage
// analytics logging is enabled. // analytics logging is enabled.
func (client appendBlobClient) Create(ctx context.Context, contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*AppendBlobCreateResponse, error) { func (client appendBlobClient) Create(ctx context.Context, contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*AppendBlobCreateResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.createPreparer(contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.createPreparer(contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -166,7 +166,7 @@ func (client appendBlobClient) Create(ctx context.Context, contentLength int64,
} }
// createPreparer prepares the Create request. // createPreparer prepares the Create request.
func (client appendBlobClient) createPreparer(contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client appendBlobClient) createPreparer(contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -209,8 +209,8 @@ func (client appendBlobClient) createPreparer(contentLength int64, timeout *int3
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))

View file

@ -6,13 +6,14 @@ package azblob
import ( import (
"context" "context"
"encoding/base64" "encoding/base64"
"github.com/Azure/azure-pipeline-go/pipeline"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
"time" "time"
"github.com/Azure/azure-pipeline-go/pipeline"
) )
// blobClient is the client for the Blob methods of the Azblob service. // blobClient is the client for the Blob methods of the Azblob service.
@ -31,7 +32,7 @@ func newBlobClient(url url.URL, p pipeline.Pipeline) blobClient {
// copyID is the copy identifier provided in the x-ms-copy-id header of the original Copy Blob operation. timeout is // copyID is the copy identifier provided in the x-ms-copy-id header of the original Copy Blob operation. timeout is
// the timeout parameter is expressed in seconds. For more information, see <a // 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 // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character // 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. // limit that is recorded in the analytics logs when storage analytics logging is enabled.
func (client blobClient) AbortCopyFromURL(ctx context.Context, copyID string, timeout *int32, leaseID *string, requestID *string) (*BlobAbortCopyFromURLResponse, error) { func (client blobClient) AbortCopyFromURL(ctx context.Context, copyID string, timeout *int32, leaseID *string, requestID *string) (*BlobAbortCopyFromURLResponse, error) {
@ -98,18 +99,18 @@ func (client blobClient) abortCopyFromURLResponder(resp pipeline.Response) (pipe
// service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor // 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 // (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 // 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 // operate only on a blob if it has not been modified since the specified date/time. ifMatch 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 // 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 // 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. // recorded in the analytics logs when storage analytics logging is enabled.
func (client blobClient) AcquireLease(ctx context.Context, timeout *int32, duration *int32, proposedLeaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobAcquireLeaseResponse, error) { func (client blobClient) AcquireLease(ctx context.Context, timeout *int32, duration *int32, proposedLeaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*BlobAcquireLeaseResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.acquireLeasePreparer(timeout, duration, proposedLeaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.acquireLeasePreparer(timeout, duration, proposedLeaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -121,7 +122,7 @@ func (client blobClient) AcquireLease(ctx context.Context, timeout *int32, durat
} }
// acquireLeasePreparer prepares the AcquireLease request. // acquireLeasePreparer prepares the AcquireLease request.
func (client blobClient) acquireLeasePreparer(timeout *int32, duration *int32, proposedLeaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client blobClient) acquireLeasePreparer(timeout *int32, duration *int32, proposedLeaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -144,8 +145,8 @@ func (client blobClient) acquireLeasePreparer(timeout *int32, duration *int32, p
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -181,18 +182,18 @@ func (client blobClient) acquireLeaseResponder(resp pipeline.Response) (pipeline
// not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an // not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an
// infinite lease breaks immediately. ifModifiedSince is specify this header value to operate only on a blob if it has // infinite lease breaks immediately. 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 // 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 // blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate only on
// on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching // blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value.
// value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the // requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics
// analytics logs when storage analytics logging is enabled. // logs when storage analytics logging is enabled.
func (client blobClient) BreakLease(ctx context.Context, timeout *int32, breakPeriod *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobBreakLeaseResponse, error) { func (client blobClient) BreakLease(ctx context.Context, timeout *int32, breakPeriod *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*BlobBreakLeaseResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.breakLeasePreparer(timeout, breakPeriod, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.breakLeasePreparer(timeout, breakPeriod, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -204,7 +205,7 @@ func (client blobClient) BreakLease(ctx context.Context, timeout *int32, breakPe
} }
// breakLeasePreparer prepares the BreakLease request. // breakLeasePreparer prepares the BreakLease request.
func (client blobClient) breakLeasePreparer(timeout *int32, breakPeriod *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client blobClient) breakLeasePreparer(timeout *int32, breakPeriod *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -224,8 +225,8 @@ func (client blobClient) breakLeasePreparer(timeout *int32, breakPeriod *int32,
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -252,25 +253,25 @@ func (client blobClient) breakLeaseResponder(resp pipeline.Response) (pipeline.R
// ChangeLease [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete // ChangeLease [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
// operations // operations
// //
// leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. // leaseID is specifies the current lease ID on the resource. proposedLeaseID is proposed lease ID, in a GUID string
// proposedLeaseID is proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the // format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See
// proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string // Guid Constructor (String) for a list of valid GUID string formats. timeout is the timeout parameter is expressed in
// formats. timeout is the timeout parameter is expressed in seconds. For more information, see <a // seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> ifModifiedSince is specify this header value to operate only on a blob if // Timeouts for Blob Service Operations.</a> 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 // 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 // on a blob if it has not been modified since the specified date/time. ifMatch 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 // 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 // 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. // in the analytics logs when storage analytics logging is enabled.
func (client blobClient) ChangeLease(ctx context.Context, leaseID string, proposedLeaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobChangeLeaseResponse, error) { func (client blobClient) ChangeLease(ctx context.Context, leaseID string, proposedLeaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*BlobChangeLeaseResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.changeLeasePreparer(leaseID, proposedLeaseID, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.changeLeasePreparer(leaseID, proposedLeaseID, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -282,7 +283,7 @@ func (client blobClient) ChangeLease(ctx context.Context, leaseID string, propos
} }
// changeLeasePreparer prepares the ChangeLease request. // changeLeasePreparer prepares the ChangeLease request.
func (client blobClient) changeLeasePreparer(leaseID string, proposedLeaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client blobClient) changeLeasePreparer(leaseID string, proposedLeaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -301,8 +302,8 @@ func (client blobClient) changeLeasePreparer(leaseID string, proposedLeaseID str
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -337,19 +338,19 @@ func (client blobClient) changeLeaseResponder(resp pipeline.Response) (pipeline.
// 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing // 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 // 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 // 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 // operate only on a blob if it has not been modified since the specified date/time. ifMatch 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 // to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs
// without a matching value. leaseID is if specified, the operation only succeeds if the container's lease is active // without a matching value. leaseID is if specified, the operation only succeeds if the resource's lease is active and
// and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character limit that is // matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded
// recorded in the analytics logs when storage analytics logging is enabled. // in the analytics logs when storage analytics logging is enabled.
func (client blobClient) CreateSnapshot(ctx context.Context, timeout *int32, metadata map[string]string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, leaseID *string, requestID *string) (*BlobCreateSnapshotResponse, error) { func (client blobClient) CreateSnapshot(ctx context.Context, timeout *int32, metadata map[string]string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, leaseID *string, requestID *string) (*BlobCreateSnapshotResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.createSnapshotPreparer(timeout, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, leaseID, requestID) req, err := client.createSnapshotPreparer(timeout, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, leaseID, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -361,7 +362,7 @@ func (client blobClient) CreateSnapshot(ctx context.Context, timeout *int32, met
} }
// createSnapshotPreparer prepares the CreateSnapshot request. // createSnapshotPreparer prepares the CreateSnapshot request.
func (client blobClient) createSnapshotPreparer(timeout *int32, metadata map[string]string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, leaseID *string, requestID *string) (pipeline.Request, error) { func (client blobClient) createSnapshotPreparer(timeout *int32, metadata map[string]string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, leaseID *string, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -383,8 +384,8 @@ func (client blobClient) createSnapshotPreparer(timeout *int32, metadata map[str
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -426,23 +427,23 @@ func (client blobClient) createSnapshotResponder(resp pipeline.Response) (pipeli
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating // 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 // 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 // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. deleteSnapshots is required if the blob has associated snapshots. Specify one // lease is active and matches this ID. deleteSnapshots is required if the blob has associated snapshots. Specify one
// of the following two options: include: Delete the base blob and all of its snapshots. only: Delete only the blob's // of the following two options: include: Delete the base blob and all of its snapshots. only: Delete only the blob's
// snapshots and not the blob itself ifModifiedSince is specify this header value to operate only on a blob if it has // snapshots and not the blob itself 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 // 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 // blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate only on
// on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching // blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value.
// value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the // requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics
// analytics logs when storage analytics logging is enabled. // logs when storage analytics logging is enabled.
func (client blobClient) Delete(ctx context.Context, snapshot *string, timeout *int32, leaseID *string, deleteSnapshots DeleteSnapshotsOptionType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobDeleteResponse, error) { func (client blobClient) Delete(ctx context.Context, snapshot *string, timeout *int32, leaseID *string, deleteSnapshots DeleteSnapshotsOptionType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*BlobDeleteResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.deletePreparer(snapshot, timeout, leaseID, deleteSnapshots, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.deletePreparer(snapshot, timeout, leaseID, deleteSnapshots, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -454,7 +455,7 @@ func (client blobClient) Delete(ctx context.Context, snapshot *string, timeout *
} }
// deletePreparer prepares the Delete request. // deletePreparer prepares the Delete request.
func (client blobClient) deletePreparer(snapshot *string, timeout *int32, leaseID *string, deleteSnapshots DeleteSnapshotsOptionType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client blobClient) deletePreparer(snapshot *string, timeout *int32, leaseID *string, deleteSnapshots DeleteSnapshotsOptionType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("DELETE", client.url, nil) req, err := pipeline.NewRequest("DELETE", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -479,8 +480,8 @@ func (client blobClient) deletePreparer(snapshot *string, timeout *int32, leaseI
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -512,22 +513,22 @@ func (client blobClient) deleteResponder(resp pipeline.Response) (pipeline.Respo
// a Snapshot of a Blob.</a> timeout is the timeout parameter is expressed in seconds. For more information, see <a // 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 // 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 // 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. // range. leaseID is if specified, the operation only succeeds if the resource's lease is active and matches this ID.
// rangeGetContentMD5 is when set to true and specified together with the Range, the service returns the MD5 hash for // rangeGetContentMD5 is when set to true and specified together with the Range, the service returns the MD5 hash for
// the range, as long as the range is less than or equal to 4 MB in size. ifModifiedSince is specify this header value // the range, as long as the range is less than or equal to 4 MB in size. 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 // 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 // header value to operate only on a blob if it has not been modified since the specified date/time. ifMatch is specify
// specify an ETag value to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to // an ETag value to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only
// operate only on blobs without a matching value. requestID is provides a client-generated, opaque value with a 1 KB // on blobs without a matching value. requestID is provides a client-generated, opaque value with a 1 KB character
// character limit that is recorded in the analytics logs when storage analytics logging is enabled. // limit that is recorded in the analytics logs when storage analytics logging is enabled.
func (client blobClient) Download(ctx context.Context, snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, rangeGetContentMD5 *bool, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*downloadResponse, error) { func (client blobClient) Download(ctx context.Context, snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, rangeGetContentMD5 *bool, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*downloadResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.downloadPreparer(snapshot, timeout, rangeParameter, leaseID, rangeGetContentMD5, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.downloadPreparer(snapshot, timeout, rangeParameter, leaseID, rangeGetContentMD5, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -539,7 +540,7 @@ func (client blobClient) Download(ctx context.Context, snapshot *string, timeout
} }
// downloadPreparer prepares the Download request. // downloadPreparer prepares the Download request.
func (client blobClient) downloadPreparer(snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, rangeGetContentMD5 *bool, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client blobClient) downloadPreparer(snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, rangeGetContentMD5 *bool, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("GET", client.url, nil) req, err := pipeline.NewRequest("GET", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -567,8 +568,8 @@ func (client blobClient) downloadPreparer(snapshot *string, timeout *int32, rang
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -635,21 +636,21 @@ func (client blobClient) getAccountInfoResponder(resp pipeline.Response) (pipeli
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating // 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 // 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 // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it // 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 // 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 // blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate only on
// on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching // blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value.
// value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the // requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics
// analytics logs when storage analytics logging is enabled. // logs when storage analytics logging is enabled.
func (client blobClient) GetProperties(ctx context.Context, snapshot *string, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobGetPropertiesResponse, error) { func (client blobClient) GetProperties(ctx context.Context, snapshot *string, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*BlobGetPropertiesResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.getPropertiesPreparer(snapshot, timeout, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.getPropertiesPreparer(snapshot, timeout, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -661,7 +662,7 @@ func (client blobClient) GetProperties(ctx context.Context, snapshot *string, ti
} }
// getPropertiesPreparer prepares the GetProperties request. // getPropertiesPreparer prepares the GetProperties request.
func (client blobClient) getPropertiesPreparer(snapshot *string, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client blobClient) getPropertiesPreparer(snapshot *string, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("HEAD", client.url, nil) req, err := pipeline.NewRequest("HEAD", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -683,8 +684,8 @@ func (client blobClient) getPropertiesPreparer(snapshot *string, timeout *int32,
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -710,23 +711,23 @@ func (client blobClient) getPropertiesResponder(resp pipeline.Response) (pipelin
// ReleaseLease [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete // ReleaseLease [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
// operations // operations
// //
// leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. timeout // leaseID is specifies the current lease ID on the resource. timeout is the timeout parameter is expressed in seconds.
// is the timeout parameter is expressed in seconds. For more information, see <a // For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> ifModifiedSince is specify this header value to operate only on a blob if // Timeouts for Blob Service Operations.</a> 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 // 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 // on a blob if it has not been modified since the specified date/time. ifMatch 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 // 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 // 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. // in the analytics logs when storage analytics logging is enabled.
func (client blobClient) ReleaseLease(ctx context.Context, leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobReleaseLeaseResponse, error) { func (client blobClient) ReleaseLease(ctx context.Context, leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*BlobReleaseLeaseResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.releaseLeasePreparer(leaseID, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.releaseLeasePreparer(leaseID, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -738,7 +739,7 @@ func (client blobClient) ReleaseLease(ctx context.Context, leaseID string, timeo
} }
// releaseLeasePreparer prepares the ReleaseLease request. // releaseLeasePreparer prepares the ReleaseLease request.
func (client blobClient) releaseLeasePreparer(leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client blobClient) releaseLeasePreparer(leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -756,8 +757,8 @@ func (client blobClient) releaseLeasePreparer(leaseID string, timeout *int32, if
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -784,23 +785,23 @@ func (client blobClient) releaseLeaseResponder(resp pipeline.Response) (pipeline
// RenewLease [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete // RenewLease [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete
// operations // operations
// //
// leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. timeout // leaseID is specifies the current lease ID on the resource. timeout is the timeout parameter is expressed in seconds.
// is the timeout parameter is expressed in seconds. For more information, see <a // For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> ifModifiedSince is specify this header value to operate only on a blob if // Timeouts for Blob Service Operations.</a> 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 // 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 // on a blob if it has not been modified since the specified date/time. ifMatch 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 // 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 // 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. // in the analytics logs when storage analytics logging is enabled.
func (client blobClient) RenewLease(ctx context.Context, leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobRenewLeaseResponse, error) { func (client blobClient) RenewLease(ctx context.Context, leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*BlobRenewLeaseResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.renewLeasePreparer(leaseID, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.renewLeasePreparer(leaseID, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -812,7 +813,7 @@ func (client blobClient) RenewLease(ctx context.Context, leaseID string, timeout
} }
// renewLeasePreparer prepares the RenewLease request. // renewLeasePreparer prepares the RenewLease request.
func (client blobClient) renewLeasePreparer(leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client blobClient) renewLeasePreparer(leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -830,8 +831,8 @@ func (client blobClient) renewLeasePreparer(leaseID string, timeout *int32, ifMo
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -866,22 +867,21 @@ func (client blobClient) renewLeaseResponder(resp pipeline.Response) (pipeline.R
// blocks were validated when each was uploaded. blobContentEncoding is optional. Sets the blob's content encoding. If // blocks were validated when each was uploaded. 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. // 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 // Set the blob's content language. If specified, this property is stored with the blob and returned with a read
// request. leaseID is if specified, the operation only succeeds if the container's lease is active and matches this // request. leaseID is if specified, the operation only succeeds if the resource's lease is active and matches this ID.
// ID. ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the // ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the specified
// specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been // date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified
// modified since the specified date/time. ifMatches is specify an ETag value to operate only on blobs with a matching // since the specified date/time. ifMatch is specify an ETag value to operate only on blobs with a matching value.
// value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. // ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. blobContentDisposition is
// blobContentDisposition is optional. Sets the blob's Content-Disposition header. requestID is provides a // optional. Sets the blob's Content-Disposition header. requestID is provides a client-generated, opaque value with a
// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage // 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled.
// analytics logging is enabled. func (client blobClient) SetHTTPHeaders(ctx context.Context, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentMD5 []byte, blobContentEncoding *string, blobContentLanguage *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, blobContentDisposition *string, requestID *string) (*BlobSetHTTPHeadersResponse, error) {
func (client blobClient) SetHTTPHeaders(ctx context.Context, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentMD5 []byte, blobContentEncoding *string, blobContentLanguage *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, blobContentDisposition *string, requestID *string) (*BlobSetHTTPHeadersResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.setHTTPHeadersPreparer(timeout, blobCacheControl, blobContentType, blobContentMD5, blobContentEncoding, blobContentLanguage, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobContentDisposition, requestID) req, err := client.setHTTPHeadersPreparer(timeout, blobCacheControl, blobContentType, blobContentMD5, blobContentEncoding, blobContentLanguage, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, blobContentDisposition, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -893,7 +893,7 @@ func (client blobClient) SetHTTPHeaders(ctx context.Context, timeout *int32, blo
} }
// setHTTPHeadersPreparer prepares the SetHTTPHeaders request. // setHTTPHeadersPreparer prepares the SetHTTPHeaders request.
func (client blobClient) setHTTPHeadersPreparer(timeout *int32, blobCacheControl *string, blobContentType *string, blobContentMD5 []byte, blobContentEncoding *string, blobContentLanguage *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, blobContentDisposition *string, requestID *string) (pipeline.Request, error) { func (client blobClient) setHTTPHeadersPreparer(timeout *int32, blobCacheControl *string, blobContentType *string, blobContentMD5 []byte, blobContentEncoding *string, blobContentLanguage *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, blobContentDisposition *string, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -928,8 +928,8 @@ func (client blobClient) setHTTPHeadersPreparer(timeout *int32, blobCacheControl
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -966,20 +966,20 @@ func (client blobClient) setHTTPHeadersResponder(resp pipeline.Response) (pipeli
// the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version // 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 // 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 // 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. ifModifiedSince is specify this header value to operate only on a // resource'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 // 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 // operate only on a blob if it has not been modified since the specified date/time. ifMatch 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 // 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 // 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. // recorded in the analytics logs when storage analytics logging is enabled.
func (client blobClient) SetMetadata(ctx context.Context, timeout *int32, metadata map[string]string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobSetMetadataResponse, error) { func (client blobClient) SetMetadata(ctx context.Context, timeout *int32, metadata map[string]string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*BlobSetMetadataResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.setMetadataPreparer(timeout, metadata, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.setMetadataPreparer(timeout, metadata, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -991,7 +991,7 @@ func (client blobClient) SetMetadata(ctx context.Context, timeout *int32, metada
} }
// setMetadataPreparer prepares the SetMetadata request. // setMetadataPreparer prepares the SetMetadata request.
func (client blobClient) setMetadataPreparer(timeout *int32, metadata map[string]string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client blobClient) setMetadataPreparer(timeout *int32, metadata map[string]string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -1016,8 +1016,8 @@ func (client blobClient) setMetadataPreparer(timeout *int32, metadata map[string
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -1049,15 +1049,16 @@ func (client blobClient) setMetadataResponder(resp pipeline.Response) (pipeline.
// information, see <a // information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // 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 // 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. // character limit that is recorded in the analytics logs when storage analytics logging is enabled. leaseID is if
func (client blobClient) SetTier(ctx context.Context, tier AccessTierType, timeout *int32, requestID *string) (*BlobSetTierResponse, error) { // specified, the operation only succeeds if the resource's lease is active and matches this ID.
func (client blobClient) SetTier(ctx context.Context, tier AccessTierType, timeout *int32, requestID *string, leaseID *string) (*BlobSetTierResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.setTierPreparer(tier, timeout, requestID) req, err := client.setTierPreparer(tier, timeout, requestID, leaseID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1069,7 +1070,7 @@ func (client blobClient) SetTier(ctx context.Context, tier AccessTierType, timeo
} }
// setTierPreparer prepares the SetTier request. // setTierPreparer prepares the SetTier request.
func (client blobClient) setTierPreparer(tier AccessTierType, timeout *int32, requestID *string) (pipeline.Request, error) { func (client blobClient) setTierPreparer(tier AccessTierType, timeout *int32, requestID *string, leaseID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -1085,6 +1086,9 @@ func (client blobClient) setTierPreparer(tier AccessTierType, timeout *int32, re
if requestID != nil { if requestID != nil {
req.Header.Set("x-ms-client-request-id", *requestID) req.Header.Set("x-ms-client-request-id", *requestID)
} }
if leaseID != nil {
req.Header.Set("x-ms-lease-id", *leaseID)
}
return req, nil return req, nil
} }
@ -1113,23 +1117,23 @@ func (client blobClient) setTierResponder(resp pipeline.Response) (pipeline.Resp
// 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing // 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. sourceIfModifiedSince is specify this header value to operate // Containers, Blobs, and Metadata for more information. sourceIfModifiedSince is specify this header value to operate
// only on a blob if it has been modified since the specified date/time. sourceIfUnmodifiedSince is specify this header // only on a blob if it has been modified since the specified date/time. sourceIfUnmodifiedSince is specify this header
// value to operate only on a blob if it has not been modified since the specified date/time. sourceIfMatches is // value to operate only on a blob if it has not been modified since the specified date/time. sourceIfMatch is specify
// specify an ETag value to operate only on blobs with a matching value. sourceIfNoneMatch is specify an ETag value to // an ETag value to operate only on blobs with a matching value. sourceIfNoneMatch is specify an ETag value to operate
// operate only on blobs without a matching value. ifModifiedSince is specify this header value to operate only on a // only on blobs without a matching value. ifModifiedSince is specify this header value to operate only on a blob if it
// blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to // has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a
// operate only on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value // blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate only on
// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs // blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value.
// without a matching value. leaseID is if specified, the operation only succeeds if the container's lease is active // leaseID is if specified, the operation only succeeds if the resource's lease is active and matches this ID.
// and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character limit that is // requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics
// recorded in the analytics logs when storage analytics logging is enabled. // logs when storage analytics logging is enabled.
func (client blobClient) StartCopyFromURL(ctx context.Context, copySource string, timeout *int32, metadata map[string]string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatches *ETag, sourceIfNoneMatch *ETag, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, leaseID *string, requestID *string) (*BlobStartCopyFromURLResponse, error) { func (client blobClient) StartCopyFromURL(ctx context.Context, copySource string, timeout *int32, metadata map[string]string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, leaseID *string, requestID *string) (*BlobStartCopyFromURLResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.startCopyFromURLPreparer(copySource, timeout, metadata, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatches, sourceIfNoneMatch, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, leaseID, requestID) req, err := client.startCopyFromURLPreparer(copySource, timeout, metadata, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatch, sourceIfNoneMatch, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, leaseID, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1141,7 +1145,7 @@ func (client blobClient) StartCopyFromURL(ctx context.Context, copySource string
} }
// startCopyFromURLPreparer prepares the StartCopyFromURL request. // startCopyFromURLPreparer prepares the StartCopyFromURL request.
func (client blobClient) startCopyFromURLPreparer(copySource string, timeout *int32, metadata map[string]string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatches *ETag, sourceIfNoneMatch *ETag, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, leaseID *string, requestID *string) (pipeline.Request, error) { func (client blobClient) startCopyFromURLPreparer(copySource string, timeout *int32, metadata map[string]string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatch *ETag, sourceIfNoneMatch *ETag, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, leaseID *string, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -1162,8 +1166,8 @@ func (client blobClient) startCopyFromURLPreparer(copySource string, timeout *in
if sourceIfUnmodifiedSince != nil { if sourceIfUnmodifiedSince != nil {
req.Header.Set("x-ms-source-if-unmodified-since", (*sourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("x-ms-source-if-unmodified-since", (*sourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if sourceIfMatches != nil { if sourceIfMatch != nil {
req.Header.Set("x-ms-source-if-match", string(*sourceIfMatches)) req.Header.Set("x-ms-source-if-match", string(*sourceIfMatch))
} }
if sourceIfNoneMatch != nil { if sourceIfNoneMatch != nil {
req.Header.Set("x-ms-source-if-none-match", string(*sourceIfNoneMatch)) req.Header.Set("x-ms-source-if-none-match", string(*sourceIfNoneMatch))
@ -1174,8 +1178,8 @@ func (client blobClient) startCopyFromURLPreparer(copySource string, timeout *in
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))

View file

@ -48,22 +48,22 @@ func newBlockBlobClient(url url.URL, p pipeline.Pipeline) blockBlobClient {
// destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified // 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, 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 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 // Metadata for more information. leaseID is if specified, the operation only succeeds if the resource's lease is
// active and matches this ID. blobContentDisposition is optional. Sets the blob's Content-Disposition header. // 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 // 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 // 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. // since the specified date/time. ifMatch 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 // 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 // client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage
// analytics logging is enabled. // analytics logging is enabled.
func (client blockBlobClient) CommitBlockList(ctx context.Context, blocks BlockLookupList, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlockBlobCommitBlockListResponse, error) { func (client blockBlobClient) CommitBlockList(ctx context.Context, blocks BlockLookupList, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*BlockBlobCommitBlockListResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.commitBlockListPreparer(blocks, timeout, blobCacheControl, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.commitBlockListPreparer(blocks, timeout, blobCacheControl, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -75,7 +75,7 @@ func (client blockBlobClient) CommitBlockList(ctx context.Context, blocks BlockL
} }
// commitBlockListPreparer prepares the CommitBlockList request. // commitBlockListPreparer prepares the CommitBlockList request.
func (client blockBlobClient) commitBlockListPreparer(blocks BlockLookupList, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client blockBlobClient) commitBlockListPreparer(blocks BlockLookupList, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -118,8 +118,8 @@ func (client blockBlobClient) commitBlockListPreparer(blocks BlockLookupList, ti
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -160,7 +160,7 @@ func (client blockBlobClient) commitBlockListResponder(resp pipeline.Response) (
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating // 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 // 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 // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character // 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. // limit that is recorded in the analytics logs when storage analytics logging is enabled.
func (client blockBlobClient) GetBlockList(ctx context.Context, listType BlockListType, snapshot *string, timeout *int32, leaseID *string, requestID *string) (*BlockList, error) { func (client blockBlobClient) GetBlockList(ctx context.Context, listType BlockListType, snapshot *string, timeout *int32, leaseID *string, requestID *string) (*BlockList, error) {
@ -220,7 +220,7 @@ func (client blockBlobClient) getBlockListResponder(resp pipeline.Response) (pip
defer resp.Response().Body.Close() defer resp.Response().Body.Close()
b, err := ioutil.ReadAll(resp.Response().Body) b, err := ioutil.ReadAll(resp.Response().Body)
if err != nil { if err != nil {
return result, NewResponseError(err, resp.Response(), "failed to read response body") return result, err
} }
if len(b) > 0 { if len(b) > 0 {
b = removeBOM(b) b = removeBOM(b)
@ -241,7 +241,7 @@ func (client blockBlobClient) getBlockListResponder(resp pipeline.Response) (pip
// transactional md5 for the body, to be validated by the service. timeout is the timeout parameter is expressed in // transactional md5 for the body, to be validated by the service. timeout is the timeout parameter is expressed in
// seconds. For more information, see <a // seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character // 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. // limit that is recorded in the analytics logs when storage analytics logging is enabled.
func (client blockBlobClient) StageBlock(ctx context.Context, blockID string, contentLength int64, body io.ReadSeeker, transactionalContentMD5 []byte, timeout *int32, leaseID *string, requestID *string) (*BlockBlobStageBlockResponse, error) { func (client blockBlobClient) StageBlock(ctx context.Context, blockID string, contentLength int64, body io.ReadSeeker, transactionalContentMD5 []byte, timeout *int32, leaseID *string, requestID *string) (*BlockBlobStageBlockResponse, error) {
@ -307,12 +307,12 @@ func (client blockBlobClient) stageBlockResponder(resp pipeline.Response) (pipel
// //
// blockID is a valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or // 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 // 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. contentLength is the length of the request. sourceURL is specifiy an URL to the copy // same size for each block. contentLength is the length of the request. sourceURL is specify a URL to the copy source.
// source. sourceRange is bytes of source data in the specified range. sourceContentMD5 is specify the md5 calculated // sourceRange is bytes of source data in the specified range. sourceContentMD5 is specify the md5 calculated for the
// for the range of bytes that must be read from the copy source. timeout is the timeout parameter is expressed in // range of bytes that must be read from the copy source. timeout is the timeout parameter is expressed in seconds. For
// seconds. For more information, see <a // more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character // 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. // limit that is recorded in the analytics logs when storage analytics logging is enabled.
func (client blockBlobClient) StageBlockFromURL(ctx context.Context, blockID string, contentLength int64, sourceURL string, sourceRange *string, sourceContentMD5 []byte, timeout *int32, leaseID *string, requestID *string) (*BlockBlobStageBlockFromURLResponse, error) { func (client blockBlobClient) StageBlockFromURL(ctx context.Context, blockID string, contentLength int64, sourceURL string, sourceRange *string, sourceContentMD5 []byte, timeout *int32, leaseID *string, requestID *string) (*BlockBlobStageBlockFromURLResponse, error) {
@ -396,15 +396,15 @@ func (client blockBlobClient) stageBlockFromURLResponder(resp pipeline.Response)
// destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified // 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, 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 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 // Metadata for more information. leaseID is if specified, the operation only succeeds if the resource's lease is
// active and matches this ID. blobContentDisposition is optional. Sets the blob's Content-Disposition header. // 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 // 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 // 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. // since the specified date/time. ifMatch 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 // 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 // client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage
// analytics logging is enabled. // analytics logging is enabled.
func (client blockBlobClient) Upload(ctx context.Context, body io.ReadSeeker, contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlockBlobUploadResponse, error) { func (client blockBlobClient) Upload(ctx context.Context, body io.ReadSeeker, contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*BlockBlobUploadResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: body, {targetValue: body,
constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}}, constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}},
@ -413,7 +413,7 @@ func (client blockBlobClient) Upload(ctx context.Context, body io.ReadSeeker, co
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.uploadPreparer(body, contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.uploadPreparer(body, contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -425,7 +425,7 @@ func (client blockBlobClient) Upload(ctx context.Context, body io.ReadSeeker, co
} }
// uploadPreparer prepares the Upload request. // uploadPreparer prepares the Upload request.
func (client blockBlobClient) uploadPreparer(body io.ReadSeeker, contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client blockBlobClient) uploadPreparer(body io.ReadSeeker, contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, body) req, err := pipeline.NewRequest("PUT", client.url, body)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -468,8 +468,8 @@ func (client blockBlobClient) uploadPreparer(body io.ReadSeeker, contentLength i
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))

View file

@ -178,10 +178,10 @@ func (client containerClient) breakLeaseResponder(resp pipeline.Response) (pipel
// ChangeLease [Update] establishes and manages a lock on a container for delete operations. The lock duration can be // ChangeLease [Update] establishes and manages a lock on a container for delete operations. The lock duration can be
// 15 to 60 seconds, or can be infinite // 15 to 60 seconds, or can be infinite
// //
// leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. // leaseID is specifies the current lease ID on the resource. proposedLeaseID is proposed lease ID, in a GUID string
// proposedLeaseID is proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the // format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See
// proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string // Guid Constructor (String) for a list of valid GUID string formats. timeout is the timeout parameter is expressed in
// formats. timeout is the timeout parameter is expressed in seconds. For more information, see <a // seconds. For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> ifModifiedSince is specify this header value to operate only on a blob if // Timeouts for Blob Service Operations.</a> 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 // it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only
@ -320,7 +320,7 @@ func (client containerClient) createResponder(resp pipeline.Response) (pipeline.
// //
// timeout is the timeout parameter is expressed in seconds. For more information, see <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 // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it // 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 // 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 // blob if it has not been modified since the specified date/time. requestID is provides a client-generated, opaque
@ -387,7 +387,7 @@ func (client containerClient) deleteResponder(resp pipeline.Response) (pipeline.
// //
// timeout is the timeout parameter is expressed in seconds. For more information, see <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 // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character // 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. // limit that is recorded in the analytics logs when storage analytics logging is enabled.
func (client containerClient) GetAccessPolicy(ctx context.Context, timeout *int32, leaseID *string, requestID *string) (*SignedIdentifiers, error) { func (client containerClient) GetAccessPolicy(ctx context.Context, timeout *int32, leaseID *string, requestID *string) (*SignedIdentifiers, error) {
@ -444,7 +444,7 @@ func (client containerClient) getAccessPolicyResponder(resp pipeline.Response) (
defer resp.Response().Body.Close() defer resp.Response().Body.Close()
b, err := ioutil.ReadAll(resp.Response().Body) b, err := ioutil.ReadAll(resp.Response().Body)
if err != nil { if err != nil {
return result, NewResponseError(err, resp.Response(), "failed to read response body") return result, err
} }
if len(b) > 0 { if len(b) > 0 {
b = removeBOM(b) b = removeBOM(b)
@ -499,7 +499,7 @@ func (client containerClient) getAccountInfoResponder(resp pipeline.Response) (p
// //
// timeout is the timeout parameter is expressed in seconds. For more information, see <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 // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character // 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. // 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) { func (client containerClient) GetProperties(ctx context.Context, timeout *int32, leaseID *string, requestID *string) (*ContainerGetPropertiesResponse, error) {
@ -635,7 +635,7 @@ func (client containerClient) listBlobFlatSegmentResponder(resp pipeline.Respons
defer resp.Response().Body.Close() defer resp.Response().Body.Close()
b, err := ioutil.ReadAll(resp.Response().Body) b, err := ioutil.ReadAll(resp.Response().Body)
if err != nil { if err != nil {
return result, NewResponseError(err, resp.Response(), "failed to read response body") return result, err
} }
if len(b) > 0 { if len(b) > 0 {
b = removeBOM(b) b = removeBOM(b)
@ -733,7 +733,7 @@ func (client containerClient) listBlobHierarchySegmentResponder(resp pipeline.Re
defer resp.Response().Body.Close() defer resp.Response().Body.Close()
b, err := ioutil.ReadAll(resp.Response().Body) b, err := ioutil.ReadAll(resp.Response().Body)
if err != nil { if err != nil {
return result, NewResponseError(err, resp.Response(), "failed to read response body") return result, err
} }
if len(b) > 0 { if len(b) > 0 {
b = removeBOM(b) b = removeBOM(b)
@ -748,8 +748,8 @@ func (client containerClient) listBlobHierarchySegmentResponder(resp pipeline.Re
// ReleaseLease [Update] establishes and manages a lock on a container for delete operations. The lock duration can be // ReleaseLease [Update] establishes and manages a lock on a container for delete operations. The lock duration can be
// 15 to 60 seconds, or can be infinite // 15 to 60 seconds, or can be infinite
// //
// leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. timeout // leaseID is specifies the current lease ID on the resource. timeout is the timeout parameter is expressed in seconds.
// is the timeout parameter is expressed in seconds. For more information, see <a // For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> ifModifiedSince is specify this header value to operate only on a blob if // Timeouts for Blob Service Operations.</a> 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 // it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only
@ -816,8 +816,8 @@ func (client containerClient) releaseLeaseResponder(resp pipeline.Response) (pip
// RenewLease [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 // RenewLease [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15
// to 60 seconds, or can be infinite // to 60 seconds, or can be infinite
// //
// leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. timeout // leaseID is specifies the current lease ID on the resource. timeout is the timeout parameter is expressed in seconds.
// is the timeout parameter is expressed in seconds. For more information, see <a // For more information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting
// Timeouts for Blob Service Operations.</a> ifModifiedSince is specify this header value to operate only on a blob if // Timeouts for Blob Service Operations.</a> 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 // it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only
@ -887,7 +887,7 @@ func (client containerClient) renewLeaseResponder(resp pipeline.Response) (pipel
// containerACL is the acls for the container timeout is the timeout parameter is expressed in seconds. For more // containerACL is the acls for the container timeout is the timeout parameter is expressed in seconds. For more
// information, see <a // information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. access is specifies whether data in the container may be accessed publicly and // 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 // 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 // since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has
@ -967,7 +967,7 @@ func (client containerClient) setAccessPolicyResponder(resp pipeline.Response) (
// //
// timeout is the timeout parameter is expressed in seconds. For more information, see <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 // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. metadata is optional. Specifies a user-defined name-value pair associated with // 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 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 // the destination blob. If one or more name-value pairs are specified, the destination blob is created with the

View file

@ -32,24 +32,24 @@ func newPageBlobClient(url url.URL, p pipeline.Pipeline) pageBlobClient {
// information, see <a // information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // 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 // 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. // range. leaseID is if specified, the operation only succeeds if the resource'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 // 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 // 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 // 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 // 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 // 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 // operate only on a blob if it has not been modified since the specified date/time. ifMatch 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 // 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 // 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. // recorded in the analytics logs when storage analytics logging is enabled.
func (client pageBlobClient) ClearPages(ctx context.Context, contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobClearPagesResponse, error) { func (client pageBlobClient) ClearPages(ctx context.Context, contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobClearPagesResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.clearPagesPreparer(contentLength, timeout, rangeParameter, leaseID, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.clearPagesPreparer(contentLength, timeout, rangeParameter, leaseID, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -61,7 +61,7 @@ func (client pageBlobClient) ClearPages(ctx context.Context, contentLength int64
} }
// clearPagesPreparer prepares the ClearPages request. // clearPagesPreparer prepares the ClearPages request.
func (client pageBlobClient) clearPagesPreparer(contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client pageBlobClient) clearPagesPreparer(contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -94,8 +94,8 @@ func (client pageBlobClient) clearPagesPreparer(contentLength int64, timeout *in
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -129,25 +129,20 @@ func (client pageBlobClient) clearPagesResponder(resp pipeline.Response) (pipeli
// must either be public or must be authenticated via a shared access signature. timeout is the timeout parameter is // 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 // 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 // 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 // Timeouts for Blob Service Operations.</a> ifModifiedSince is specify this header value to operate only on a blob if
// with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or // it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only
// file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with // on a blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate
// the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version // only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a
// 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing // matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded
// Containers, Blobs, and Metadata for more information. ifModifiedSince is specify this header value to operate only // in the analytics logs when storage analytics logging is enabled.
// on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to func (client pageBlobClient) CopyIncremental(ctx context.Context, copySource string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobCopyIncrementalResponse, error) {
// 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 pageBlobClient) CopyIncremental(ctx context.Context, copySource string, timeout *int32, metadata map[string]string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobCopyIncrementalResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.copyIncrementalPreparer(copySource, timeout, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.copyIncrementalPreparer(copySource, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -159,7 +154,7 @@ func (client pageBlobClient) CopyIncremental(ctx context.Context, copySource str
} }
// copyIncrementalPreparer prepares the CopyIncremental request. // copyIncrementalPreparer prepares the CopyIncremental request.
func (client pageBlobClient) copyIncrementalPreparer(copySource string, timeout *int32, metadata map[string]string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client pageBlobClient) copyIncrementalPreparer(copySource string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -170,19 +165,14 @@ func (client pageBlobClient) copyIncrementalPreparer(copySource string, timeout
} }
params.Set("comp", "incrementalcopy") params.Set("comp", "incrementalcopy")
req.URL.RawQuery = params.Encode() req.URL.RawQuery = params.Encode()
if metadata != nil {
for k, v := range metadata {
req.Header.Set("x-ms-meta-"+k, v)
}
}
if ifModifiedSince != nil { if ifModifiedSince != nil {
req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -224,23 +214,23 @@ func (client pageBlobClient) copyIncrementalResponder(resp pipeline.Response) (p
// destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified // 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, 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 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 // Metadata for more information. leaseID is if specified, the operation only succeeds if the resource's lease is
// active and matches this ID. blobContentDisposition is optional. Sets the blob's Content-Disposition header. // 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 // 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 // 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. // since the specified date/time. ifMatch 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. blobSequenceNumber is set // ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. blobSequenceNumber is set
// for page blobs only. The sequence number is a user-controlled value that you can use to track requests. The value of // for page blobs only. The sequence number is a user-controlled value that you can use to track requests. The value of
// the sequence number must be between 0 and 2^63 - 1. requestID is provides a client-generated, opaque value with a 1 // the sequence number must be between 0 and 2^63 - 1. 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. // KB character limit that is recorded in the analytics logs when storage analytics logging is enabled.
func (client pageBlobClient) Create(ctx context.Context, contentLength int64, blobContentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, blobSequenceNumber *int64, requestID *string) (*PageBlobCreateResponse, error) { func (client pageBlobClient) Create(ctx context.Context, contentLength int64, blobContentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, blobSequenceNumber *int64, requestID *string) (*PageBlobCreateResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.createPreparer(contentLength, blobContentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobSequenceNumber, requestID) req, err := client.createPreparer(contentLength, blobContentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, blobSequenceNumber, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -252,7 +242,7 @@ func (client pageBlobClient) Create(ctx context.Context, contentLength int64, bl
} }
// createPreparer prepares the Create request. // createPreparer prepares the Create request.
func (client pageBlobClient) createPreparer(contentLength int64, blobContentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, blobSequenceNumber *int64, requestID *string) (pipeline.Request, error) { func (client pageBlobClient) createPreparer(contentLength int64, blobContentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, blobSequenceNumber *int64, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -295,8 +285,8 @@ func (client pageBlobClient) createPreparer(contentLength int64, blobContentLeng
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -333,21 +323,21 @@ func (client pageBlobClient) createResponder(resp pipeline.Response) (pipeline.R
// a Snapshot of a Blob.</a> timeout is the timeout parameter is expressed in seconds. For more information, see <a // 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 // 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 // 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. // range. leaseID is if specified, the operation only succeeds if the resource'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 // 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 // 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. // since the specified date/time. ifMatch 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 // 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 // client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage
// analytics logging is enabled. // analytics logging is enabled.
func (client pageBlobClient) GetPageRanges(ctx context.Context, snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageList, error) { func (client pageBlobClient) GetPageRanges(ctx context.Context, snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageList, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.getPageRangesPreparer(snapshot, timeout, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.getPageRangesPreparer(snapshot, timeout, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -359,7 +349,7 @@ func (client pageBlobClient) GetPageRanges(ctx context.Context, snapshot *string
} }
// getPageRangesPreparer prepares the GetPageRanges request. // getPageRangesPreparer prepares the GetPageRanges request.
func (client pageBlobClient) getPageRangesPreparer(snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client pageBlobClient) getPageRangesPreparer(snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("GET", client.url, nil) req, err := pipeline.NewRequest("GET", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -385,8 +375,8 @@ func (client pageBlobClient) getPageRangesPreparer(snapshot *string, timeout *in
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -411,7 +401,7 @@ func (client pageBlobClient) getPageRangesResponder(resp pipeline.Response) (pip
defer resp.Response().Body.Close() defer resp.Response().Body.Close()
b, err := ioutil.ReadAll(resp.Response().Body) b, err := ioutil.ReadAll(resp.Response().Body)
if err != nil { if err != nil {
return result, NewResponseError(err, resp.Response(), "failed to read response body") return result, err
} }
if len(b) > 0 { if len(b) > 0 {
b = removeBOM(b) b = removeBOM(b)
@ -436,21 +426,21 @@ func (client pageBlobClient) getPageRangesResponder(resp pipeline.Response) (pip
// target blob and previous snapshot. Changed pages include both updated and cleared pages. The target blob may be a // 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 // 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 // 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 // of the blob in the specified range. leaseID is if specified, the operation only succeeds if the resource's lease is
// active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it has been // 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 // 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 // it has not been modified since the specified date/time. ifMatch 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. // 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 // 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. // logs when storage analytics logging is enabled.
func (client pageBlobClient) GetPageRangesDiff(ctx context.Context, snapshot *string, timeout *int32, prevsnapshot *string, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageList, error) { func (client pageBlobClient) GetPageRangesDiff(ctx context.Context, snapshot *string, timeout *int32, prevsnapshot *string, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageList, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.getPageRangesDiffPreparer(snapshot, timeout, prevsnapshot, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.getPageRangesDiffPreparer(snapshot, timeout, prevsnapshot, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -462,7 +452,7 @@ func (client pageBlobClient) GetPageRangesDiff(ctx context.Context, snapshot *st
} }
// getPageRangesDiffPreparer prepares the GetPageRangesDiff request. // getPageRangesDiffPreparer prepares the GetPageRangesDiff request.
func (client pageBlobClient) getPageRangesDiffPreparer(snapshot *string, timeout *int32, prevsnapshot *string, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client pageBlobClient) getPageRangesDiffPreparer(snapshot *string, timeout *int32, prevsnapshot *string, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("GET", client.url, nil) req, err := pipeline.NewRequest("GET", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -491,8 +481,8 @@ func (client pageBlobClient) getPageRangesDiffPreparer(snapshot *string, timeout
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -517,7 +507,7 @@ func (client pageBlobClient) getPageRangesDiffResponder(resp pipeline.Response)
defer resp.Response().Body.Close() defer resp.Response().Body.Close()
b, err := ioutil.ReadAll(resp.Response().Body) b, err := ioutil.ReadAll(resp.Response().Body)
if err != nil { if err != nil {
return result, NewResponseError(err, resp.Response(), "failed to read response body") return result, err
} }
if len(b) > 0 { if len(b) > 0 {
b = removeBOM(b) b = removeBOM(b)
@ -535,21 +525,21 @@ func (client pageBlobClient) getPageRangesDiffResponder(resp pipeline.Response)
// be aligned to a 512-byte boundary. timeout is the timeout parameter is expressed in seconds. For more information, // be aligned to a 512-byte boundary. timeout is the timeout parameter is expressed in seconds. For more information,
// see <a // see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it // 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 // 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 // blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate only on
// on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching // blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value.
// value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the // requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics
// analytics logs when storage analytics logging is enabled. // logs when storage analytics logging is enabled.
func (client pageBlobClient) Resize(ctx context.Context, blobContentLength int64, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobResizeResponse, error) { func (client pageBlobClient) Resize(ctx context.Context, blobContentLength int64, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobResizeResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.resizePreparer(blobContentLength, timeout, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.resizePreparer(blobContentLength, timeout, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -561,7 +551,7 @@ func (client pageBlobClient) Resize(ctx context.Context, blobContentLength int64
} }
// resizePreparer prepares the Resize request. // resizePreparer prepares the Resize request.
func (client pageBlobClient) resizePreparer(blobContentLength int64, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client pageBlobClient) resizePreparer(blobContentLength int64, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -581,8 +571,8 @@ func (client pageBlobClient) resizePreparer(blobContentLength int64, timeout *in
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -612,23 +602,23 @@ func (client pageBlobClient) resizeResponder(resp pipeline.Response) (pipeline.R
// applies to page blobs only. This property indicates how the service should modify the blob's sequence number timeout // applies to page blobs only. This property indicates how the service should modify the blob's sequence number timeout
// is the timeout parameter is expressed in seconds. For more information, see <a // 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 // 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 // Timeouts for Blob Service Operations.</a> leaseID is if specified, the operation only succeeds if the resource's
// lease is active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it // 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 // 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 // blob if it has not been modified since the specified date/time. ifMatch is specify an ETag value to operate only on
// on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching // blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value.
// value. blobSequenceNumber is set for page blobs only. The sequence number is a user-controlled value that you can // blobSequenceNumber is set for page blobs only. The sequence number is a user-controlled value that you can use to
// use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. requestID is provides a // track requests. The value of the sequence number must be between 0 and 2^63 - 1. requestID is provides a
// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage // client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage
// analytics logging is enabled. // analytics logging is enabled.
func (client pageBlobClient) UpdateSequenceNumber(ctx context.Context, sequenceNumberAction SequenceNumberActionType, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, blobSequenceNumber *int64, requestID *string) (*PageBlobUpdateSequenceNumberResponse, error) { func (client pageBlobClient) UpdateSequenceNumber(ctx context.Context, sequenceNumberAction SequenceNumberActionType, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, blobSequenceNumber *int64, requestID *string) (*PageBlobUpdateSequenceNumberResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: timeout, {targetValue: timeout,
constraints: []constraint{{target: "timeout", name: null, rule: false, constraints: []constraint{{target: "timeout", name: null, rule: false,
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.updateSequenceNumberPreparer(sequenceNumberAction, timeout, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobSequenceNumber, requestID) req, err := client.updateSequenceNumberPreparer(sequenceNumberAction, timeout, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, blobSequenceNumber, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -640,7 +630,7 @@ func (client pageBlobClient) UpdateSequenceNumber(ctx context.Context, sequenceN
} }
// updateSequenceNumberPreparer prepares the UpdateSequenceNumber request. // updateSequenceNumberPreparer prepares the UpdateSequenceNumber request.
func (client pageBlobClient) updateSequenceNumberPreparer(sequenceNumberAction SequenceNumberActionType, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, blobSequenceNumber *int64, requestID *string) (pipeline.Request, error) { func (client pageBlobClient) updateSequenceNumberPreparer(sequenceNumberAction SequenceNumberActionType, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, blobSequenceNumber *int64, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, nil) req, err := pipeline.NewRequest("PUT", client.url, nil)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -660,8 +650,8 @@ func (client pageBlobClient) updateSequenceNumberPreparer(sequenceNumberAction S
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))
@ -696,17 +686,17 @@ func (client pageBlobClient) updateSequenceNumberResponder(resp pipeline.Respons
// information, see <a // information, see <a
// href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting // 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 // 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. // range. leaseID is if specified, the operation only succeeds if the resource'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 // 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 // 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 // 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 // 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 // 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 // operate only on a blob if it has not been modified since the specified date/time. ifMatch 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 // 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 // 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. // recorded in the analytics logs when storage analytics logging is enabled.
func (client pageBlobClient) UploadPages(ctx context.Context, body io.ReadSeeker, contentLength int64, transactionalContentMD5 []byte, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobUploadPagesResponse, error) { func (client pageBlobClient) UploadPages(ctx context.Context, body io.ReadSeeker, contentLength int64, transactionalContentMD5 []byte, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobUploadPagesResponse, error) {
if err := validate([]validation{ if err := validate([]validation{
{targetValue: body, {targetValue: body,
constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}}, constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}},
@ -715,7 +705,7 @@ func (client pageBlobClient) UploadPages(ctx context.Context, body io.ReadSeeker
chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil {
return nil, err return nil, err
} }
req, err := client.uploadPagesPreparer(body, contentLength, transactionalContentMD5, timeout, rangeParameter, leaseID, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) req, err := client.uploadPagesPreparer(body, contentLength, transactionalContentMD5, timeout, rangeParameter, leaseID, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, requestID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -727,7 +717,7 @@ func (client pageBlobClient) UploadPages(ctx context.Context, body io.ReadSeeker
} }
// uploadPagesPreparer prepares the UploadPages request. // uploadPagesPreparer prepares the UploadPages request.
func (client pageBlobClient) uploadPagesPreparer(body io.ReadSeeker, contentLength int64, transactionalContentMD5 []byte, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { func (client pageBlobClient) uploadPagesPreparer(body io.ReadSeeker, contentLength int64, transactionalContentMD5 []byte, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatch *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) {
req, err := pipeline.NewRequest("PUT", client.url, body) req, err := pipeline.NewRequest("PUT", client.url, body)
if err != nil { if err != nil {
return req, pipeline.NewError(err, "failed to create request") return req, pipeline.NewError(err, "failed to create request")
@ -763,8 +753,8 @@ func (client pageBlobClient) uploadPagesPreparer(body io.ReadSeeker, contentLeng
if ifUnmodifiedSince != nil { if ifUnmodifiedSince != nil {
req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123))
} }
if ifMatches != nil { if ifMatch != nil {
req.Header.Set("If-Match", string(*ifMatches)) req.Header.Set("If-Match", string(*ifMatch))
} }
if ifNoneMatch != nil { if ifNoneMatch != nil {
req.Header.Set("If-None-Match", string(*ifNoneMatch)) req.Header.Set("If-None-Match", string(*ifNoneMatch))

View file

@ -55,7 +55,7 @@ func validateResponse(resp pipeline.Response, successStatusCodes ...int) error {
defer resp.Response().Body.Close() defer resp.Response().Body.Close()
b, err := ioutil.ReadAll(resp.Response().Body) b, err := ioutil.ReadAll(resp.Response().Body)
if err != nil { if err != nil {
return NewResponseError(err, resp.Response(), "failed to read response body") return err
} }
// the service code, description and details will be populated during unmarshalling // the service code, description and details will be populated during unmarshalling
responseError := NewResponseError(nil, resp.Response(), resp.Response().Status) responseError := NewResponseError(nil, resp.Response(), resp.Response().Status)

View file

@ -121,7 +121,7 @@ func (client serviceClient) getPropertiesResponder(resp pipeline.Response) (pipe
defer resp.Response().Body.Close() defer resp.Response().Body.Close()
b, err := ioutil.ReadAll(resp.Response().Body) b, err := ioutil.ReadAll(resp.Response().Body)
if err != nil { if err != nil {
return result, NewResponseError(err, resp.Response(), "failed to read response body") return result, err
} }
if len(b) > 0 { if len(b) > 0 {
b = removeBOM(b) b = removeBOM(b)
@ -191,7 +191,7 @@ func (client serviceClient) getStatisticsResponder(resp pipeline.Response) (pipe
defer resp.Response().Body.Close() defer resp.Response().Body.Close()
b, err := ioutil.ReadAll(resp.Response().Body) b, err := ioutil.ReadAll(resp.Response().Body)
if err != nil { if err != nil {
return result, NewResponseError(err, resp.Response(), "failed to read response body") return result, err
} }
if len(b) > 0 { if len(b) > 0 {
b = removeBOM(b) b = removeBOM(b)
@ -286,7 +286,7 @@ func (client serviceClient) listContainersSegmentResponder(resp pipeline.Respons
defer resp.Response().Body.Close() defer resp.Response().Body.Close()
b, err := ioutil.ReadAll(resp.Response().Body) b, err := ioutil.ReadAll(resp.Response().Body)
if err != nil { if err != nil {
return result, NewResponseError(err, resp.Response(), "failed to read response body") return result, err
} }
if len(b) > 0 { if len(b) > 0 {
b = removeBOM(b) b = removeBOM(b)

View file

@ -18,7 +18,7 @@ const UseServiceDefaultRetries = -1
type RequestRetryer interface{} type RequestRetryer interface{}
// A Config provides service configuration for service clients. By default, // A Config provides service configuration for service clients. By default,
// all clients will use the defaults.DefaultConfig tructure. // all clients will use the defaults.DefaultConfig structure.
// //
// // Create Session with MaxRetry configuration to be shared by multiple // // Create Session with MaxRetry configuration to be shared by multiple
// // service clients. // // service clients.

View file

@ -65,6 +65,10 @@ type Provider struct {
// //
// If ExpiryWindow is 0 or less it will be ignored. // If ExpiryWindow is 0 or less it will be ignored.
ExpiryWindow time.Duration ExpiryWindow time.Duration
// Optional authorization token value if set will be used as the value of
// the Authorization header of the endpoint credential request.
AuthorizationToken string
} }
// NewProviderClient returns a credentials Provider for retrieving AWS credentials // NewProviderClient returns a credentials Provider for retrieving AWS credentials
@ -152,6 +156,9 @@ func (p *Provider) getCredentials() (*getCredentialsOutput, error) {
out := &getCredentialsOutput{} out := &getCredentialsOutput{}
req := p.Client.NewRequest(op, nil, out) req := p.Client.NewRequest(op, nil, out)
req.HTTPRequest.Header.Set("Accept", "application/json") req.HTTPRequest.Header.Set("Accept", "application/json")
if authToken := p.AuthorizationToken; len(authToken) != 0 {
req.HTTPRequest.Header.Set("Authorization", authToken)
}
return out, req.Send() return out, req.Send()
} }

View file

@ -4,9 +4,8 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/go-ini/ini"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/internal/ini"
"github.com/aws/aws-sdk-go/internal/shareddefaults" "github.com/aws/aws-sdk-go/internal/shareddefaults"
) )
@ -77,36 +76,37 @@ func (p *SharedCredentialsProvider) IsExpired() bool {
// The credentials retrieved from the profile will be returned or error. Error will be // The credentials retrieved from the profile will be returned or error. Error will be
// returned if it fails to read from the file, or the data is invalid. // returned if it fails to read from the file, or the data is invalid.
func loadProfile(filename, profile string) (Value, error) { func loadProfile(filename, profile string) (Value, error) {
config, err := ini.Load(filename) config, err := ini.OpenFile(filename)
if err != nil { if err != nil {
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err) return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err)
} }
iniProfile, err := config.GetSection(profile)
if err != nil { iniProfile, ok := config.GetSection(profile)
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", err) if !ok {
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", nil)
} }
id, err := iniProfile.GetKey("aws_access_key_id") id := iniProfile.String("aws_access_key_id")
if err != nil { if len(id) == 0 {
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsAccessKey", return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsAccessKey",
fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename), fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename),
err) nil)
} }
secret, err := iniProfile.GetKey("aws_secret_access_key") secret := iniProfile.String("aws_secret_access_key")
if err != nil { if len(secret) == 0 {
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsSecret", return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsSecret",
fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename), fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename),
nil) nil)
} }
// Default to empty string if not found // Default to empty string if not found
token := iniProfile.Key("aws_session_token") token := iniProfile.String("aws_session_token")
return Value{ return Value{
AccessKeyID: id.String(), AccessKeyID: id,
SecretAccessKey: secret.String(), SecretAccessKey: secret,
SessionToken: token.String(), SessionToken: token,
ProviderName: SharedCredsProviderName, ProviderName: SharedCredsProviderName,
}, nil }, nil
} }

View file

@ -48,4 +48,6 @@ type metric struct {
DNSLatency *int `json:"DnsLatency,omitempty"` DNSLatency *int `json:"DnsLatency,omitempty"`
TCPLatency *int `json:"TcpLatency,omitempty"` TCPLatency *int `json:"TcpLatency,omitempty"`
SSLLatency *int `json:"SslLatency,omitempty"` SSLLatency *int `json:"SslLatency,omitempty"`
MaxRetriesExceeded *int `json:"MaxRetriesExceeded,omitempty"`
} }

View file

@ -112,14 +112,16 @@ func (rep *Reporter) sendAPICallMetric(r *request.Request) {
now := time.Now() now := time.Now()
m := metric{ m := metric{
ClientID: aws.String(rep.clientID), ClientID: aws.String(rep.clientID),
API: aws.String(r.Operation.Name), API: aws.String(r.Operation.Name),
Service: aws.String(r.ClientInfo.ServiceID), Service: aws.String(r.ClientInfo.ServiceID),
Timestamp: (*metricTime)(&now), Timestamp: (*metricTime)(&now),
Type: aws.String("ApiCall"), Type: aws.String("ApiCall"),
AttemptCount: aws.Int(r.RetryCount + 1), AttemptCount: aws.Int(r.RetryCount + 1),
Latency: aws.Int(int(time.Now().Sub(r.Time) / time.Millisecond)), Region: r.Config.Region,
XAmzRequestID: aws.String(r.RequestID), Latency: aws.Int(int(time.Now().Sub(r.Time) / time.Millisecond)),
XAmzRequestID: aws.String(r.RequestID),
MaxRetriesExceeded: aws.Int(boolIntValue(r.RetryCount >= r.MaxRetries())),
} }
// TODO: Probably want to figure something out for logging dropped // TODO: Probably want to figure something out for logging dropped
@ -229,3 +231,12 @@ func (rep *Reporter) InjectHandlers(handlers *request.Handlers) {
handlers.AfterRetry.PushFrontNamed(apiCallAttemptHandler) handlers.AfterRetry.PushFrontNamed(apiCallAttemptHandler)
} }
// boolIntValue return 1 for true and 0 for false.
func boolIntValue(b bool) int {
if b {
return 1
}
return 0
}

View file

@ -24,6 +24,7 @@ import (
"github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/shareddefaults"
) )
// A Defaults provides a collection of default values for SDK clients. // A Defaults provides a collection of default values for SDK clients.
@ -112,8 +113,8 @@ func CredProviders(cfg *aws.Config, handlers request.Handlers) []credentials.Pro
} }
const ( const (
httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI" httpProviderAuthorizationEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN"
ecsCredsProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
) )
// RemoteCredProvider returns a credentials provider for the default remote // RemoteCredProvider returns a credentials provider for the default remote
@ -123,8 +124,8 @@ func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.P
return localHTTPCredProvider(cfg, handlers, u) return localHTTPCredProvider(cfg, handlers, u)
} }
if uri := os.Getenv(ecsCredsProviderEnvVar); len(uri) > 0 { if uri := os.Getenv(shareddefaults.ECSCredsProviderEnvVar); len(uri) > 0 {
u := fmt.Sprintf("http://169.254.170.2%s", uri) u := fmt.Sprintf("%s%s", shareddefaults.ECSContainerCredentialsURI, uri)
return httpCredProvider(cfg, handlers, u) return httpCredProvider(cfg, handlers, u)
} }
@ -187,6 +188,7 @@ func httpCredProvider(cfg aws.Config, handlers request.Handlers, u string) crede
return endpointcreds.NewProviderClient(cfg, handlers, u, return endpointcreds.NewProviderClient(cfg, handlers, u,
func(p *endpointcreds.Provider) { func(p *endpointcreds.Provider) {
p.ExpiryWindow = 5 * time.Minute p.ExpiryWindow = 5 * time.Minute
p.AuthorizationToken = os.Getenv(httpProviderAuthorizationEnvVar)
}, },
) )
} }

View file

@ -72,6 +72,7 @@ func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
cfg, cfg,
metadata.ClientInfo{ metadata.ClientInfo{
ServiceName: ServiceName, ServiceName: ServiceName,
ServiceID: ServiceName,
Endpoint: endpoint, Endpoint: endpoint,
APIVersion: "latest", APIVersion: "latest",
}, },

View file

@ -761,6 +761,7 @@ var awsPartition = partition{
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
@ -777,6 +778,7 @@ var awsPartition = partition{
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
@ -1282,7 +1284,6 @@ var awsPartition = partition{
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
@ -1415,10 +1416,11 @@ var awsPartition = partition{
"iotanalytics": service{ "iotanalytics": service{
Endpoints: endpoints{ Endpoints: endpoints{
"eu-west-1": endpoint{}, "ap-northeast-1": endpoint{},
"us-east-1": endpoint{}, "eu-west-1": endpoint{},
"us-east-2": endpoint{}, "us-east-1": endpoint{},
"us-west-2": endpoint{}, "us-east-2": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"kinesis": service{ "kinesis": service{
@ -1597,6 +1599,7 @@ var awsPartition = partition{
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"sa-east-1": endpoint{}, "sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
@ -1701,6 +1704,12 @@ var awsPartition = partition{
Region: "eu-west-1", Region: "eu-west-1",
}, },
}, },
"eu-west-2": endpoint{
Hostname: "rds.eu-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "eu-west-2",
},
},
"us-east-1": endpoint{ "us-east-1": endpoint{
Hostname: "rds.us-east-1.amazonaws.com", Hostname: "rds.us-east-1.amazonaws.com",
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -2100,20 +2109,49 @@ var awsPartition = partition{
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"sa-east-1": endpoint{}, "sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-1-fips": endpoint{
"us-west-1": endpoint{}, Hostname: "servicecatalog-fips.us-east-1.amazonaws.com",
"us-west-2": endpoint{}, CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"us-east-2": endpoint{},
"us-east-2-fips": endpoint{
Hostname: "servicecatalog-fips.us-east-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-2",
},
},
"us-west-1": endpoint{},
"us-west-1-fips": endpoint{
Hostname: "servicecatalog-fips.us-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-1",
},
},
"us-west-2": endpoint{},
"us-west-2-fips": endpoint{
Hostname: "servicecatalog-fips.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
}, },
}, },
"servicediscovery": service{ "servicediscovery": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
@ -2618,6 +2656,13 @@ var awscnPartition = partition{
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{},
}, },
}, },
"codebuild": service{
Endpoints: endpoints{
"cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
},
},
"codedeploy": service{ "codedeploy": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -2939,6 +2984,12 @@ var awsusgovPartition = partition{
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
"api.sagemaker": service{
Endpoints: endpoints{
"us-gov-west-1": endpoint{},
},
},
"apigateway": service{ "apigateway": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -3199,6 +3250,12 @@ var awsusgovPartition = partition{
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
"runtime.sagemaker": service{
Endpoints: endpoints{
"us-gov-west-1": endpoint{},
},
},
"s3": service{ "s3": service{
Defaults: endpoint{ Defaults: endpoint{
SignatureVersions: []string{"s3", "s3v4"}, SignatureVersions: []string{"s3", "s3v4"},

View file

@ -17,6 +17,10 @@ const (
ParamMinValueErrCode = "ParamMinValueError" ParamMinValueErrCode = "ParamMinValueError"
// ParamMinLenErrCode is the error code for fields without enough elements. // ParamMinLenErrCode is the error code for fields without enough elements.
ParamMinLenErrCode = "ParamMinLenError" ParamMinLenErrCode = "ParamMinLenError"
// ParamFormatErrCode is the error code for a field with invalid
// format or characters.
ParamFormatErrCode = "ParamFormatInvalidError"
) )
// Validator provides a way for types to perform validation logic on their // Validator provides a way for types to perform validation logic on their
@ -232,3 +236,26 @@ func NewErrParamMinLen(field string, min int) *ErrParamMinLen {
func (e *ErrParamMinLen) MinLen() int { func (e *ErrParamMinLen) MinLen() int {
return e.min return e.min
} }
// An ErrParamFormat represents a invalid format parameter error.
type ErrParamFormat struct {
errInvalidParam
format string
}
// NewErrParamFormat creates a new invalid format parameter error.
func NewErrParamFormat(field string, format, value string) *ErrParamFormat {
return &ErrParamFormat{
errInvalidParam: errInvalidParam{
code: ParamFormatErrCode,
field: field,
msg: fmt.Sprintf("format %v, %v", format, value),
},
format: format,
}
}
// Format returns the field's required format.
func (e *ErrParamFormat) Format() string {
return e.format
}

View file

@ -19,8 +19,26 @@ import (
"github.com/aws/aws-sdk-go/aws/defaults" "github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/shareddefaults"
) )
const (
// ErrCodeSharedConfig represents an error that occurs in the shared
// configuration logic
ErrCodeSharedConfig = "SharedConfigErr"
)
// ErrSharedConfigSourceCollision will be returned if a section contains both
// source_profile and credential_source
var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only source profile or credential source can be specified, not both", nil)
// ErrSharedConfigECSContainerEnvVarEmpty will be returned if the environment
// variables are empty and Environment was set as the credential source
var ErrSharedConfigECSContainerEnvVarEmpty = awserr.New(ErrCodeSharedConfig, "EcsContainer was specified as the credential_source, but 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI' was not set", nil)
// ErrSharedConfigInvalidCredSource will be returned if an invalid credential source was provided
var ErrSharedConfigInvalidCredSource = awserr.New(ErrCodeSharedConfig, "credential source values must be EcsContainer, Ec2InstanceMetadata, or Environment", nil)
// A Session provides a central location to create service clients from and // A Session provides a central location to create service clients from and
// store configurations and request handlers for those services. // store configurations and request handlers for those services.
// //
@ -436,6 +454,57 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg share
// Configure credentials if not already set // Configure credentials if not already set
if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil { if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
// inspect the profile to see if a credential source has been specified.
if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.CredentialSource) > 0 {
// if both credential_source and source_profile have been set, return an error
// as this is undefined behavior.
if len(sharedCfg.AssumeRole.SourceProfile) > 0 {
return ErrSharedConfigSourceCollision
}
// valid credential source values
const (
credSourceEc2Metadata = "Ec2InstanceMetadata"
credSourceEnvironment = "Environment"
credSourceECSContainer = "EcsContainer"
)
switch sharedCfg.AssumeRole.CredentialSource {
case credSourceEc2Metadata:
cfgCp := *cfg
p := defaults.RemoteCredProvider(cfgCp, handlers)
cfgCp.Credentials = credentials.NewCredentials(p)
if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
// AssumeRole Token provider is required if doing Assume Role
// with MFA.
return AssumeRoleTokenProviderNotSetError{}
}
cfg.Credentials = assumeRoleCredentials(cfgCp, handlers, sharedCfg, sessOpts)
case credSourceEnvironment:
cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
envCfg.Creds,
)
case credSourceECSContainer:
if len(os.Getenv(shareddefaults.ECSCredsProviderEnvVar)) == 0 {
return ErrSharedConfigECSContainerEnvVarEmpty
}
cfgCp := *cfg
p := defaults.RemoteCredProvider(cfgCp, handlers)
creds := credentials.NewCredentials(p)
cfg.Credentials = creds
default:
return ErrSharedConfigInvalidCredSource
}
return nil
}
if len(envCfg.Creds.AccessKeyID) > 0 { if len(envCfg.Creds.AccessKeyID) > 0 {
cfg.Credentials = credentials.NewStaticCredentialsFromCreds( cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
envCfg.Creds, envCfg.Creds,
@ -445,32 +514,14 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg share
cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds( cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds(
sharedCfg.AssumeRoleSource.Creds, sharedCfg.AssumeRoleSource.Creds,
) )
if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil { if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
// AssumeRole Token provider is required if doing Assume Role // AssumeRole Token provider is required if doing Assume Role
// with MFA. // with MFA.
return AssumeRoleTokenProviderNotSetError{} return AssumeRoleTokenProviderNotSetError{}
} }
cfg.Credentials = stscreds.NewCredentials(
&Session{
Config: &cfgCp,
Handlers: handlers.Copy(),
},
sharedCfg.AssumeRole.RoleARN,
func(opt *stscreds.AssumeRoleProvider) {
opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName
// Assume role with external ID cfg.Credentials = assumeRoleCredentials(cfgCp, handlers, sharedCfg, sessOpts)
if len(sharedCfg.AssumeRole.ExternalID) > 0 {
opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID)
}
// Assume role with MFA
if len(sharedCfg.AssumeRole.MFASerial) > 0 {
opt.SerialNumber = aws.String(sharedCfg.AssumeRole.MFASerial)
opt.TokenProvider = sessOpts.AssumeRoleTokenProvider
}
},
)
} else if len(sharedCfg.Creds.AccessKeyID) > 0 { } else if len(sharedCfg.Creds.AccessKeyID) > 0 {
cfg.Credentials = credentials.NewStaticCredentialsFromCreds( cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
sharedCfg.Creds, sharedCfg.Creds,
@ -493,6 +544,30 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg share
return nil return nil
} }
func assumeRoleCredentials(cfg aws.Config, handlers request.Handlers, sharedCfg sharedConfig, sessOpts Options) *credentials.Credentials {
return stscreds.NewCredentials(
&Session{
Config: &cfg,
Handlers: handlers.Copy(),
},
sharedCfg.AssumeRole.RoleARN,
func(opt *stscreds.AssumeRoleProvider) {
opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName
// Assume role with external ID
if len(sharedCfg.AssumeRole.ExternalID) > 0 {
opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID)
}
// Assume role with MFA
if len(sharedCfg.AssumeRole.MFASerial) > 0 {
opt.SerialNumber = aws.String(sharedCfg.AssumeRole.MFASerial)
opt.TokenProvider = sessOpts.AssumeRoleTokenProvider
}
},
)
}
// AssumeRoleTokenProviderNotSetError is an error returned when creating a session when the // AssumeRoleTokenProviderNotSetError is an error returned when creating a session when the
// MFAToken option is not set when shared config is configured load assume a // MFAToken option is not set when shared config is configured load assume a
// role with an MFA token. // role with an MFA token.

View file

@ -2,11 +2,11 @@ package session
import ( import (
"fmt" "fmt"
"io/ioutil"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/go-ini/ini"
"github.com/aws/aws-sdk-go/internal/ini"
) )
const ( const (
@ -16,11 +16,12 @@ const (
sessionTokenKey = `aws_session_token` // optional sessionTokenKey = `aws_session_token` // optional
// Assume Role Credentials group // Assume Role Credentials group
roleArnKey = `role_arn` // group required roleArnKey = `role_arn` // group required
sourceProfileKey = `source_profile` // group required sourceProfileKey = `source_profile` // group required (or credential_source)
externalIDKey = `external_id` // optional credentialSourceKey = `credential_source` // group required (or source_profile)
mfaSerialKey = `mfa_serial` // optional externalIDKey = `external_id` // optional
roleSessionNameKey = `role_session_name` // optional mfaSerialKey = `mfa_serial` // optional
roleSessionNameKey = `role_session_name` // optional
// Additional Config fields // Additional Config fields
regionKey = `region` regionKey = `region`
@ -32,11 +33,12 @@ const (
) )
type assumeRoleConfig struct { type assumeRoleConfig struct {
RoleARN string RoleARN string
SourceProfile string SourceProfile string
ExternalID string CredentialSource string
MFASerial string ExternalID string
RoleSessionName string MFASerial string
RoleSessionName string
} }
// sharedConfig represents the configuration fields of the SDK config files. // sharedConfig represents the configuration fields of the SDK config files.
@ -64,7 +66,7 @@ type sharedConfig struct {
type sharedConfigFile struct { type sharedConfigFile struct {
Filename string Filename string
IniData *ini.File IniData ini.Sections
} }
// loadSharedConfig retrieves the configuration from the list of files // loadSharedConfig retrieves the configuration from the list of files
@ -105,19 +107,16 @@ func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) {
files := make([]sharedConfigFile, 0, len(filenames)) files := make([]sharedConfigFile, 0, len(filenames))
for _, filename := range filenames { for _, filename := range filenames {
b, err := ioutil.ReadFile(filename) sections, err := ini.OpenFile(filename)
if err != nil { if aerr, ok := err.(awserr.Error); ok && aerr.Code() == ini.ErrCodeUnableToReadFile {
// Skip files which can't be opened and read for whatever reason // Skip files which can't be opened and read for whatever reason
continue continue
} } else if err != nil {
f, err := ini.Load(b)
if err != nil {
return nil, SharedConfigLoadError{Filename: filename, Err: err} return nil, SharedConfigLoadError{Filename: filename, Err: err}
} }
files = append(files, sharedConfigFile{ files = append(files, sharedConfigFile{
Filename: filename, IniData: f, Filename: filename, IniData: sections,
}) })
} }
@ -127,6 +126,13 @@ func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) {
func (cfg *sharedConfig) setAssumeRoleSource(origProfile string, files []sharedConfigFile) error { func (cfg *sharedConfig) setAssumeRoleSource(origProfile string, files []sharedConfigFile) error {
var assumeRoleSrc sharedConfig var assumeRoleSrc sharedConfig
if len(cfg.AssumeRole.CredentialSource) > 0 {
// setAssumeRoleSource is only called when source_profile is found.
// If both source_profile and credential_source are set, then
// ErrSharedConfigSourceCollision will be returned
return ErrSharedConfigSourceCollision
}
// Multiple level assume role chains are not support // Multiple level assume role chains are not support
if cfg.AssumeRole.SourceProfile == origProfile { if cfg.AssumeRole.SourceProfile == origProfile {
assumeRoleSrc = *cfg assumeRoleSrc = *cfg
@ -171,42 +177,45 @@ func (cfg *sharedConfig) setFromIniFiles(profile string, files []sharedConfigFil
// if a config file only includes aws_access_key_id but no aws_secret_access_key // if a config file only includes aws_access_key_id but no aws_secret_access_key
// the aws_access_key_id will be ignored. // the aws_access_key_id will be ignored.
func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) error { func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) error {
section, err := file.IniData.GetSection(profile) section, ok := file.IniData.GetSection(profile)
if err != nil { if !ok {
// Fallback to to alternate profile name: profile <name> // Fallback to to alternate profile name: profile <name>
section, err = file.IniData.GetSection(fmt.Sprintf("profile %s", profile)) section, ok = file.IniData.GetSection(fmt.Sprintf("profile %s", profile))
if err != nil { if !ok {
return SharedConfigProfileNotExistsError{Profile: profile, Err: err} return SharedConfigProfileNotExistsError{Profile: profile, Err: nil}
} }
} }
// Shared Credentials // Shared Credentials
akid := section.Key(accessKeyIDKey).String() akid := section.String(accessKeyIDKey)
secret := section.Key(secretAccessKey).String() secret := section.String(secretAccessKey)
if len(akid) > 0 && len(secret) > 0 { if len(akid) > 0 && len(secret) > 0 {
cfg.Creds = credentials.Value{ cfg.Creds = credentials.Value{
AccessKeyID: akid, AccessKeyID: akid,
SecretAccessKey: secret, SecretAccessKey: secret,
SessionToken: section.Key(sessionTokenKey).String(), SessionToken: section.String(sessionTokenKey),
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename), ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename),
} }
} }
// Assume Role // Assume Role
roleArn := section.Key(roleArnKey).String() roleArn := section.String(roleArnKey)
srcProfile := section.Key(sourceProfileKey).String() srcProfile := section.String(sourceProfileKey)
if len(roleArn) > 0 && len(srcProfile) > 0 { credentialSource := section.String(credentialSourceKey)
hasSource := len(srcProfile) > 0 || len(credentialSource) > 0
if len(roleArn) > 0 && hasSource {
cfg.AssumeRole = assumeRoleConfig{ cfg.AssumeRole = assumeRoleConfig{
RoleARN: roleArn, RoleARN: roleArn,
SourceProfile: srcProfile, SourceProfile: srcProfile,
ExternalID: section.Key(externalIDKey).String(), CredentialSource: credentialSource,
MFASerial: section.Key(mfaSerialKey).String(), ExternalID: section.String(externalIDKey),
RoleSessionName: section.Key(roleSessionNameKey).String(), MFASerial: section.String(mfaSerialKey),
RoleSessionName: section.String(roleSessionNameKey),
} }
} }
// Region // Region
if v := section.Key(regionKey).String(); len(v) > 0 { if v := section.String(regionKey); len(v) > 0 {
cfg.Region = v cfg.Region = v
} }

View file

@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go" const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK // SDKVersion is the version of this SDK
const SDKVersion = "1.15.39" const SDKVersion = "1.15.62"

120
vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go generated vendored Normal file
View file

@ -0,0 +1,120 @@
package ini
// ASTKind represents different states in the parse table
// and the type of AST that is being constructed
type ASTKind int
// ASTKind* is used in the parse table to transition between
// the different states
const (
ASTKindNone = ASTKind(iota)
ASTKindStart
ASTKindExpr
ASTKindEqualExpr
ASTKindStatement
ASTKindSkipStatement
ASTKindExprStatement
ASTKindSectionStatement
ASTKindNestedSectionStatement
ASTKindCompletedNestedSectionStatement
ASTKindCommentStatement
ASTKindCompletedSectionStatement
)
func (k ASTKind) String() string {
switch k {
case ASTKindNone:
return "none"
case ASTKindStart:
return "start"
case ASTKindExpr:
return "expr"
case ASTKindStatement:
return "stmt"
case ASTKindSectionStatement:
return "section_stmt"
case ASTKindExprStatement:
return "expr_stmt"
case ASTKindCommentStatement:
return "comment"
case ASTKindNestedSectionStatement:
return "nested_section_stmt"
case ASTKindCompletedSectionStatement:
return "completed_stmt"
case ASTKindSkipStatement:
return "skip"
default:
return ""
}
}
// AST interface allows us to determine what kind of node we
// are on and casting may not need to be necessary.
//
// The root is always the first node in Children
type AST struct {
Kind ASTKind
Root Token
RootToken bool
Children []AST
}
func newAST(kind ASTKind, root AST, children ...AST) AST {
return AST{
Kind: kind,
Children: append([]AST{root}, children...),
}
}
func newASTWithRootToken(kind ASTKind, root Token, children ...AST) AST {
return AST{
Kind: kind,
Root: root,
RootToken: true,
Children: children,
}
}
// AppendChild will append to the list of children an AST has.
func (a *AST) AppendChild(child AST) {
a.Children = append(a.Children, child)
}
// GetRoot will return the root AST which can be the first entry
// in the children list or a token.
func (a *AST) GetRoot() AST {
if a.RootToken {
return *a
}
if len(a.Children) == 0 {
return AST{}
}
return a.Children[0]
}
// GetChildren will return the current AST's list of children
func (a *AST) GetChildren() []AST {
if len(a.Children) == 0 {
return []AST{}
}
if a.RootToken {
return a.Children
}
return a.Children[1:]
}
// SetChildren will set and override all children of the AST.
func (a *AST) SetChildren(children []AST) {
if a.RootToken {
a.Children = children
} else {
a.Children = append(a.Children[:1], children...)
}
}
// Start is used to indicate the starting state of the parse table.
var Start = newAST(ASTKindStart, AST{})

View file

@ -0,0 +1,11 @@
package ini
var commaRunes = []rune(",")
func isComma(b rune) bool {
return b == ','
}
func newCommaToken() Token {
return newToken(TokenComma, commaRunes, NoneType)
}

View file

@ -0,0 +1,39 @@
package ini
// isComment will return whether or not the next byte(s) is a
// comment.
func isComment(b []rune) bool {
if len(b) == 0 {
return false
}
switch b[0] {
case ';':
return true
case '#':
return true
case '/':
if len(b) > 1 {
return b[1] == '/'
}
}
return false
}
// newCommentToken will create a comment token and
// return how many bytes were read.
func newCommentToken(b []rune) (Token, int, error) {
i := 0
for ; i < len(b); i++ {
if b[i] == '\n' {
break
}
if len(b)-i > 2 && b[i] == '\r' && b[i+1] == '\n' {
break
}
}
return newToken(TokenComment, b[:i], NoneType), i, nil
}

30
vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go generated vendored Normal file
View file

@ -0,0 +1,30 @@
// Package ini is an LL(1) parser for configuration files.
//
// Example:
// sections, err := ini.OpenFile("/path/to/file")
// if err != nil {
// panic(err)
// }
//
// profile := "foo"
// section, ok := sections.GetSection(profile)
// if !ok {
// fmt.Printf("section %q could not be found", profile)
// }
//
// Below is the BNF that describes this parser
// Grammar:
// stmt -> value stmt'
// stmt' -> epsilon | op stmt
// value -> number | string | boolean | quoted_string
//
// section -> [ section'
// section' -> value section_close
// section_close -> ]
//
// SkipState will skip (NL WS)+
//
// comment -> # comment' | ; comment' | / comment_slash
// comment_slash -> / comment'
// comment' -> epsilon | value
package ini

View file

@ -0,0 +1,4 @@
package ini
// emptyToken is used to satisfy the Token interface
var emptyToken = newToken(TokenNone, []rune{}, NoneType)

View file

@ -0,0 +1,24 @@
package ini
// newExpression will return an expression AST.
// Expr represents an expression
//
// grammar:
// expr -> string | number
func newExpression(tok Token) AST {
return newASTWithRootToken(ASTKindExpr, tok)
}
func newEqualExpr(left AST, tok Token) AST {
return newASTWithRootToken(ASTKindEqualExpr, tok, left)
}
// EqualExprKey will return a LHS value in the equal expr
func EqualExprKey(ast AST) string {
children := ast.GetChildren()
if len(children) == 0 || ast.Kind != ASTKindEqualExpr {
return ""
}
return string(children[0].Root.Raw())
}

17
vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go generated vendored Normal file
View file

@ -0,0 +1,17 @@
// +build gofuzz
package ini
import (
"bytes"
)
func Fuzz(data []byte) int {
b := bytes.NewReader(data)
if _, err := Parse(b); err != nil {
return 0
}
return 1
}

51
vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go generated vendored Normal file
View file

@ -0,0 +1,51 @@
package ini
import (
"io"
"os"
"github.com/aws/aws-sdk-go/aws/awserr"
)
// OpenFile takes a path to a given file, and will open and parse
// that file.
func OpenFile(path string) (Sections, error) {
f, err := os.Open(path)
if err != nil {
return Sections{}, awserr.New(ErrCodeUnableToReadFile, "unable to open file", err)
}
defer f.Close()
return Parse(f)
}
// Parse will parse the given file using the shared config
// visitor.
func Parse(f io.Reader) (Sections, error) {
tree, err := ParseAST(f)
if err != nil {
return Sections{}, err
}
v := NewDefaultVisitor()
if err = Walk(tree, v); err != nil {
return Sections{}, err
}
return v.Sections, nil
}
// ParseBytes will parse the given bytes and return the parsed sections.
func ParseBytes(b []byte) (Sections, error) {
tree, err := ParseASTBytes(b)
if err != nil {
return Sections{}, err
}
v := NewDefaultVisitor()
if err = Walk(tree, v); err != nil {
return Sections{}, err
}
return v.Sections, nil
}

View file

@ -0,0 +1,165 @@
package ini
import (
"bytes"
"io"
"io/ioutil"
"github.com/aws/aws-sdk-go/aws/awserr"
)
const (
// ErrCodeUnableToReadFile is used when a file is failed to be
// opened or read from.
ErrCodeUnableToReadFile = "FailedRead"
)
// TokenType represents the various different tokens types
type TokenType int
func (t TokenType) String() string {
switch t {
case TokenNone:
return "none"
case TokenLit:
return "literal"
case TokenSep:
return "sep"
case TokenOp:
return "op"
case TokenWS:
return "ws"
case TokenNL:
return "newline"
case TokenComment:
return "comment"
case TokenComma:
return "comma"
default:
return ""
}
}
// TokenType enums
const (
TokenNone = TokenType(iota)
TokenLit
TokenSep
TokenComma
TokenOp
TokenWS
TokenNL
TokenComment
)
type iniLexer struct{}
// Tokenize will return a list of tokens during lexical analysis of the
// io.Reader.
func (l *iniLexer) Tokenize(r io.Reader) ([]Token, error) {
b, err := ioutil.ReadAll(r)
if err != nil {
return nil, awserr.New(ErrCodeUnableToReadFile, "unable to read file", err)
}
return l.tokenize(b)
}
func (l *iniLexer) tokenize(b []byte) ([]Token, error) {
runes := bytes.Runes(b)
var err error
n := 0
tokenAmount := countTokens(runes)
tokens := make([]Token, tokenAmount)
count := 0
for len(runes) > 0 && count < tokenAmount {
switch {
case isWhitespace(runes[0]):
tokens[count], n, err = newWSToken(runes)
case isComma(runes[0]):
tokens[count], n = newCommaToken(), 1
case isComment(runes):
tokens[count], n, err = newCommentToken(runes)
case isNewline(runes):
tokens[count], n, err = newNewlineToken(runes)
case isSep(runes):
tokens[count], n, err = newSepToken(runes)
case isOp(runes):
tokens[count], n, err = newOpToken(runes)
default:
tokens[count], n, err = newLitToken(runes)
}
if err != nil {
return nil, err
}
count++
runes = runes[n:]
}
return tokens[:count], nil
}
func countTokens(runes []rune) int {
count, n := 0, 0
var err error
for len(runes) > 0 {
switch {
case isWhitespace(runes[0]):
_, n, err = newWSToken(runes)
case isComma(runes[0]):
_, n = newCommaToken(), 1
case isComment(runes):
_, n, err = newCommentToken(runes)
case isNewline(runes):
_, n, err = newNewlineToken(runes)
case isSep(runes):
_, n, err = newSepToken(runes)
case isOp(runes):
_, n, err = newOpToken(runes)
default:
_, n, err = newLitToken(runes)
}
if err != nil {
return 0
}
count++
runes = runes[n:]
}
return count + 1
}
// Token indicates a metadata about a given value.
type Token struct {
t TokenType
ValueType ValueType
base int
raw []rune
}
var emptyValue = Value{}
func newToken(t TokenType, raw []rune, v ValueType) Token {
return Token{
t: t,
raw: raw,
ValueType: v,
}
}
// Raw return the raw runes that were consumed
func (tok Token) Raw() []rune {
return tok.raw
}
// Type returns the token type
func (tok Token) Type() TokenType {
return tok.t
}

View file

@ -0,0 +1,312 @@
package ini
import (
"fmt"
"io"
)
// State enums for the parse table
const (
InvalidState = iota
// stmt -> value stmt'
StatementState
// stmt' -> MarkComplete | op stmt
StatementPrimeState
// value -> number | string | boolean | quoted_string
ValueState
// section -> [ section'
OpenScopeState
// section' -> value section_close
SectionState
// section_close -> ]
CloseScopeState
// SkipState will skip (NL WS)+
SkipState
// SkipTokenState will skip any token and push the previous
// state onto the stack.
SkipTokenState
// comment -> # comment' | ; comment' | / comment_slash
// comment_slash -> / comment'
// comment' -> MarkComplete | value
CommentState
// MarkComplete state will complete statements and move that
// to the completed AST list
MarkCompleteState
// TerminalState signifies that the tokens have been fully parsed
TerminalState
)
// parseTable is a state machine to dictate the grammar above.
var parseTable = map[ASTKind]map[TokenType]int{
ASTKindStart: map[TokenType]int{
TokenLit: StatementState,
TokenSep: OpenScopeState,
TokenWS: SkipTokenState,
TokenNL: SkipTokenState,
TokenComment: CommentState,
TokenNone: TerminalState,
},
ASTKindCommentStatement: map[TokenType]int{
TokenLit: StatementState,
TokenSep: OpenScopeState,
TokenWS: SkipTokenState,
TokenNL: SkipTokenState,
TokenComment: CommentState,
TokenNone: MarkCompleteState,
},
ASTKindExpr: map[TokenType]int{
TokenOp: StatementPrimeState,
TokenLit: ValueState,
TokenSep: OpenScopeState,
TokenWS: SkipTokenState,
TokenNL: SkipState,
TokenComment: CommentState,
TokenNone: MarkCompleteState,
},
ASTKindEqualExpr: map[TokenType]int{
TokenLit: ValueState,
TokenWS: SkipTokenState,
TokenNL: SkipState,
},
ASTKindStatement: map[TokenType]int{
TokenLit: SectionState,
TokenSep: CloseScopeState,
TokenWS: SkipTokenState,
TokenNL: SkipTokenState,
TokenComment: CommentState,
TokenNone: MarkCompleteState,
},
ASTKindExprStatement: map[TokenType]int{
TokenLit: ValueState,
TokenSep: OpenScopeState,
TokenOp: ValueState,
TokenWS: ValueState,
TokenNL: MarkCompleteState,
TokenComment: CommentState,
TokenNone: TerminalState,
TokenComma: SkipState,
},
ASTKindSectionStatement: map[TokenType]int{
TokenLit: SectionState,
TokenSep: CloseScopeState,
TokenWS: SkipTokenState,
TokenNL: SkipTokenState,
},
ASTKindCompletedSectionStatement: map[TokenType]int{
TokenWS: SkipTokenState,
TokenNL: SkipTokenState,
TokenLit: StatementState,
TokenSep: OpenScopeState,
TokenComment: CommentState,
TokenNone: MarkCompleteState,
},
ASTKindSkipStatement: map[TokenType]int{
TokenLit: StatementState,
TokenSep: OpenScopeState,
TokenWS: SkipTokenState,
TokenNL: SkipTokenState,
TokenComment: CommentState,
TokenNone: TerminalState,
},
}
// ParseAST will parse input from an io.Reader using
// an LL(1) parser.
func ParseAST(r io.Reader) ([]AST, error) {
lexer := iniLexer{}
tokens, err := lexer.Tokenize(r)
if err != nil {
return []AST{}, err
}
return parse(tokens)
}
// ParseASTBytes will parse input from a byte slice using
// an LL(1) parser.
func ParseASTBytes(b []byte) ([]AST, error) {
lexer := iniLexer{}
tokens, err := lexer.tokenize(b)
if err != nil {
return []AST{}, err
}
return parse(tokens)
}
func parse(tokens []Token) ([]AST, error) {
start := Start
stack := newParseStack(3, len(tokens))
stack.Push(start)
s := newSkipper()
loop:
for stack.Len() > 0 {
k := stack.Pop()
var tok Token
if len(tokens) == 0 {
// this occurs when all the tokens have been processed
// but reduction of what's left on the stack needs to
// occur.
tok = emptyToken
} else {
tok = tokens[0]
}
step := parseTable[k.Kind][tok.Type()]
if s.ShouldSkip(tok) {
step = SkipTokenState
}
switch step {
case TerminalState:
// Finished parsing. Push what should be the last
// statement to the stack. If there is anything left
// on the stack, an error in parsing has occurred.
if k.Kind != ASTKindStart {
stack.MarkComplete(k)
}
break loop
case SkipTokenState:
// When skipping a token, the previous state was popped off the stack.
// To maintain the correct state, the previous state will be pushed
// onto the stack.
stack.Push(k)
case StatementState:
if k.Kind != ASTKindStart {
stack.MarkComplete(k)
}
expr := newExpression(tok)
stack.Push(expr)
case StatementPrimeState:
if tok.Type() != TokenOp {
stack.MarkComplete(k)
continue
}
if k.Kind != ASTKindExpr {
return nil, NewParseError(
fmt.Sprintf("invalid expression: expected Expr type, but found %T type", k),
)
}
expr := newEqualExpr(k, tok)
stack.Push(expr)
case ValueState:
// ValueState requires the previous state to either be an equal expression
// or an expression statement.
//
// This grammar occurs when the RHS is a number, word, or quoted string.
// equal_expr -> lit op equal_expr'
// equal_expr' -> number | string | quoted_string
// quoted_string -> " quoted_string'
// quoted_string' -> string quoted_string_end
// quoted_string_end -> "
//
// otherwise
// expr_stmt -> equal_expr (expr_stmt')*
// expr_stmt' -> ws S | op S | MarkComplete
// S -> equal_expr' expr_stmt'
switch k.Kind {
case ASTKindEqualExpr:
// assiging a value to some key
k.AppendChild(newExpression(tok))
stack.Push(newExprStatement(k))
case ASTKindExprStatement:
root := k.GetRoot()
children := root.GetChildren()
if len(children) == 0 {
return nil, NewParseError(
fmt.Sprintf("invalid expression: AST contains no children %s", k.Kind),
)
}
rhs := children[len(children)-1]
if rhs.Root.ValueType != QuotedStringType {
rhs.Root.ValueType = StringType
rhs.Root.raw = append(rhs.Root.raw, tok.Raw()...)
}
children[len(children)-1] = rhs
k.SetChildren(children)
stack.Push(k)
}
case OpenScopeState:
if !runeCompare(tok.Raw(), openBrace) {
return nil, NewParseError("expected '['")
}
stmt := newStatement()
stack.Push(stmt)
case CloseScopeState:
if !runeCompare(tok.Raw(), closeBrace) {
return nil, NewParseError("expected ']'")
}
stack.Push(newCompletedSectionStatement(k))
case SectionState:
var stmt AST
switch k.Kind {
case ASTKindStatement:
// If there are multiple literals inside of a scope declaration,
// then the current token's raw value will be appended to the Name.
//
// This handles cases like [ profile default ]
//
// k will represent a SectionStatement with the children representing
// the label of the section
stmt = newSectionStatement(tok)
case ASTKindSectionStatement:
k.Root.raw = append(k.Root.raw, ' ')
k.Root.raw = append(k.Root.raw, tok.Raw()...)
stmt = k
default:
return nil, NewParseError(
fmt.Sprintf("invalid statement: expected statement: %v", k.Kind),
)
}
stack.Push(stmt)
case MarkCompleteState:
if k.Kind != ASTKindStart {
stack.MarkComplete(k)
}
if stack.Len() == 0 {
stack.Push(start)
}
case SkipState:
stack.Push(newSkipStatement(k))
s.Skip()
case CommentState:
if k.Kind == ASTKindStart {
stack.Push(k)
} else {
stack.MarkComplete(k)
}
stmt := newCommentStatement(tok)
stack.Push(stmt)
default:
return nil, NewParseError(fmt.Sprintf("invalid state with ASTKind %v and TokenType %v", k, tok))
}
if len(tokens) > 0 {
tokens = tokens[1:]
}
}
// this occurs when a statement has not been completed
if stack.top > 1 {
return nil, NewParseError(fmt.Sprintf("incomplete expression: %v", stack.container))
}
// returns a sublist which exludes the start symbol
return stack.List(), nil
}

View file

@ -0,0 +1,317 @@
package ini
import (
"fmt"
"strconv"
"strings"
)
var (
runesTrue = []rune("true")
runesFalse = []rune("false")
)
var literalValues = [][]rune{
runesTrue,
runesFalse,
}
func isBoolValue(b []rune) bool {
for _, lv := range literalValues {
if isLitValue(lv, b) {
return true
}
}
return false
}
func isLitValue(want, have []rune) bool {
if len(have) < len(want) {
return false
}
for i := 0; i < len(want); i++ {
if want[i] != have[i] {
return false
}
}
return true
}
// isNumberValue will return whether not the leading characters in
// a byte slice is a number. A number is delimited by whitespace or
// the newline token.
//
// A number is defined to be in a binary, octal, decimal (int | float), hex format,
// or in scientific notation.
func isNumberValue(b []rune) bool {
negativeIndex := 0
helper := numberHelper{}
needDigit := false
for i := 0; i < len(b); i++ {
negativeIndex++
switch b[i] {
case '-':
if helper.IsNegative() || negativeIndex != 1 {
return false
}
helper.Determine(b[i])
needDigit = true
continue
case 'e', 'E':
if err := helper.Determine(b[i]); err != nil {
return false
}
negativeIndex = 0
needDigit = true
continue
case 'b':
if helper.numberFormat == hex {
break
}
fallthrough
case 'o', 'x':
needDigit = true
if i == 0 {
return false
}
fallthrough
case '.':
if err := helper.Determine(b[i]); err != nil {
return false
}
needDigit = true
continue
}
if i > 0 && (isNewline(b[i:]) || isWhitespace(b[i])) {
return !needDigit
}
if !helper.CorrectByte(b[i]) {
return false
}
needDigit = false
}
return !needDigit
}
func isValid(b []rune) (bool, int, error) {
if len(b) == 0 {
// TODO: should probably return an error
return false, 0, nil
}
return isValidRune(b[0]), 1, nil
}
func isValidRune(r rune) bool {
return r != ':' && r != '=' && r != '[' && r != ']' && r != ' ' && r != '\n'
}
// ValueType is an enum that will signify what type
// the Value is
type ValueType int
func (v ValueType) String() string {
switch v {
case NoneType:
return "NONE"
case DecimalType:
return "FLOAT"
case IntegerType:
return "INT"
case StringType:
return "STRING"
case BoolType:
return "BOOL"
}
return ""
}
// ValueType enums
const (
NoneType = ValueType(iota)
DecimalType
IntegerType
StringType
QuotedStringType
BoolType
)
// Value is a union container
type Value struct {
Type ValueType
raw []rune
integer int64
decimal float64
boolean bool
str string
}
func newValue(t ValueType, base int, raw []rune) (Value, error) {
v := Value{
Type: t,
raw: raw,
}
var err error
switch t {
case DecimalType:
v.decimal, err = strconv.ParseFloat(string(raw), 64)
if err != nil {
panic(err)
}
case IntegerType:
if base != 10 {
raw = raw[2:]
}
v.integer, err = strconv.ParseInt(string(raw), base, 64)
case StringType:
v.str = string(raw)
case QuotedStringType:
v.str = string(raw[1 : len(raw)-1])
case BoolType:
v.boolean = runeCompare(v.raw, runesTrue)
}
return v, err
}
// Append will append values and change the type to a string
// type.
func (v *Value) Append(tok Token) {
r := tok.Raw()
if v.Type != QuotedStringType {
v.Type = StringType
r = tok.raw[1 : len(tok.raw)-1]
}
if tok.Type() != TokenLit {
v.raw = append(v.raw, tok.Raw()...)
} else {
v.raw = append(v.raw, r...)
}
}
func (v Value) String() string {
switch v.Type {
case DecimalType:
return fmt.Sprintf("decimal: %f", v.decimal)
case IntegerType:
return fmt.Sprintf("integer: %d", v.integer)
case StringType:
return fmt.Sprintf("string: %s", string(v.raw))
case QuotedStringType:
return fmt.Sprintf("quoted string: %s", string(v.raw))
case BoolType:
return fmt.Sprintf("bool: %t", v.boolean)
default:
return "union not set"
}
}
func newLitToken(b []rune) (Token, int, error) {
n := 0
var err error
token := Token{}
if b[0] == '"' {
n, err = getStringValue(b)
if err != nil {
return token, n, err
}
token = newToken(TokenLit, b[:n], QuotedStringType)
} else if isNumberValue(b) {
var base int
base, n, err = getNumericalValue(b)
if err != nil {
return token, 0, err
}
value := b[:n]
vType := IntegerType
if contains(value, '.') || hasExponent(value) {
vType = DecimalType
}
token = newToken(TokenLit, value, vType)
token.base = base
} else if isBoolValue(b) {
n, err = getBoolValue(b)
token = newToken(TokenLit, b[:n], BoolType)
} else {
n, err = getValue(b)
token = newToken(TokenLit, b[:n], StringType)
}
return token, n, err
}
// IntValue returns an integer value
func (v Value) IntValue() int64 {
return v.integer
}
// FloatValue returns a float value
func (v Value) FloatValue() float64 {
return v.decimal
}
// BoolValue returns a bool value
func (v Value) BoolValue() bool {
return v.boolean
}
func isTrimmable(r rune) bool {
switch r {
case '\n', ' ':
return true
}
return false
}
// StringValue returns the string value
func (v Value) StringValue() string {
switch v.Type {
case StringType:
return strings.TrimFunc(string(v.raw), isTrimmable)
case QuotedStringType:
// preserve all characters in the quotes
return string(removeEscapedCharacters(v.raw[1 : len(v.raw)-1]))
default:
return strings.TrimFunc(string(v.raw), isTrimmable)
}
}
func contains(runes []rune, c rune) bool {
for i := 0; i < len(runes); i++ {
if runes[i] == c {
return true
}
}
return false
}
func runeCompare(v1 []rune, v2 []rune) bool {
if len(v1) != len(v2) {
return false
}
for i := 0; i < len(v1); i++ {
if v1[i] != v2[i] {
return false
}
}
return true
}

View file

@ -0,0 +1,30 @@
package ini
func isNewline(b []rune) bool {
if len(b) == 0 {
return false
}
if b[0] == '\n' {
return true
}
if len(b) < 2 {
return false
}
return b[0] == '\r' && b[1] == '\n'
}
func newNewlineToken(b []rune) (Token, int, error) {
i := 1
if b[0] == '\r' && isNewline(b[1:]) {
i++
}
if !isNewline([]rune(b[:i])) {
return emptyToken, 0, NewParseError("invalid new line token")
}
return newToken(TokenNL, b[:i], NoneType), i, nil
}

View file

@ -0,0 +1,152 @@
package ini
import (
"bytes"
"fmt"
"strconv"
)
const (
none = numberFormat(iota)
binary
octal
decimal
hex
exponent
)
type numberFormat int
// numberHelper is used to dictate what format a number is in
// and what to do for negative values. Since -1e-4 is a valid
// number, we cannot just simply check for duplicate negatives.
type numberHelper struct {
numberFormat numberFormat
negative bool
negativeExponent bool
}
func (b numberHelper) Exists() bool {
return b.numberFormat != none
}
func (b numberHelper) IsNegative() bool {
return b.negative || b.negativeExponent
}
func (b *numberHelper) Determine(c rune) error {
if b.Exists() {
return NewParseError(fmt.Sprintf("multiple number formats: 0%v", string(c)))
}
switch c {
case 'b':
b.numberFormat = binary
case 'o':
b.numberFormat = octal
case 'x':
b.numberFormat = hex
case 'e', 'E':
b.numberFormat = exponent
case '-':
if b.numberFormat != exponent {
b.negative = true
} else {
b.negativeExponent = true
}
case '.':
b.numberFormat = decimal
default:
return NewParseError(fmt.Sprintf("invalid number character: %v", string(c)))
}
return nil
}
func (b numberHelper) CorrectByte(c rune) bool {
switch {
case b.numberFormat == binary:
if !isBinaryByte(c) {
return false
}
case b.numberFormat == octal:
if !isOctalByte(c) {
return false
}
case b.numberFormat == hex:
if !isHexByte(c) {
return false
}
case b.numberFormat == decimal:
if !isDigit(c) {
return false
}
case b.numberFormat == exponent:
if !isDigit(c) {
return false
}
case b.negativeExponent:
if !isDigit(c) {
return false
}
case b.negative:
if !isDigit(c) {
return false
}
default:
if !isDigit(c) {
return false
}
}
return true
}
func (b numberHelper) Base() int {
switch b.numberFormat {
case binary:
return 2
case octal:
return 8
case hex:
return 16
default:
return 10
}
}
func (b numberHelper) String() string {
buf := bytes.Buffer{}
i := 0
switch b.numberFormat {
case binary:
i++
buf.WriteString(strconv.Itoa(i) + ": binary format\n")
case octal:
i++
buf.WriteString(strconv.Itoa(i) + ": octal format\n")
case hex:
i++
buf.WriteString(strconv.Itoa(i) + ": hex format\n")
case exponent:
i++
buf.WriteString(strconv.Itoa(i) + ": exponent format\n")
default:
i++
buf.WriteString(strconv.Itoa(i) + ": integer format\n")
}
if b.negative {
i++
buf.WriteString(strconv.Itoa(i) + ": negative format\n")
}
if b.negativeExponent {
i++
buf.WriteString(strconv.Itoa(i) + ": negative exponent format\n")
}
return buf.String()
}

View file

@ -0,0 +1,39 @@
package ini
import (
"fmt"
)
var (
equalOp = []rune("=")
equalColonOp = []rune(":")
)
func isOp(b []rune) bool {
if len(b) == 0 {
return false
}
switch b[0] {
case '=':
return true
case ':':
return true
default:
return false
}
}
func newOpToken(b []rune) (Token, int, error) {
tok := Token{}
switch b[0] {
case '=':
tok = newToken(TokenOp, equalOp, NoneType)
case ':':
tok = newToken(TokenOp, equalColonOp, NoneType)
default:
return tok, 0, NewParseError(fmt.Sprintf("unexpected op type, %v", b[0]))
}
return tok, 1, nil
}

View file

@ -0,0 +1,43 @@
package ini
import "fmt"
const (
// ErrCodeParseError is returned when a parsing error
// has occurred.
ErrCodeParseError = "INIParseError"
)
// ParseError is an error which is returned during any part of
// the parsing process.
type ParseError struct {
msg string
}
// NewParseError will return a new ParseError where message
// is the description of the error.
func NewParseError(message string) *ParseError {
return &ParseError{
msg: message,
}
}
// Code will return the ErrCodeParseError
func (err *ParseError) Code() string {
return ErrCodeParseError
}
// Message returns the error's message
func (err *ParseError) Message() string {
return err.msg
}
// OrigError return nothing since there will never be any
// original error.
func (err *ParseError) OrigError() error {
return nil
}
func (err *ParseError) Error() string {
return fmt.Sprintf("%s: %s", err.Code(), err.Message())
}

View file

@ -0,0 +1,60 @@
package ini
import (
"bytes"
"fmt"
)
// ParseStack is a stack that contains a container, the stack portion,
// and the list which is the list of ASTs that have been successfully
// parsed.
type ParseStack struct {
top int
container []AST
list []AST
index int
}
func newParseStack(sizeContainer, sizeList int) ParseStack {
return ParseStack{
container: make([]AST, sizeContainer),
list: make([]AST, sizeList),
}
}
// Pop will return and truncate the last container element.
func (s *ParseStack) Pop() AST {
s.top--
return s.container[s.top]
}
// Push will add the new AST to the container
func (s *ParseStack) Push(ast AST) {
s.container[s.top] = ast
s.top++
}
// MarkComplete will append the AST to the list of completed statements
func (s *ParseStack) MarkComplete(ast AST) {
s.list[s.index] = ast
s.index++
}
// List will return the completed statements
func (s ParseStack) List() []AST {
return s.list[:s.index]
}
// Len will return the length of the container
func (s *ParseStack) Len() int {
return s.top
}
func (s ParseStack) String() string {
buf := bytes.Buffer{}
for i, node := range s.list {
buf.WriteString(fmt.Sprintf("%d: %v\n", i+1, node))
}
return buf.String()
}

View file

@ -0,0 +1,41 @@
package ini
import (
"fmt"
)
var (
emptyRunes = []rune{}
)
func isSep(b []rune) bool {
if len(b) == 0 {
return false
}
switch b[0] {
case '[', ']':
return true
default:
return false
}
}
var (
openBrace = []rune("[")
closeBrace = []rune("]")
)
func newSepToken(b []rune) (Token, int, error) {
tok := Token{}
switch b[0] {
case '[':
tok = newToken(TokenSep, openBrace, NoneType)
case ']':
tok = newToken(TokenSep, closeBrace, NoneType)
default:
return tok, 0, NewParseError(fmt.Sprintf("unexpected sep type, %v", b[0]))
}
return tok, 1, nil
}

View file

@ -0,0 +1,42 @@
package ini
// skipper is used to skip certain blocks of an ini file.
// Currently skipper is used to skip nested blocks of ini
// files. See example below
//
// [ foo ]
// nested = // this section will be skipped
// a=b
// c=d
// bar=baz // this will be included
type skipper struct {
shouldSkip bool
TokenSet bool
prevTok Token
}
func newSkipper() skipper {
return skipper{
prevTok: emptyToken,
}
}
func (s *skipper) ShouldSkip(tok Token) bool {
if s.shouldSkip && s.prevTok.Type() == TokenNL && tok.Type() != TokenWS {
s.Continue()
return false
}
s.prevTok = tok
return s.shouldSkip
}
func (s *skipper) Skip() {
s.shouldSkip = true
s.prevTok = emptyToken
}
func (s *skipper) Continue() {
s.shouldSkip = false
s.prevTok = emptyToken
}

View file

@ -0,0 +1,36 @@
package ini
// Statement is an empty AST mostly used for transitioning states.
func newStatement() AST {
return newAST(ASTKindStatement, AST{})
}
// SectionStatement represents a section AST
func newSectionStatement(tok Token) AST {
return newASTWithRootToken(ASTKindSectionStatement, tok)
}
// ExprStatement represents a completed expression AST
func newExprStatement(ast AST) AST {
return newAST(ASTKindExprStatement, ast)
}
// CommentStatement represents a comment in the ini defintion.
//
// grammar:
// comment -> #comment' | ;comment' | /comment_slash
// comment_slash -> /comment'
// comment' -> value
func newCommentStatement(tok Token) AST {
return newAST(ASTKindCommentStatement, newExpression(tok))
}
// CompletedSectionStatement represents a completed section
func newCompletedSectionStatement(ast AST) AST {
return newAST(ASTKindCompletedSectionStatement, ast)
}
// SkipStatement is used to skip whole statements
func newSkipStatement(ast AST) AST {
return newAST(ASTKindSkipStatement, ast)
}

View file

@ -0,0 +1,284 @@
package ini
import (
"fmt"
)
// getStringValue will return a quoted string and the amount
// of bytes read
//
// an error will be returned if the string is not properly formatted
func getStringValue(b []rune) (int, error) {
if b[0] != '"' {
return 0, NewParseError("strings must start with '\"'")
}
endQuote := false
i := 1
for ; i < len(b) && !endQuote; i++ {
if escaped := isEscaped(b[:i], b[i]); b[i] == '"' && !escaped {
endQuote = true
break
} else if escaped {
/*c, err := getEscapedByte(b[i])
if err != nil {
return 0, err
}
b[i-1] = c
b = append(b[:i], b[i+1:]...)
i--*/
continue
}
}
if !endQuote {
return 0, NewParseError("missing '\"' in string value")
}
return i + 1, nil
}
// getBoolValue will return a boolean and the amount
// of bytes read
//
// an error will be returned if the boolean is not of a correct
// value
func getBoolValue(b []rune) (int, error) {
if len(b) < 4 {
return 0, NewParseError("invalid boolean value")
}
n := 0
for _, lv := range literalValues {
if len(lv) > len(b) {
continue
}
if isLitValue(lv, b) {
n = len(lv)
}
}
if n == 0 {
return 0, NewParseError("invalid boolean value")
}
return n, nil
}
// getNumericalValue will return a numerical string, the amount
// of bytes read, and the base of the number
//
// an error will be returned if the number is not of a correct
// value
func getNumericalValue(b []rune) (int, int, error) {
if !isDigit(b[0]) {
return 0, 0, NewParseError("invalid digit value")
}
i := 0
helper := numberHelper{}
loop:
for negativeIndex := 0; i < len(b); i++ {
negativeIndex++
if !isDigit(b[i]) {
switch b[i] {
case '-':
if helper.IsNegative() || negativeIndex != 1 {
return 0, 0, NewParseError("parse error '-'")
}
n := getNegativeNumber(b[i:])
i += (n - 1)
helper.Determine(b[i])
continue
case '.':
if err := helper.Determine(b[i]); err != nil {
return 0, 0, err
}
case 'e', 'E':
if err := helper.Determine(b[i]); err != nil {
return 0, 0, err
}
negativeIndex = 0
case 'b':
if helper.numberFormat == hex {
break
}
fallthrough
case 'o', 'x':
if i == 0 && b[i] != '0' {
return 0, 0, NewParseError("incorrect base format, expected leading '0'")
}
if i != 1 {
return 0, 0, NewParseError(fmt.Sprintf("incorrect base format found %s at %d index", string(b[i]), i))
}
if err := helper.Determine(b[i]); err != nil {
return 0, 0, err
}
default:
if isWhitespace(b[i]) {
break loop
}
if isNewline(b[i:]) {
break loop
}
if !(helper.numberFormat == hex && isHexByte(b[i])) {
if i+2 < len(b) && !isNewline(b[i:i+2]) {
return 0, 0, NewParseError("invalid numerical character")
} else if !isNewline([]rune{b[i]}) {
return 0, 0, NewParseError("invalid numerical character")
}
break loop
}
}
}
}
return helper.Base(), i, nil
}
// isDigit will return whether or not something is an integer
func isDigit(b rune) bool {
return b >= '0' && b <= '9'
}
func hasExponent(v []rune) bool {
return contains(v, 'e') || contains(v, 'E')
}
func isBinaryByte(b rune) bool {
switch b {
case '0', '1':
return true
default:
return false
}
}
func isOctalByte(b rune) bool {
switch b {
case '0', '1', '2', '3', '4', '5', '6', '7':
return true
default:
return false
}
}
func isHexByte(b rune) bool {
if isDigit(b) {
return true
}
return (b >= 'A' && b <= 'F') ||
(b >= 'a' && b <= 'f')
}
func getValue(b []rune) (int, error) {
i := 0
for i < len(b) {
if isNewline(b[i:]) {
break
}
if isOp(b[i:]) {
break
}
valid, n, err := isValid(b[i:])
if err != nil {
return 0, err
}
if !valid {
break
}
i += n
}
return i, nil
}
// getNegativeNumber will return a negative number from a
// byte slice. This will iterate through all characters until
// a non-digit has been found.
func getNegativeNumber(b []rune) int {
if b[0] != '-' {
return 0
}
i := 1
for ; i < len(b); i++ {
if !isDigit(b[i]) {
return i
}
}
return i
}
// isEscaped will return whether or not the character is an escaped
// character.
func isEscaped(value []rune, b rune) bool {
if len(value) == 0 {
return false
}
switch b {
case '\'': // single quote
case '"': // quote
case 'n': // newline
case 't': // tab
case '\\': // backslash
default:
return false
}
return value[len(value)-1] == '\\'
}
func getEscapedByte(b rune) (rune, error) {
switch b {
case '\'': // single quote
return '\'', nil
case '"': // quote
return '"', nil
case 'n': // newline
return '\n', nil
case 't': // table
return '\t', nil
case '\\': // backslash
return '\\', nil
default:
return b, NewParseError(fmt.Sprintf("invalid escaped character %c", b))
}
}
func removeEscapedCharacters(b []rune) []rune {
for i := 0; i < len(b); i++ {
if isEscaped(b[:i], b[i]) {
c, err := getEscapedByte(b[i])
if err != nil {
return b
}
b[i-1] = c
b = append(b[:i], b[i+1:]...)
i--
}
}
return b
}

View file

@ -0,0 +1,161 @@
package ini
import (
"fmt"
"sort"
)
// Visitor is an interface used by walkers that will
// traverse an array of ASTs.
type Visitor interface {
VisitExpr(AST) error
VisitStatement(AST) error
}
// DefaultVisitor is used to visit statements and expressions
// and ensure that they are both of the correct format.
// In addition, upon visiting this will build sections and populate
// the Sections field which can be used to retrieve profile
// configuration.
type DefaultVisitor struct {
scope string
Sections Sections
}
// NewDefaultVisitor return a DefaultVisitor
func NewDefaultVisitor() *DefaultVisitor {
return &DefaultVisitor{
Sections: Sections{
container: map[string]Section{},
},
}
}
// VisitExpr visits expressions...
func (v *DefaultVisitor) VisitExpr(expr AST) error {
t := v.Sections.container[v.scope]
if t.values == nil {
t.values = values{}
}
switch expr.Kind {
case ASTKindExprStatement:
opExpr := expr.GetRoot()
switch opExpr.Kind {
case ASTKindEqualExpr:
children := opExpr.GetChildren()
if len(children) <= 1 {
return NewParseError("unexpected token type")
}
rhs := children[1]
if rhs.Root.Type() != TokenLit {
return NewParseError("unexpected token type")
}
key := EqualExprKey(opExpr)
v, err := newValue(rhs.Root.ValueType, rhs.Root.base, rhs.Root.Raw())
if err != nil {
return err
}
t.values[key] = v
default:
return NewParseError(fmt.Sprintf("unsupported expression %v", expr))
}
default:
return NewParseError(fmt.Sprintf("unsupported expression %v", expr))
}
v.Sections.container[v.scope] = t
return nil
}
// VisitStatement visits statements...
func (v *DefaultVisitor) VisitStatement(stmt AST) error {
switch stmt.Kind {
case ASTKindCompletedSectionStatement:
child := stmt.GetRoot()
if child.Kind != ASTKindSectionStatement {
return NewParseError(fmt.Sprintf("unsupported child statement: %T", child))
}
name := string(child.Root.Raw())
v.Sections.container[name] = Section{}
v.scope = name
default:
return NewParseError(fmt.Sprintf("unsupported statement: %s", stmt.Kind))
}
return nil
}
// Sections is a map of Section structures that represent
// a configuration.
type Sections struct {
container map[string]Section
}
// GetSection will return section p. If section p does not exist,
// false will be returned in the second parameter.
func (t Sections) GetSection(p string) (Section, bool) {
v, ok := t.container[p]
return v, ok
}
// values represents a map of union values.
type values map[string]Value
// List will return a list of all sections that were successfully
// parsed.
func (t Sections) List() []string {
keys := make([]string, len(t.container))
i := 0
for k := range t.container {
keys[i] = k
i++
}
sort.Strings(keys)
return keys
}
// Section contains a name and values. This represent
// a sectioned entry in a configuration file.
type Section struct {
Name string
values values
}
// Has will return whether or not an entry exists in a given section
func (t Section) Has(k string) bool {
_, ok := t.values[k]
return ok
}
// ValueType will returned what type the union is set to. If
// k was not found, the NoneType will be returned.
func (t Section) ValueType(k string) (ValueType, bool) {
v, ok := t.values[k]
return v.Type, ok
}
// Int returns an integer value at k
func (t Section) Int(k string) int64 {
return t.values[k].IntValue()
}
// Float64 returns a float value at k
func (t Section) Float64(k string) float64 {
return t.values[k].FloatValue()
}
// String returns the string value at k
func (t Section) String(k string) string {
_, ok := t.values[k]
if !ok {
return ""
}
return t.values[k].StringValue()
}

View file

@ -0,0 +1,25 @@
package ini
// Walk will traverse the AST using the v, the Visitor.
func Walk(tree []AST, v Visitor) error {
for _, node := range tree {
switch node.Kind {
case ASTKindExpr,
ASTKindExprStatement:
if err := v.VisitExpr(node); err != nil {
return err
}
case ASTKindStatement,
ASTKindCompletedSectionStatement,
ASTKindNestedSectionStatement,
ASTKindCompletedNestedSectionStatement:
if err := v.VisitStatement(node); err != nil {
return err
}
}
}
return nil
}

View file

@ -0,0 +1,24 @@
package ini
import (
"unicode"
)
// isWhitespace will return whether or not the character is
// a whitespace character.
//
// Whitespace is defined as a space or tab.
func isWhitespace(c rune) bool {
return unicode.IsSpace(c) && c != '\n' && c != '\r'
}
func newWSToken(b []rune) (Token, int, error) {
i := 0
for ; i < len(b); i++ {
if !isWhitespace(b[i]) {
break
}
}
return newToken(TokenWS, b[:i], NoneType), i, nil
}

View file

@ -0,0 +1,57 @@
package s3err
import (
"fmt"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
)
// RequestFailure provides additional S3 specific metadata for the request
// failure.
type RequestFailure struct {
awserr.RequestFailure
hostID string
}
// NewRequestFailure returns a request failure error decordated with S3
// specific metadata.
func NewRequestFailure(err awserr.RequestFailure, hostID string) *RequestFailure {
return &RequestFailure{RequestFailure: err, hostID: hostID}
}
func (r RequestFailure) Error() string {
extra := fmt.Sprintf("status code: %d, request id: %s, host id: %s",
r.StatusCode(), r.RequestID(), r.hostID)
return awserr.SprintError(r.Code(), r.Message(), extra, r.OrigErr())
}
func (r RequestFailure) String() string {
return r.Error()
}
// HostID returns the HostID request response value.
func (r RequestFailure) HostID() string {
return r.hostID
}
// RequestFailureWrapperHandler returns a handler to rap an
// awserr.RequestFailure with the S3 request ID 2 from the response.
func RequestFailureWrapperHandler() request.NamedHandler {
return request.NamedHandler{
Name: "awssdk.s3.errorHandler",
Fn: func(req *request.Request) {
reqErr, ok := req.Error.(awserr.RequestFailure)
if !ok || reqErr == nil {
return
}
hostID := req.HTTPResponse.Header.Get("X-Amz-Id-2")
if req.Error == nil {
return
}
req.Error = NewRequestFailure(reqErr, hostID)
},
}
}

View file

@ -0,0 +1,12 @@
package shareddefaults
const (
// ECSCredsProviderEnvVar is an environmental variable key used to
// determine which path needs to be hit.
ECSCredsProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
)
// ECSContainerCredentialsURI is the endpoint to retrieve container
// credentials. This can be overriden to test to ensure the credential process
// is behaving correctly.
var ECSContainerCredentialsURI = "http://169.254.170.2"

View file

@ -0,0 +1,21 @@
package protocol
// ValidHostLabel returns if the label is a valid RFC 1123 Section 2.1 domain
// host label name.
func ValidHostLabel(label string) bool {
if l := len(label); l == 0 || l > 63 {
return false
}
for _, r := range label {
switch {
case r >= '0' && r <= '9':
case r >= 'A' && r <= 'Z':
case r >= 'a' && r <= 'z':
case r == '-':
default:
return false
}
}
return true
}

View file

@ -27,7 +27,7 @@ const opAbortMultipartUpload = "AbortMultipartUpload"
// AbortMultipartUploadRequest generates a "aws/request.Request" representing the // AbortMultipartUploadRequest generates a "aws/request.Request" representing the
// client's request for the AbortMultipartUpload operation. The "output" return // client's request for the AbortMultipartUpload operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -110,7 +110,7 @@ const opCompleteMultipartUpload = "CompleteMultipartUpload"
// CompleteMultipartUploadRequest generates a "aws/request.Request" representing the // CompleteMultipartUploadRequest generates a "aws/request.Request" representing the
// client's request for the CompleteMultipartUpload operation. The "output" return // client's request for the CompleteMultipartUpload operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -184,7 +184,7 @@ const opCopyObject = "CopyObject"
// CopyObjectRequest generates a "aws/request.Request" representing the // CopyObjectRequest generates a "aws/request.Request" representing the
// client's request for the CopyObject operation. The "output" return // client's request for the CopyObject operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -264,7 +264,7 @@ const opCreateBucket = "CreateBucket"
// CreateBucketRequest generates a "aws/request.Request" representing the // CreateBucketRequest generates a "aws/request.Request" representing the
// client's request for the CreateBucket operation. The "output" return // client's request for the CreateBucket operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -346,7 +346,7 @@ const opCreateMultipartUpload = "CreateMultipartUpload"
// CreateMultipartUploadRequest generates a "aws/request.Request" representing the // CreateMultipartUploadRequest generates a "aws/request.Request" representing the
// client's request for the CreateMultipartUpload operation. The "output" return // client's request for the CreateMultipartUpload operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -426,7 +426,7 @@ const opDeleteBucket = "DeleteBucket"
// DeleteBucketRequest generates a "aws/request.Request" representing the // DeleteBucketRequest generates a "aws/request.Request" representing the
// client's request for the DeleteBucket operation. The "output" return // client's request for the DeleteBucket operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -503,7 +503,7 @@ const opDeleteBucketAnalyticsConfiguration = "DeleteBucketAnalyticsConfiguration
// DeleteBucketAnalyticsConfigurationRequest generates a "aws/request.Request" representing the // DeleteBucketAnalyticsConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the DeleteBucketAnalyticsConfiguration operation. The "output" return // client's request for the DeleteBucketAnalyticsConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -580,7 +580,7 @@ const opDeleteBucketCors = "DeleteBucketCors"
// DeleteBucketCorsRequest generates a "aws/request.Request" representing the // DeleteBucketCorsRequest generates a "aws/request.Request" representing the
// client's request for the DeleteBucketCors operation. The "output" return // client's request for the DeleteBucketCors operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -656,7 +656,7 @@ const opDeleteBucketEncryption = "DeleteBucketEncryption"
// DeleteBucketEncryptionRequest generates a "aws/request.Request" representing the // DeleteBucketEncryptionRequest generates a "aws/request.Request" representing the
// client's request for the DeleteBucketEncryption operation. The "output" return // client's request for the DeleteBucketEncryption operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -732,7 +732,7 @@ const opDeleteBucketInventoryConfiguration = "DeleteBucketInventoryConfiguration
// DeleteBucketInventoryConfigurationRequest generates a "aws/request.Request" representing the // DeleteBucketInventoryConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the DeleteBucketInventoryConfiguration operation. The "output" return // client's request for the DeleteBucketInventoryConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -809,7 +809,7 @@ const opDeleteBucketLifecycle = "DeleteBucketLifecycle"
// DeleteBucketLifecycleRequest generates a "aws/request.Request" representing the // DeleteBucketLifecycleRequest generates a "aws/request.Request" representing the
// client's request for the DeleteBucketLifecycle operation. The "output" return // client's request for the DeleteBucketLifecycle operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -885,7 +885,7 @@ const opDeleteBucketMetricsConfiguration = "DeleteBucketMetricsConfiguration"
// DeleteBucketMetricsConfigurationRequest generates a "aws/request.Request" representing the // DeleteBucketMetricsConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the DeleteBucketMetricsConfiguration operation. The "output" return // client's request for the DeleteBucketMetricsConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -962,7 +962,7 @@ const opDeleteBucketPolicy = "DeleteBucketPolicy"
// DeleteBucketPolicyRequest generates a "aws/request.Request" representing the // DeleteBucketPolicyRequest generates a "aws/request.Request" representing the
// client's request for the DeleteBucketPolicy operation. The "output" return // client's request for the DeleteBucketPolicy operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1038,7 +1038,7 @@ const opDeleteBucketReplication = "DeleteBucketReplication"
// DeleteBucketReplicationRequest generates a "aws/request.Request" representing the // DeleteBucketReplicationRequest generates a "aws/request.Request" representing the
// client's request for the DeleteBucketReplication operation. The "output" return // client's request for the DeleteBucketReplication operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1114,7 +1114,7 @@ const opDeleteBucketTagging = "DeleteBucketTagging"
// DeleteBucketTaggingRequest generates a "aws/request.Request" representing the // DeleteBucketTaggingRequest generates a "aws/request.Request" representing the
// client's request for the DeleteBucketTagging operation. The "output" return // client's request for the DeleteBucketTagging operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1190,7 +1190,7 @@ const opDeleteBucketWebsite = "DeleteBucketWebsite"
// DeleteBucketWebsiteRequest generates a "aws/request.Request" representing the // DeleteBucketWebsiteRequest generates a "aws/request.Request" representing the
// client's request for the DeleteBucketWebsite operation. The "output" return // client's request for the DeleteBucketWebsite operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1266,7 +1266,7 @@ const opDeleteObject = "DeleteObject"
// DeleteObjectRequest generates a "aws/request.Request" representing the // DeleteObjectRequest generates a "aws/request.Request" representing the
// client's request for the DeleteObject operation. The "output" return // client's request for the DeleteObject operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1342,7 +1342,7 @@ const opDeleteObjectTagging = "DeleteObjectTagging"
// DeleteObjectTaggingRequest generates a "aws/request.Request" representing the // DeleteObjectTaggingRequest generates a "aws/request.Request" representing the
// client's request for the DeleteObjectTagging operation. The "output" return // client's request for the DeleteObjectTagging operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1416,7 +1416,7 @@ const opDeleteObjects = "DeleteObjects"
// DeleteObjectsRequest generates a "aws/request.Request" representing the // DeleteObjectsRequest generates a "aws/request.Request" representing the
// client's request for the DeleteObjects operation. The "output" return // client's request for the DeleteObjects operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1491,7 +1491,7 @@ const opGetBucketAccelerateConfiguration = "GetBucketAccelerateConfiguration"
// GetBucketAccelerateConfigurationRequest generates a "aws/request.Request" representing the // GetBucketAccelerateConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketAccelerateConfiguration operation. The "output" return // client's request for the GetBucketAccelerateConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1565,7 +1565,7 @@ const opGetBucketAcl = "GetBucketAcl"
// GetBucketAclRequest generates a "aws/request.Request" representing the // GetBucketAclRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketAcl operation. The "output" return // client's request for the GetBucketAcl operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1639,7 +1639,7 @@ const opGetBucketAnalyticsConfiguration = "GetBucketAnalyticsConfiguration"
// GetBucketAnalyticsConfigurationRequest generates a "aws/request.Request" representing the // GetBucketAnalyticsConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketAnalyticsConfiguration operation. The "output" return // client's request for the GetBucketAnalyticsConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1714,7 +1714,7 @@ const opGetBucketCors = "GetBucketCors"
// GetBucketCorsRequest generates a "aws/request.Request" representing the // GetBucketCorsRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketCors operation. The "output" return // client's request for the GetBucketCors operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1788,7 +1788,7 @@ const opGetBucketEncryption = "GetBucketEncryption"
// GetBucketEncryptionRequest generates a "aws/request.Request" representing the // GetBucketEncryptionRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketEncryption operation. The "output" return // client's request for the GetBucketEncryption operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1862,7 +1862,7 @@ const opGetBucketInventoryConfiguration = "GetBucketInventoryConfiguration"
// GetBucketInventoryConfigurationRequest generates a "aws/request.Request" representing the // GetBucketInventoryConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketInventoryConfiguration operation. The "output" return // client's request for the GetBucketInventoryConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -1937,7 +1937,7 @@ const opGetBucketLifecycle = "GetBucketLifecycle"
// GetBucketLifecycleRequest generates a "aws/request.Request" representing the // GetBucketLifecycleRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketLifecycle operation. The "output" return // client's request for the GetBucketLifecycle operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2020,7 +2020,7 @@ const opGetBucketLifecycleConfiguration = "GetBucketLifecycleConfiguration"
// GetBucketLifecycleConfigurationRequest generates a "aws/request.Request" representing the // GetBucketLifecycleConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketLifecycleConfiguration operation. The "output" return // client's request for the GetBucketLifecycleConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2094,7 +2094,7 @@ const opGetBucketLocation = "GetBucketLocation"
// GetBucketLocationRequest generates a "aws/request.Request" representing the // GetBucketLocationRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketLocation operation. The "output" return // client's request for the GetBucketLocation operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2168,7 +2168,7 @@ const opGetBucketLogging = "GetBucketLogging"
// GetBucketLoggingRequest generates a "aws/request.Request" representing the // GetBucketLoggingRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketLogging operation. The "output" return // client's request for the GetBucketLogging operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2243,7 +2243,7 @@ const opGetBucketMetricsConfiguration = "GetBucketMetricsConfiguration"
// GetBucketMetricsConfigurationRequest generates a "aws/request.Request" representing the // GetBucketMetricsConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketMetricsConfiguration operation. The "output" return // client's request for the GetBucketMetricsConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2318,7 +2318,7 @@ const opGetBucketNotification = "GetBucketNotification"
// GetBucketNotificationRequest generates a "aws/request.Request" representing the // GetBucketNotificationRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketNotification operation. The "output" return // client's request for the GetBucketNotification operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2401,7 +2401,7 @@ const opGetBucketNotificationConfiguration = "GetBucketNotificationConfiguration
// GetBucketNotificationConfigurationRequest generates a "aws/request.Request" representing the // GetBucketNotificationConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketNotificationConfiguration operation. The "output" return // client's request for the GetBucketNotificationConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2475,7 +2475,7 @@ const opGetBucketPolicy = "GetBucketPolicy"
// GetBucketPolicyRequest generates a "aws/request.Request" representing the // GetBucketPolicyRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketPolicy operation. The "output" return // client's request for the GetBucketPolicy operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2549,7 +2549,7 @@ const opGetBucketReplication = "GetBucketReplication"
// GetBucketReplicationRequest generates a "aws/request.Request" representing the // GetBucketReplicationRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketReplication operation. The "output" return // client's request for the GetBucketReplication operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2623,7 +2623,7 @@ const opGetBucketRequestPayment = "GetBucketRequestPayment"
// GetBucketRequestPaymentRequest generates a "aws/request.Request" representing the // GetBucketRequestPaymentRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketRequestPayment operation. The "output" return // client's request for the GetBucketRequestPayment operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2697,7 +2697,7 @@ const opGetBucketTagging = "GetBucketTagging"
// GetBucketTaggingRequest generates a "aws/request.Request" representing the // GetBucketTaggingRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketTagging operation. The "output" return // client's request for the GetBucketTagging operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2771,7 +2771,7 @@ const opGetBucketVersioning = "GetBucketVersioning"
// GetBucketVersioningRequest generates a "aws/request.Request" representing the // GetBucketVersioningRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketVersioning operation. The "output" return // client's request for the GetBucketVersioning operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2845,7 +2845,7 @@ const opGetBucketWebsite = "GetBucketWebsite"
// GetBucketWebsiteRequest generates a "aws/request.Request" representing the // GetBucketWebsiteRequest generates a "aws/request.Request" representing the
// client's request for the GetBucketWebsite operation. The "output" return // client's request for the GetBucketWebsite operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2919,7 +2919,7 @@ const opGetObject = "GetObject"
// GetObjectRequest generates a "aws/request.Request" representing the // GetObjectRequest generates a "aws/request.Request" representing the
// client's request for the GetObject operation. The "output" return // client's request for the GetObject operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -2998,7 +2998,7 @@ const opGetObjectAcl = "GetObjectAcl"
// GetObjectAclRequest generates a "aws/request.Request" representing the // GetObjectAclRequest generates a "aws/request.Request" representing the
// client's request for the GetObjectAcl operation. The "output" return // client's request for the GetObjectAcl operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -3077,7 +3077,7 @@ const opGetObjectTagging = "GetObjectTagging"
// GetObjectTaggingRequest generates a "aws/request.Request" representing the // GetObjectTaggingRequest generates a "aws/request.Request" representing the
// client's request for the GetObjectTagging operation. The "output" return // client's request for the GetObjectTagging operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -3151,7 +3151,7 @@ const opGetObjectTorrent = "GetObjectTorrent"
// GetObjectTorrentRequest generates a "aws/request.Request" representing the // GetObjectTorrentRequest generates a "aws/request.Request" representing the
// client's request for the GetObjectTorrent operation. The "output" return // client's request for the GetObjectTorrent operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -3225,7 +3225,7 @@ const opHeadBucket = "HeadBucket"
// HeadBucketRequest generates a "aws/request.Request" representing the // HeadBucketRequest generates a "aws/request.Request" representing the
// client's request for the HeadBucket operation. The "output" return // client's request for the HeadBucket operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -3307,7 +3307,7 @@ const opHeadObject = "HeadObject"
// HeadObjectRequest generates a "aws/request.Request" representing the // HeadObjectRequest generates a "aws/request.Request" representing the
// client's request for the HeadObject operation. The "output" return // client's request for the HeadObject operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -3386,7 +3386,7 @@ const opListBucketAnalyticsConfigurations = "ListBucketAnalyticsConfigurations"
// ListBucketAnalyticsConfigurationsRequest generates a "aws/request.Request" representing the // ListBucketAnalyticsConfigurationsRequest generates a "aws/request.Request" representing the
// client's request for the ListBucketAnalyticsConfigurations operation. The "output" return // client's request for the ListBucketAnalyticsConfigurations operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -3460,7 +3460,7 @@ const opListBucketInventoryConfigurations = "ListBucketInventoryConfigurations"
// ListBucketInventoryConfigurationsRequest generates a "aws/request.Request" representing the // ListBucketInventoryConfigurationsRequest generates a "aws/request.Request" representing the
// client's request for the ListBucketInventoryConfigurations operation. The "output" return // client's request for the ListBucketInventoryConfigurations operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -3534,7 +3534,7 @@ const opListBucketMetricsConfigurations = "ListBucketMetricsConfigurations"
// ListBucketMetricsConfigurationsRequest generates a "aws/request.Request" representing the // ListBucketMetricsConfigurationsRequest generates a "aws/request.Request" representing the
// client's request for the ListBucketMetricsConfigurations operation. The "output" return // client's request for the ListBucketMetricsConfigurations operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -3608,7 +3608,7 @@ const opListBuckets = "ListBuckets"
// ListBucketsRequest generates a "aws/request.Request" representing the // ListBucketsRequest generates a "aws/request.Request" representing the
// client's request for the ListBuckets operation. The "output" return // client's request for the ListBuckets operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -3682,7 +3682,7 @@ const opListMultipartUploads = "ListMultipartUploads"
// ListMultipartUploadsRequest generates a "aws/request.Request" representing the // ListMultipartUploadsRequest generates a "aws/request.Request" representing the
// client's request for the ListMultipartUploads operation. The "output" return // client's request for the ListMultipartUploads operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -3812,7 +3812,7 @@ const opListObjectVersions = "ListObjectVersions"
// ListObjectVersionsRequest generates a "aws/request.Request" representing the // ListObjectVersionsRequest generates a "aws/request.Request" representing the
// client's request for the ListObjectVersions operation. The "output" return // client's request for the ListObjectVersions operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -3942,7 +3942,7 @@ const opListObjects = "ListObjects"
// ListObjectsRequest generates a "aws/request.Request" representing the // ListObjectsRequest generates a "aws/request.Request" representing the
// client's request for the ListObjects operation. The "output" return // client's request for the ListObjects operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -4079,7 +4079,7 @@ const opListObjectsV2 = "ListObjectsV2"
// ListObjectsV2Request generates a "aws/request.Request" representing the // ListObjectsV2Request generates a "aws/request.Request" representing the
// client's request for the ListObjectsV2 operation. The "output" return // client's request for the ListObjectsV2 operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -4217,7 +4217,7 @@ const opListParts = "ListParts"
// ListPartsRequest generates a "aws/request.Request" representing the // ListPartsRequest generates a "aws/request.Request" representing the
// client's request for the ListParts operation. The "output" return // client's request for the ListParts operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -4347,7 +4347,7 @@ const opPutBucketAccelerateConfiguration = "PutBucketAccelerateConfiguration"
// PutBucketAccelerateConfigurationRequest generates a "aws/request.Request" representing the // PutBucketAccelerateConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketAccelerateConfiguration operation. The "output" return // client's request for the PutBucketAccelerateConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -4423,7 +4423,7 @@ const opPutBucketAcl = "PutBucketAcl"
// PutBucketAclRequest generates a "aws/request.Request" representing the // PutBucketAclRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketAcl operation. The "output" return // client's request for the PutBucketAcl operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -4499,7 +4499,7 @@ const opPutBucketAnalyticsConfiguration = "PutBucketAnalyticsConfiguration"
// PutBucketAnalyticsConfigurationRequest generates a "aws/request.Request" representing the // PutBucketAnalyticsConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketAnalyticsConfiguration operation. The "output" return // client's request for the PutBucketAnalyticsConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -4576,7 +4576,7 @@ const opPutBucketCors = "PutBucketCors"
// PutBucketCorsRequest generates a "aws/request.Request" representing the // PutBucketCorsRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketCors operation. The "output" return // client's request for the PutBucketCors operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -4652,7 +4652,7 @@ const opPutBucketEncryption = "PutBucketEncryption"
// PutBucketEncryptionRequest generates a "aws/request.Request" representing the // PutBucketEncryptionRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketEncryption operation. The "output" return // client's request for the PutBucketEncryption operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -4729,7 +4729,7 @@ const opPutBucketInventoryConfiguration = "PutBucketInventoryConfiguration"
// PutBucketInventoryConfigurationRequest generates a "aws/request.Request" representing the // PutBucketInventoryConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketInventoryConfiguration operation. The "output" return // client's request for the PutBucketInventoryConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -4806,7 +4806,7 @@ const opPutBucketLifecycle = "PutBucketLifecycle"
// PutBucketLifecycleRequest generates a "aws/request.Request" representing the // PutBucketLifecycleRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketLifecycle operation. The "output" return // client's request for the PutBucketLifecycle operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -4891,7 +4891,7 @@ const opPutBucketLifecycleConfiguration = "PutBucketLifecycleConfiguration"
// PutBucketLifecycleConfigurationRequest generates a "aws/request.Request" representing the // PutBucketLifecycleConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketLifecycleConfiguration operation. The "output" return // client's request for the PutBucketLifecycleConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -4968,7 +4968,7 @@ const opPutBucketLogging = "PutBucketLogging"
// PutBucketLoggingRequest generates a "aws/request.Request" representing the // PutBucketLoggingRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketLogging operation. The "output" return // client's request for the PutBucketLogging operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5046,7 +5046,7 @@ const opPutBucketMetricsConfiguration = "PutBucketMetricsConfiguration"
// PutBucketMetricsConfigurationRequest generates a "aws/request.Request" representing the // PutBucketMetricsConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketMetricsConfiguration operation. The "output" return // client's request for the PutBucketMetricsConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5123,7 +5123,7 @@ const opPutBucketNotification = "PutBucketNotification"
// PutBucketNotificationRequest generates a "aws/request.Request" representing the // PutBucketNotificationRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketNotification operation. The "output" return // client's request for the PutBucketNotification operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5208,7 +5208,7 @@ const opPutBucketNotificationConfiguration = "PutBucketNotificationConfiguration
// PutBucketNotificationConfigurationRequest generates a "aws/request.Request" representing the // PutBucketNotificationConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketNotificationConfiguration operation. The "output" return // client's request for the PutBucketNotificationConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5284,7 +5284,7 @@ const opPutBucketPolicy = "PutBucketPolicy"
// PutBucketPolicyRequest generates a "aws/request.Request" representing the // PutBucketPolicyRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketPolicy operation. The "output" return // client's request for the PutBucketPolicy operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5361,7 +5361,7 @@ const opPutBucketReplication = "PutBucketReplication"
// PutBucketReplicationRequest generates a "aws/request.Request" representing the // PutBucketReplicationRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketReplication operation. The "output" return // client's request for the PutBucketReplication operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5439,7 +5439,7 @@ const opPutBucketRequestPayment = "PutBucketRequestPayment"
// PutBucketRequestPaymentRequest generates a "aws/request.Request" representing the // PutBucketRequestPaymentRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketRequestPayment operation. The "output" return // client's request for the PutBucketRequestPayment operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5519,7 +5519,7 @@ const opPutBucketTagging = "PutBucketTagging"
// PutBucketTaggingRequest generates a "aws/request.Request" representing the // PutBucketTaggingRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketTagging operation. The "output" return // client's request for the PutBucketTagging operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5595,7 +5595,7 @@ const opPutBucketVersioning = "PutBucketVersioning"
// PutBucketVersioningRequest generates a "aws/request.Request" representing the // PutBucketVersioningRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketVersioning operation. The "output" return // client's request for the PutBucketVersioning operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5672,7 +5672,7 @@ const opPutBucketWebsite = "PutBucketWebsite"
// PutBucketWebsiteRequest generates a "aws/request.Request" representing the // PutBucketWebsiteRequest generates a "aws/request.Request" representing the
// client's request for the PutBucketWebsite operation. The "output" return // client's request for the PutBucketWebsite operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5748,7 +5748,7 @@ const opPutObject = "PutObject"
// PutObjectRequest generates a "aws/request.Request" representing the // PutObjectRequest generates a "aws/request.Request" representing the
// client's request for the PutObject operation. The "output" return // client's request for the PutObject operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5822,7 +5822,7 @@ const opPutObjectAcl = "PutObjectAcl"
// PutObjectAclRequest generates a "aws/request.Request" representing the // PutObjectAclRequest generates a "aws/request.Request" representing the
// client's request for the PutObjectAcl operation. The "output" return // client's request for the PutObjectAcl operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5902,7 +5902,7 @@ const opPutObjectTagging = "PutObjectTagging"
// PutObjectTaggingRequest generates a "aws/request.Request" representing the // PutObjectTaggingRequest generates a "aws/request.Request" representing the
// client's request for the PutObjectTagging operation. The "output" return // client's request for the PutObjectTagging operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -5976,7 +5976,7 @@ const opRestoreObject = "RestoreObject"
// RestoreObjectRequest generates a "aws/request.Request" representing the // RestoreObjectRequest generates a "aws/request.Request" representing the
// client's request for the RestoreObject operation. The "output" return // client's request for the RestoreObject operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -6055,7 +6055,7 @@ const opSelectObjectContent = "SelectObjectContent"
// SelectObjectContentRequest generates a "aws/request.Request" representing the // SelectObjectContentRequest generates a "aws/request.Request" representing the
// client's request for the SelectObjectContent operation. The "output" return // client's request for the SelectObjectContent operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -6137,7 +6137,7 @@ const opUploadPart = "UploadPart"
// UploadPartRequest generates a "aws/request.Request" representing the // UploadPartRequest generates a "aws/request.Request" representing the
// client's request for the UploadPart operation. The "output" return // client's request for the UploadPart operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -6217,7 +6217,7 @@ const opUploadPartCopy = "UploadPartCopy"
// UploadPartCopyRequest generates a "aws/request.Request" representing the // UploadPartCopyRequest generates a "aws/request.Request" representing the
// client's request for the UploadPartCopy operation. The "output" return // client's request for the UploadPartCopy operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.

View file

@ -3,6 +3,7 @@ package s3
import ( import (
"github.com/aws/aws-sdk-go/aws/client" "github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/s3err"
) )
func init() { func init() {
@ -21,6 +22,7 @@ func defaultInitClientFn(c *client.Client) {
// S3 uses custom error unmarshaling logic // S3 uses custom error unmarshaling logic
c.Handlers.UnmarshalError.Clear() c.Handlers.UnmarshalError.Clear()
c.Handlers.UnmarshalError.PushBack(unmarshalError) c.Handlers.UnmarshalError.PushBack(unmarshalError)
c.Handlers.UnmarshalError.PushBackNamed(s3err.RequestFailureWrapperHandler())
} }
func defaultInitRequestFn(r *request.Request) { func defaultInitRequestFn(r *request.Request) {
@ -42,6 +44,7 @@ func defaultInitRequestFn(r *request.Request) {
r.Handlers.Validate.PushFront(populateLocationConstraint) r.Handlers.Validate.PushFront(populateLocationConstraint)
case opCopyObject, opUploadPartCopy, opCompleteMultipartUpload: case opCopyObject, opUploadPartCopy, opCompleteMultipartUpload:
r.Handlers.Unmarshal.PushFront(copyMultipartStatusOKUnmarhsalError) r.Handlers.Unmarshal.PushFront(copyMultipartStatusOKUnmarhsalError)
r.Handlers.Unmarshal.PushBackNamed(s3err.RequestFailureWrapperHandler())
case opPutObject, opUploadPart: case opPutObject, opUploadPart:
r.Handlers.Build.PushBack(computeBodyHashes) r.Handlers.Build.PushBack(computeBodyHashes)
// Disabled until #1837 root issue is resolved. // Disabled until #1837 root issue is resolved.

View file

@ -67,7 +67,9 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
} }
// Handlers // Handlers
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) svc.Handlers.Sign.PushBackNamed(v4.BuildNamedHandler(v4.SignRequestHandler.Name, func(s *v4.Signer) {
s.DisableURIPathEscaping = true
}))
svc.Handlers.Build.PushBackNamed(restxml.BuildHandler) svc.Handlers.Build.PushBackNamed(restxml.BuildHandler)
svc.Handlers.Unmarshal.PushBackNamed(restxml.UnmarshalHandler) svc.Handlers.Unmarshal.PushBackNamed(restxml.UnmarshalHandler)
svc.Handlers.UnmarshalMeta.PushBackNamed(restxml.UnmarshalMetaHandler) svc.Handlers.UnmarshalMeta.PushBackNamed(restxml.UnmarshalMetaHandler)

View file

@ -13,7 +13,11 @@ import (
func copyMultipartStatusOKUnmarhsalError(r *request.Request) { func copyMultipartStatusOKUnmarhsalError(r *request.Request) {
b, err := ioutil.ReadAll(r.HTTPResponse.Body) b, err := ioutil.ReadAll(r.HTTPResponse.Body)
if err != nil { if err != nil {
r.Error = awserr.New("SerializationError", "unable to read response body", err) r.Error = awserr.NewRequestFailure(
awserr.New("SerializationError", "unable to read response body", err),
r.HTTPResponse.StatusCode,
r.RequestID,
)
return return
} }
body := bytes.NewReader(b) body := bytes.NewReader(b)

View file

@ -23,22 +23,17 @@ func unmarshalError(r *request.Request) {
defer r.HTTPResponse.Body.Close() defer r.HTTPResponse.Body.Close()
defer io.Copy(ioutil.Discard, r.HTTPResponse.Body) defer io.Copy(ioutil.Discard, r.HTTPResponse.Body)
hostID := r.HTTPResponse.Header.Get("X-Amz-Id-2")
// Bucket exists in a different region, and request needs // Bucket exists in a different region, and request needs
// to be made to the correct region. // to be made to the correct region.
if r.HTTPResponse.StatusCode == http.StatusMovedPermanently { if r.HTTPResponse.StatusCode == http.StatusMovedPermanently {
r.Error = requestFailure{ r.Error = awserr.NewRequestFailure(
RequestFailure: awserr.NewRequestFailure( awserr.New("BucketRegionError",
awserr.New("BucketRegionError", fmt.Sprintf("incorrect region, the bucket is not in '%s' region",
fmt.Sprintf("incorrect region, the bucket is not in '%s' region", aws.StringValue(r.Config.Region)),
aws.StringValue(r.Config.Region)), nil),
nil), r.HTTPResponse.StatusCode,
r.HTTPResponse.StatusCode, r.RequestID,
r.RequestID, )
),
hostID: hostID,
}
return return
} }
@ -63,14 +58,11 @@ func unmarshalError(r *request.Request) {
errMsg = statusText errMsg = statusText
} }
r.Error = requestFailure{ r.Error = awserr.NewRequestFailure(
RequestFailure: awserr.NewRequestFailure( awserr.New(errCode, errMsg, err),
awserr.New(errCode, errMsg, err), r.HTTPResponse.StatusCode,
r.HTTPResponse.StatusCode, r.RequestID,
r.RequestID, )
),
hostID: hostID,
}
} }
// A RequestFailure provides access to the S3 Request ID and Host ID values // A RequestFailure provides access to the S3 Request ID and Host ID values
@ -83,21 +75,3 @@ type RequestFailure interface {
// Host ID is the S3 Host ID needed for debug, and contacting support // Host ID is the S3 Host ID needed for debug, and contacting support
HostID() string HostID() string
} }
type requestFailure struct {
awserr.RequestFailure
hostID string
}
func (r requestFailure) Error() string {
extra := fmt.Sprintf("status code: %d, request id: %s, host id: %s",
r.StatusCode(), r.RequestID(), r.hostID)
return awserr.SprintError(r.Code(), r.Message(), extra, r.OrigErr())
}
func (r requestFailure) String() string {
return r.Error()
}
func (r requestFailure) HostID() string {
return r.hostID
}

View file

@ -15,7 +15,7 @@ const opAssumeRole = "AssumeRole"
// AssumeRoleRequest generates a "aws/request.Request" representing the // AssumeRoleRequest generates a "aws/request.Request" representing the
// client's request for the AssumeRole operation. The "output" return // client's request for the AssumeRole operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -209,7 +209,7 @@ const opAssumeRoleWithSAML = "AssumeRoleWithSAML"
// AssumeRoleWithSAMLRequest generates a "aws/request.Request" representing the // AssumeRoleWithSAMLRequest generates a "aws/request.Request" representing the
// client's request for the AssumeRoleWithSAML operation. The "output" return // client's request for the AssumeRoleWithSAML operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -391,7 +391,7 @@ const opAssumeRoleWithWebIdentity = "AssumeRoleWithWebIdentity"
// AssumeRoleWithWebIdentityRequest generates a "aws/request.Request" representing the // AssumeRoleWithWebIdentityRequest generates a "aws/request.Request" representing the
// client's request for the AssumeRoleWithWebIdentity operation. The "output" return // client's request for the AssumeRoleWithWebIdentity operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -602,7 +602,7 @@ const opDecodeAuthorizationMessage = "DecodeAuthorizationMessage"
// DecodeAuthorizationMessageRequest generates a "aws/request.Request" representing the // DecodeAuthorizationMessageRequest generates a "aws/request.Request" representing the
// client's request for the DecodeAuthorizationMessage operation. The "output" return // client's request for the DecodeAuthorizationMessage operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -714,7 +714,7 @@ const opGetCallerIdentity = "GetCallerIdentity"
// GetCallerIdentityRequest generates a "aws/request.Request" representing the // GetCallerIdentityRequest generates a "aws/request.Request" representing the
// client's request for the GetCallerIdentity operation. The "output" return // client's request for the GetCallerIdentity operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -789,7 +789,7 @@ const opGetFederationToken = "GetFederationToken"
// GetFederationTokenRequest generates a "aws/request.Request" representing the // GetFederationTokenRequest generates a "aws/request.Request" representing the
// client's request for the GetFederationToken operation. The "output" return // client's request for the GetFederationToken operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.
@ -958,7 +958,7 @@ const opGetSessionToken = "GetSessionToken"
// GetSessionTokenRequest generates a "aws/request.Request" representing the // GetSessionTokenRequest generates a "aws/request.Request" representing the
// client's request for the GetSessionToken operation. The "output" return // client's request for the GetSessionToken operation. The "output" return
// value will be populated with the request's response once the request completes // value will be populated with the request's response once the request completes
// successfuly. // successfully.
// //
// Use "Send" method on the returned Request to send the API call to the service. // Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error. // the "output" return value is not valid until after Send returns without error.

View file

@ -1,6 +0,0 @@
testdata/conf_out.ini
ini.sublime-project
ini.sublime-workspace
testdata/conf_reflect.ini
.idea
/.vscode

View file

@ -1,16 +0,0 @@
sudo: false
language: go
go:
- 1.6.x
- 1.7.x
- 1.8.x
- 1.9.x
- 1.10.x
script:
- go get golang.org/x/tools/cmd/cover
- go get github.com/smartystreets/goconvey
- mkdir -p $HOME/gopath/src/gopkg.in
- ln -s $HOME/gopath/src/github.com/go-ini/ini $HOME/gopath/src/gopkg.in/ini.v1
- cd $HOME/gopath/src/gopkg.in/ini.v1
- go test -v -cover -race

191
vendor/github.com/go-ini/ini/LICENSE generated vendored
View file

@ -1,191 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright 2014 Unknwon
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -1,15 +0,0 @@
.PHONY: build test bench vet coverage
build: vet bench
test:
go test -v -cover -race
bench:
go test -v -cover -race -test.bench=. -test.benchmem
vet:
go vet
coverage:
go test -coverprofile=c.out && go tool cover -html=c.out && rm c.out

View file

@ -1,44 +0,0 @@
INI [![Build Status](https://travis-ci.org/go-ini/ini.svg?branch=master)](https://travis-ci.org/go-ini/ini) [![Sourcegraph](https://img.shields.io/badge/view%20on-Sourcegraph-brightgreen.svg)](https://sourcegraph.com/github.com/go-ini/ini)
===
![](https://avatars0.githubusercontent.com/u/10216035?v=3&s=200)
Package ini provides INI file read and write functionality in Go.
## Features
- Load from multiple data sources(`[]byte`, file and `io.ReadCloser`) with overwrites.
- Read with recursion values.
- Read with parent-child sections.
- Read with auto-increment key names.
- Read with multiple-line values.
- Read with tons of helper methods.
- Read and convert values to Go types.
- Read and **WRITE** comments of sections and keys.
- Manipulate sections, keys and comments with ease.
- Keep sections and keys in order as you parse and save.
## Installation
To use a tagged revision:
```sh
$ go get gopkg.in/ini.v1
```
To use with latest changes:
```sh
$ go get github.com/go-ini/ini
```
Please add `-u` flag to update in the future.
## Getting Help
- [Getting Started](https://ini.unknwon.io/docs/intro/getting_started)
- [API Documentation](https://gowalker.org/gopkg.in/ini.v1)
## License
This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text.

View file

@ -1,32 +0,0 @@
// Copyright 2016 Unknwon
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package ini
import (
"fmt"
)
type ErrDelimiterNotFound struct {
Line string
}
func IsErrDelimiterNotFound(err error) bool {
_, ok := err.(ErrDelimiterNotFound)
return ok
}
func (err ErrDelimiterNotFound) Error() string {
return fmt.Sprintf("key-value delimiter not found: %s", err.Line)
}

414
vendor/github.com/go-ini/ini/file.go generated vendored
View file

@ -1,414 +0,0 @@
// Copyright 2017 Unknwon
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package ini
import (
"bytes"
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
"sync"
)
// File represents a combination of a or more INI file(s) in memory.
type File struct {
options LoadOptions
dataSources []dataSource
// Should make things safe, but sometimes doesn't matter.
BlockMode bool
lock sync.RWMutex
// To keep data in order.
sectionList []string
// Actual data is stored here.
sections map[string]*Section
NameMapper
ValueMapper
}
// newFile initializes File object with given data sources.
func newFile(dataSources []dataSource, opts LoadOptions) *File {
return &File{
BlockMode: true,
dataSources: dataSources,
sections: make(map[string]*Section),
sectionList: make([]string, 0, 10),
options: opts,
}
}
// Empty returns an empty file object.
func Empty() *File {
// Ignore error here, we sure our data is good.
f, _ := Load([]byte(""))
return f
}
// NewSection creates a new section.
func (f *File) NewSection(name string) (*Section, error) {
if len(name) == 0 {
return nil, errors.New("error creating new section: empty section name")
} else if f.options.Insensitive && name != DEFAULT_SECTION {
name = strings.ToLower(name)
}
if f.BlockMode {
f.lock.Lock()
defer f.lock.Unlock()
}
if inSlice(name, f.sectionList) {
return f.sections[name], nil
}
f.sectionList = append(f.sectionList, name)
f.sections[name] = newSection(f, name)
return f.sections[name], nil
}
// NewRawSection creates a new section with an unparseable body.
func (f *File) NewRawSection(name, body string) (*Section, error) {
section, err := f.NewSection(name)
if err != nil {
return nil, err
}
section.isRawSection = true
section.rawBody = body
return section, nil
}
// NewSections creates a list of sections.
func (f *File) NewSections(names ...string) (err error) {
for _, name := range names {
if _, err = f.NewSection(name); err != nil {
return err
}
}
return nil
}
// GetSection returns section by given name.
func (f *File) GetSection(name string) (*Section, error) {
if len(name) == 0 {
name = DEFAULT_SECTION
}
if f.options.Insensitive {
name = strings.ToLower(name)
}
if f.BlockMode {
f.lock.RLock()
defer f.lock.RUnlock()
}
sec := f.sections[name]
if sec == nil {
return nil, fmt.Errorf("section '%s' does not exist", name)
}
return sec, nil
}
// Section assumes named section exists and returns a zero-value when not.
func (f *File) Section(name string) *Section {
sec, err := f.GetSection(name)
if err != nil {
// Note: It's OK here because the only possible error is empty section name,
// but if it's empty, this piece of code won't be executed.
sec, _ = f.NewSection(name)
return sec
}
return sec
}
// Section returns list of Section.
func (f *File) Sections() []*Section {
if f.BlockMode {
f.lock.RLock()
defer f.lock.RUnlock()
}
sections := make([]*Section, len(f.sectionList))
for i, name := range f.sectionList {
sections[i] = f.sections[name]
}
return sections
}
// ChildSections returns a list of child sections of given section name.
func (f *File) ChildSections(name string) []*Section {
return f.Section(name).ChildSections()
}
// SectionStrings returns list of section names.
func (f *File) SectionStrings() []string {
list := make([]string, len(f.sectionList))
copy(list, f.sectionList)
return list
}
// DeleteSection deletes a section.
func (f *File) DeleteSection(name string) {
if f.BlockMode {
f.lock.Lock()
defer f.lock.Unlock()
}
if len(name) == 0 {
name = DEFAULT_SECTION
}
for i, s := range f.sectionList {
if s == name {
f.sectionList = append(f.sectionList[:i], f.sectionList[i+1:]...)
delete(f.sections, name)
return
}
}
}
func (f *File) reload(s dataSource) error {
r, err := s.ReadCloser()
if err != nil {
return err
}
defer r.Close()
return f.parse(r)
}
// Reload reloads and parses all data sources.
func (f *File) Reload() (err error) {
for _, s := range f.dataSources {
if err = f.reload(s); err != nil {
// In loose mode, we create an empty default section for nonexistent files.
if os.IsNotExist(err) && f.options.Loose {
f.parse(bytes.NewBuffer(nil))
continue
}
return err
}
}
return nil
}
// Append appends one or more data sources and reloads automatically.
func (f *File) Append(source interface{}, others ...interface{}) error {
ds, err := parseDataSource(source)
if err != nil {
return err
}
f.dataSources = append(f.dataSources, ds)
for _, s := range others {
ds, err = parseDataSource(s)
if err != nil {
return err
}
f.dataSources = append(f.dataSources, ds)
}
return f.Reload()
}
func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
equalSign := "="
if PrettyFormat || PrettyEqual {
equalSign = " = "
}
// Use buffer to make sure target is safe until finish encoding.
buf := bytes.NewBuffer(nil)
for i, sname := range f.sectionList {
sec := f.Section(sname)
if len(sec.Comment) > 0 {
// Support multiline comments
lines := strings.Split(sec.Comment, LineBreak)
for i := range lines {
if lines[i][0] != '#' && lines[i][0] != ';' {
lines[i] = "; " + lines[i]
} else {
lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:])
}
if _, err := buf.WriteString(lines[i] + LineBreak); err != nil {
return nil, err
}
}
}
if i > 0 || DefaultHeader {
if _, err := buf.WriteString("[" + sname + "]" + LineBreak); err != nil {
return nil, err
}
} else {
// Write nothing if default section is empty
if len(sec.keyList) == 0 {
continue
}
}
if sec.isRawSection {
if _, err := buf.WriteString(sec.rawBody); err != nil {
return nil, err
}
if PrettySection {
// Put a line between sections
if _, err := buf.WriteString(LineBreak); err != nil {
return nil, err
}
}
continue
}
// Count and generate alignment length and buffer spaces using the
// longest key. Keys may be modifed if they contain certain characters so
// we need to take that into account in our calculation.
alignLength := 0
if PrettyFormat {
for _, kname := range sec.keyList {
keyLength := len(kname)
// First case will surround key by ` and second by """
if strings.ContainsAny(kname, "\"=:") {
keyLength += 2
} else if strings.Contains(kname, "`") {
keyLength += 6
}
if keyLength > alignLength {
alignLength = keyLength
}
}
}
alignSpaces := bytes.Repeat([]byte(" "), alignLength)
KEY_LIST:
for _, kname := range sec.keyList {
key := sec.Key(kname)
if len(key.Comment) > 0 {
if len(indent) > 0 && sname != DEFAULT_SECTION {
buf.WriteString(indent)
}
// Support multiline comments
lines := strings.Split(key.Comment, LineBreak)
for i := range lines {
if lines[i][0] != '#' && lines[i][0] != ';' {
lines[i] = "; " + lines[i]
} else {
lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:])
}
if _, err := buf.WriteString(lines[i] + LineBreak); err != nil {
return nil, err
}
}
}
if len(indent) > 0 && sname != DEFAULT_SECTION {
buf.WriteString(indent)
}
switch {
case key.isAutoIncrement:
kname = "-"
case strings.ContainsAny(kname, "\"=:"):
kname = "`" + kname + "`"
case strings.Contains(kname, "`"):
kname = `"""` + kname + `"""`
}
for _, val := range key.ValueWithShadows() {
if _, err := buf.WriteString(kname); err != nil {
return nil, err
}
if key.isBooleanType {
if kname != sec.keyList[len(sec.keyList)-1] {
buf.WriteString(LineBreak)
}
continue KEY_LIST
}
// Write out alignment spaces before "=" sign
if PrettyFormat {
buf.Write(alignSpaces[:alignLength-len(kname)])
}
// In case key value contains "\n", "`", "\"", "#" or ";"
if strings.ContainsAny(val, "\n`") {
val = `"""` + val + `"""`
} else if !f.options.IgnoreInlineComment && strings.ContainsAny(val, "#;") {
val = "`" + val + "`"
}
if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil {
return nil, err
}
}
for _, val := range key.nestedValues {
if _, err := buf.WriteString(indent + " " + val + LineBreak); err != nil {
return nil, err
}
}
}
if PrettySection {
// Put a line between sections
if _, err := buf.WriteString(LineBreak); err != nil {
return nil, err
}
}
}
return buf, nil
}
// WriteToIndent writes content into io.Writer with given indention.
// If PrettyFormat has been set to be true,
// it will align "=" sign with spaces under each section.
func (f *File) WriteToIndent(w io.Writer, indent string) (int64, error) {
buf, err := f.writeToBuffer(indent)
if err != nil {
return 0, err
}
return buf.WriteTo(w)
}
// WriteTo writes file content into io.Writer.
func (f *File) WriteTo(w io.Writer) (int64, error) {
return f.WriteToIndent(w, "")
}
// SaveToIndent writes content to file system with given value indention.
func (f *File) SaveToIndent(filename, indent string) error {
// Note: Because we are truncating with os.Create,
// so it's safer to save to a temporary file location and rename afte done.
buf, err := f.writeToBuffer(indent)
if err != nil {
return err
}
return ioutil.WriteFile(filename, buf.Bytes(), 0666)
}
// SaveTo writes content to file system.
func (f *File) SaveTo(filename string) error {
return f.SaveToIndent(filename, "")
}

Some files were not shown because too many files have changed in this diff Show more