From 7ffc03ff8fbdcb743403beb70612aa79c8d4f009 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 22 Jul 2018 14:12:02 +0200 Subject: [PATCH 1/2] Update github.com/kurin/blazer to 0.5.0 This includes support for the upcoming B2 application keys feature. --- Gopkg.lock | 181 +- vendor/github.com/kurin/blazer/.gitignore | 2 +- vendor/github.com/kurin/blazer/b2/b2.go | 73 +- vendor/github.com/kurin/blazer/b2/b2_test.go | 12 +- vendor/github.com/kurin/blazer/b2/backend.go | 99 +- vendor/github.com/kurin/blazer/b2/baseline.go | 60 +- .../kurin/blazer/b2/integration_test.go | 222 +- vendor/github.com/kurin/blazer/b2/key.go | 148 ++ vendor/github.com/kurin/blazer/b2/reader.go | 149 +- vendor/github.com/kurin/blazer/b2/writer.go | 24 + vendor/github.com/kurin/blazer/base/base.go | 126 +- .../kurin/blazer/base/integration_test.go | 5 +- .../kurin/blazer/bin/b2keys/b2keys.go | 98 + .../kurin/blazer/bin/bonfire/bonfire.go | 43 + .../kurin/blazer/bonfire/bonfire.go | 257 +++ .../kurin/blazer/internal/b2types/b2types.go | 94 +- .../kurin/blazer/internal/pyre/api.go | 325 +++ .../kurin/blazer/internal/pyre/download.go | 136 ++ .../kurin/blazer/internal/pyre/large.go | 91 + .../blazer/internal/pyre/proto/pyre.pb.go | 1896 +++++++++++++++++ .../blazer/internal/pyre/proto/pyre.pb.gw.go | 484 +++++ .../blazer/internal/pyre/proto/pyre.proto | 335 +++ .../kurin/blazer/internal/pyre/pyre.go | 20 + .../kurin/blazer/internal/pyre/simple.go | 109 + .../blazer/x/consistent/consistent_test.go | 2 +- 25 files changed, 4655 insertions(+), 336 deletions(-) create mode 100644 vendor/github.com/kurin/blazer/b2/key.go create mode 100644 vendor/github.com/kurin/blazer/bin/b2keys/b2keys.go create mode 100644 vendor/github.com/kurin/blazer/bin/bonfire/bonfire.go create mode 100644 vendor/github.com/kurin/blazer/bonfire/bonfire.go create mode 100644 vendor/github.com/kurin/blazer/internal/pyre/api.go create mode 100644 vendor/github.com/kurin/blazer/internal/pyre/download.go create mode 100644 vendor/github.com/kurin/blazer/internal/pyre/large.go create mode 100644 vendor/github.com/kurin/blazer/internal/pyre/proto/pyre.pb.go create mode 100644 vendor/github.com/kurin/blazer/internal/pyre/proto/pyre.pb.gw.go create mode 100644 vendor/github.com/kurin/blazer/internal/pyre/proto/pyre.proto create mode 100644 vendor/github.com/kurin/blazer/internal/pyre/pyre.go create mode 100644 vendor/github.com/kurin/blazer/internal/pyre/simple.go diff --git a/Gopkg.lock b/Gopkg.lock index 4f6ce221f..54ee83b62 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -4,11 +4,7 @@ [[projects]] branch = "master" name = "bazil.org/fuse" - packages = [ - ".", - "fs", - "fuseutil" - ] + packages = [".","fs","fuseutil"] revision = "371fbbdaa8987b715bdd21d6adc4c9b20155f748" [[projects]] @@ -19,21 +15,13 @@ [[projects]] name = "github.com/Azure/azure-sdk-for-go" - packages = [ - "storage", - "version" - ] + packages = ["storage","version"] revision = "56332fec5b308fbb6615fa1af6117394cdba186d" version = "v15.0.0" [[projects]] name = "github.com/Azure/go-autorest" - packages = [ - "autorest", - "autorest/adal", - "autorest/azure", - "autorest/date" - ] + packages = ["autorest","autorest/adal","autorest/azure","autorest/date"] revision = "ed4b7f5bf1ec0c9ede1fda2681d96771282f2862" version = "v10.4.0" @@ -81,12 +69,7 @@ [[projects]] name = "github.com/google/go-cmp" - packages = [ - "cmp", - "cmp/internal/diff", - "cmp/internal/function", - "cmp/internal/value" - ] + packages = ["cmp","cmp/internal/diff","cmp/internal/function","cmp/internal/value"] revision = "8099a9787ce5dc5984ed879a3bda47dc730a8e97" version = "v0.1.0" @@ -110,16 +93,9 @@ [[projects]] name = "github.com/kurin/blazer" - packages = [ - "b2", - "base", - "internal/b2assets", - "internal/b2types", - "internal/blog", - "x/window" - ] - revision = "318e9768bf9a0fe52a64b9f8fe74f4f5caef6452" - version = "v0.4.4" + packages = ["b2","base","internal/b2assets","internal/b2types","internal/blog","x/window"] + revision = "7f1134c7489e86be5c924137996d4e421815f48a" + version = "v0.5.0" [[projects]] name = "github.com/marstr/guid" @@ -135,15 +111,7 @@ [[projects]] name = "github.com/minio/minio-go" - packages = [ - ".", - "pkg/credentials", - "pkg/encrypt", - "pkg/policy", - "pkg/s3signer", - "pkg/s3utils", - "pkg/set" - ] + packages = [".","pkg/credentials","pkg/encrypt","pkg/policy","pkg/s3signer","pkg/s3utils","pkg/set"] revision = "66252c2a3c15f7b90cc8493d497a04ac3b6e3606" version = "5.0.0" @@ -189,52 +157,6 @@ revision = "db83917be3b88cc307464b7d8a221c173e34a0db" version = "v0.2.0" -[[projects]] - branch = "master" - name = "github.com/restic/restic" - packages = [ - "internal/archiver", - "internal/backend", - "internal/backend/azure", - "internal/backend/b2", - "internal/backend/gs", - "internal/backend/local", - "internal/backend/location", - "internal/backend/mem", - "internal/backend/rclone", - "internal/backend/rest", - "internal/backend/s3", - "internal/backend/sftp", - "internal/backend/swift", - "internal/backend/test", - "internal/cache", - "internal/checker", - "internal/crypto", - "internal/debug", - "internal/errors", - "internal/filter", - "internal/fs", - "internal/fuse", - "internal/hashing", - "internal/index", - "internal/limiter", - "internal/list", - "internal/migrations", - "internal/mock", - "internal/options", - "internal/pack", - "internal/repository", - "internal/restic", - "internal/restorer", - "internal/test", - "internal/textfile", - "internal/ui", - "internal/ui/termstatus", - "internal/walker", - "internal/worker" - ] - revision = "bd742ddb692ffeaf5ac24eefdff0c0ba3e7c17fb" - [[projects]] name = "github.com/russross/blackfriday" packages = ["."] @@ -255,10 +177,7 @@ [[projects]] name = "github.com/spf13/cobra" - packages = [ - ".", - "doc" - ] + packages = [".","doc"] revision = "a1f051bc3eba734da4772d60e2d677f47cf93ef4" version = "v0.0.2" @@ -271,44 +190,19 @@ [[projects]] branch = "master" name = "golang.org/x/crypto" - packages = [ - "argon2", - "blake2b", - "curve25519", - "ed25519", - "ed25519/internal/edwards25519", - "internal/chacha20", - "pbkdf2", - "poly1305", - "scrypt", - "ssh", - "ssh/terminal" - ] + packages = ["argon2","blake2b","curve25519","ed25519","ed25519/internal/edwards25519","internal/chacha20","pbkdf2","poly1305","scrypt","ssh","ssh/terminal"] revision = "4ec37c66abab2c7e02ae775328b2ff001c3f025a" [[projects]] branch = "master" name = "golang.org/x/net" - packages = [ - "context", - "context/ctxhttp", - "http2", - "http2/hpack", - "idna", - "lex/httplex" - ] + packages = ["context","context/ctxhttp","http2","http2/hpack","idna","lex/httplex"] revision = "6078986fec03a1dcc236c34816c71b0e05018fda" [[projects]] branch = "master" name = "golang.org/x/oauth2" - packages = [ - ".", - "google", - "internal", - "jws", - "jwt" - ] + packages = [".","google","internal","jws","jwt"] revision = "fdc9e635145ae97e6c2cb777c48305600cf515cb" [[projects]] @@ -320,65 +214,24 @@ [[projects]] branch = "master" name = "golang.org/x/sys" - packages = [ - "cpu", - "unix", - "windows" - ] + packages = ["cpu","unix","windows"] revision = "7db1c3b1a98089d0071c84f646ff5c96aad43682" [[projects]] name = "golang.org/x/text" - packages = [ - "collate", - "collate/build", - "encoding", - "encoding/internal", - "encoding/internal/identifier", - "encoding/unicode", - "internal/colltab", - "internal/gen", - "internal/tag", - "internal/triegen", - "internal/ucd", - "internal/utf8internal", - "language", - "runes", - "secure/bidirule", - "transform", - "unicode/bidi", - "unicode/cldr", - "unicode/norm", - "unicode/rangetable" - ] + packages = ["collate","collate/build","encoding","encoding/internal","encoding/internal/identifier","encoding/unicode","internal/colltab","internal/gen","internal/tag","internal/triegen","internal/ucd","internal/utf8internal","language","runes","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"] revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" version = "v0.3.0" [[projects]] branch = "master" name = "google.golang.org/api" - packages = [ - "gensupport", - "googleapi", - "googleapi/internal/uritemplates", - "storage/v1" - ] + packages = ["gensupport","googleapi","googleapi/internal/uritemplates","storage/v1"] revision = "dbbc13f71100fa6ece308335445fca6bb0dd5c2f" [[projects]] name = "google.golang.org/appengine" - packages = [ - ".", - "internal", - "internal/app_identity", - "internal/base", - "internal/datastore", - "internal/log", - "internal/modules", - "internal/remote_api", - "internal/urlfetch", - "urlfetch" - ] + packages = [".","internal","internal/app_identity","internal/base","internal/datastore","internal/log","internal/modules","internal/remote_api","internal/urlfetch","urlfetch"] revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a" version = "v1.0.0" @@ -397,6 +250,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "cfab88aa746c1535f17c59e8db9ee2ca6908b840f71d7331de84c722221348d0" + inputs-digest = "a5de339cba7570216b212439b90e1e6c384c94be8342fe7755b7cb66aa0a3440" solver-name = "gps-cdcl" solver-version = 1 diff --git a/vendor/github.com/kurin/blazer/.gitignore b/vendor/github.com/kurin/blazer/.gitignore index 38a74b4d8..743c06aa7 100644 --- a/vendor/github.com/kurin/blazer/.gitignore +++ b/vendor/github.com/kurin/blazer/.gitignore @@ -1,4 +1,4 @@ -bonfire +bin/bonfire/bonfire # Compiled Object files, Static and Dynamic libs (Shared Objects) *.o diff --git a/vendor/github.com/kurin/blazer/b2/b2.go b/vendor/github.com/kurin/blazer/b2/b2.go index cd83b858e..8b2727a1b 100644 --- a/vendor/github.com/kurin/blazer/b2/b2.go +++ b/vendor/github.com/kurin/blazer/b2/b2.go @@ -32,6 +32,7 @@ import ( "fmt" "io" "net/http" + "net/url" "regexp" "strconv" "sync" @@ -46,6 +47,7 @@ type Client struct { sWriters map[string]*Writer sReaders map[string]*Reader sMethods []methodCounter + opts clientOptions } // NewClient creates and returns a new Client with valid B2 service account @@ -63,7 +65,10 @@ func NewClient(ctx context.Context, account, key string, opts ...ClientOption) ( }, } opts = append(opts, client(c)) - if err := c.backend.authorizeAccount(ctx, account, key, opts...); err != nil { + for _, f := range opts { + f(&c.opts) + } + if err := c.backend.authorizeAccount(ctx, account, key, c.opts); err != nil { return nil, err } return c, nil @@ -75,27 +80,9 @@ type clientOptions struct { failSomeUploads bool expireTokens bool capExceeded bool + apiBase string userAgents []string -} - -// for testing -func (c clientOptions) eq(o clientOptions) bool { - if c.client != o.client || - c.transport != o.transport || - c.failSomeUploads != o.failSomeUploads || - c.expireTokens != o.expireTokens || - c.capExceeded != o.capExceeded { - return false - } - if len(c.userAgents) != len(o.userAgents) { - return false - } - for i := range c.userAgents { - if c.userAgents[i] != o.userAgents[i] { - return false - } - } - return true + writerOpts []WriterOption } // A ClientOption allows callers to adjust various per-client settings. @@ -112,6 +99,13 @@ func UserAgent(agent string) ClientOption { } } +// APIBase returns a ClientOption specifying the URL root of API requests. +func APIBase(url string) ClientOption { + return func(o *clientOptions) { + o.apiBase = url + } +} + // Transport sets the underlying HTTP transport mechanism. If unset, // http.DefaultTransport is used. func Transport(rt http.RoundTripper) ClientOption { @@ -434,7 +428,7 @@ type Attrs struct { ContentType string // Used on upload, default is "application/octet-stream". Status ObjectState // Not used on upload. UploadTimestamp time.Time // Not used on upload. - SHA1 string // Not used on upload. Can be "none" for large files. + SHA1 string // Can be "none" for large files. If set on upload, will be used for large files. LastModified time.Time // If present, and there are fewer than 10 keys in the Info field, this is saved on upload. Info map[string]string // Save arbitrary metadata on upload, but limited to 10 keys. } @@ -474,6 +468,9 @@ func (o *Object) Attrs(ctx context.Context) (*Attrs, error) { mtime = time.Unix(ms/1e3, (ms%1e3)*1e6) delete(info, "src_last_modified_millis") } + if v, ok := info["large_file_sha1"]; ok { + sha = v + } return &Attrs{ Name: name, Size: size, @@ -524,14 +521,21 @@ func (o *Object) URL() string { // overwritten are not deleted, but are "hidden". // // Callers must close the writer when finished and check the error status. -func (o *Object) NewWriter(ctx context.Context) *Writer { +func (o *Object) NewWriter(ctx context.Context, opts ...WriterOption) *Writer { ctx, cancel := context.WithCancel(ctx) - return &Writer{ + w := &Writer{ o: o, name: o.name, ctx: ctx, cancel: cancel, } + for _, f := range o.b.c.opts.writerOpts { + f(w) + } + for _, f := range opts { + f(w) + } + return w } // NewRangeReader returns a reader for the given object, reading up to length @@ -760,5 +764,24 @@ func (b *Bucket) getObject(ctx context.Context, name string) (*Object, error) { // in a private bucket. Only objects that begin with prefix can be accessed. // The token expires after the given duration. func (b *Bucket) AuthToken(ctx context.Context, prefix string, valid time.Duration) (string, error) { - return b.b.getDownloadAuthorization(ctx, prefix, valid) + return b.b.getDownloadAuthorization(ctx, prefix, valid, "") +} + +// AuthURL returns a URL for the given object with embedded token and, +// possibly, b2ContentDisposition arguments. Leave b2cd blank for no content +// disposition. +func (o *Object) AuthURL(ctx context.Context, valid time.Duration, b2cd string) (*url.URL, error) { + token, err := o.b.b.getDownloadAuthorization(ctx, o.name, valid, b2cd) + if err != nil { + return nil, err + } + urlString := fmt.Sprintf("%s?Authorization=%s", o.URL(), url.QueryEscape(token)) + if b2cd != "" { + urlString = fmt.Sprintf("%s&b2ContentDisposition=%s", urlString, url.QueryEscape(b2cd)) + } + u, err := url.Parse(urlString) + if err != nil { + return nil, err + } + return u, nil } diff --git a/vendor/github.com/kurin/blazer/b2/b2_test.go b/vendor/github.com/kurin/blazer/b2/b2_test.go index add7d7567..1bb8ee4ab 100644 --- a/vendor/github.com/kurin/blazer/b2/b2_test.go +++ b/vendor/github.com/kurin/blazer/b2/b2_test.go @@ -71,7 +71,7 @@ type testRoot struct { bucketMap map[string]map[string]string } -func (t *testRoot) authorizeAccount(context.Context, string, string, ...ClientOption) error { +func (t *testRoot) authorizeAccount(context.Context, string, string, clientOptions) error { t.auths++ return nil } @@ -108,6 +108,13 @@ func (t *testRoot) transient(err error) bool { return e.retry || e.reupload || e.backoff > 0 } +func (t *testRoot) createKey(context.Context, string, []string, time.Duration, string, string) (b2KeyInterface, error) { + return nil, nil +} +func (t *testRoot) listKeys(context.Context, int, string) ([]b2KeyInterface, string, error) { + return nil, "", nil +} + func (t *testRoot) createBucket(_ context.Context, name, _ string, _ map[string]string, _ []LifecycleRule) (b2BucketInterface, error) { if err := t.errs.getError("createBucket"); err != nil { return nil, err @@ -147,6 +154,7 @@ func (t *testBucket) btype() string { return func (t *testBucket) attrs() *BucketAttrs { return nil } func (t *testBucket) deleteBucket(context.Context) error { return nil } func (t *testBucket) updateBucket(context.Context, *BucketAttrs) error { return nil } +func (t *testBucket) id() string { return "" } func (t *testBucket) getUploadURL(context.Context) (b2URLInterface, error) { if err := t.errs.getError("getUploadURL"); err != nil { @@ -221,7 +229,7 @@ func (t *testBucket) downloadFileByName(_ context.Context, name string, offset, } func (t *testBucket) hideFile(context.Context, string) (b2FileInterface, error) { return nil, nil } -func (t *testBucket) getDownloadAuthorization(context.Context, string, time.Duration) (string, error) { +func (t *testBucket) getDownloadAuthorization(context.Context, string, time.Duration, string) (string, error) { return "", nil } func (t *testBucket) baseURL() string { return "" } diff --git a/vendor/github.com/kurin/blazer/b2/backend.go b/vendor/github.com/kurin/blazer/b2/backend.go index 06de88023..bd91fef74 100644 --- a/vendor/github.com/kurin/blazer/b2/backend.go +++ b/vendor/github.com/kurin/blazer/b2/backend.go @@ -28,22 +28,25 @@ type beRootInterface interface { reauth(error) bool transient(error) bool reupload(error) bool - authorizeAccount(context.Context, string, string, ...ClientOption) error + authorizeAccount(context.Context, string, string, clientOptions) error reauthorizeAccount(context.Context) error createBucket(ctx context.Context, name, btype string, info map[string]string, rules []LifecycleRule) (beBucketInterface, error) listBuckets(context.Context) ([]beBucketInterface, error) + createKey(context.Context, string, []string, time.Duration, string, string) (beKeyInterface, error) + listKeys(context.Context, int, string) ([]beKeyInterface, string, error) } type beRoot struct { account, key string b2i b2RootInterface - options []ClientOption + options clientOptions } type beBucketInterface interface { name() string btype() BucketType attrs() *BucketAttrs + id() string updateBucket(context.Context, *BucketAttrs) error deleteBucket(context.Context) error getUploadURL(context.Context) (beURLInterface, error) @@ -53,7 +56,7 @@ type beBucketInterface interface { listUnfinishedLargeFiles(context.Context, int, string) ([]beFileInterface, string, error) downloadFileByName(context.Context, string, int64, int64) (beFileReaderInterface, error) hideFile(context.Context, string) (beFileInterface, error) - getDownloadAuthorization(context.Context, string, time.Duration) (string, error) + getDownloadAuthorization(context.Context, string, time.Duration, string) (string, error) baseURL() string file(string, string) beFileInterface } @@ -145,26 +148,39 @@ type beFileInfo struct { stamp time.Time } +type beKeyInterface interface { + del(context.Context) error + caps() []string + name() string + expires() time.Time + secret() string +} + +type beKey struct { + b2i beRootInterface + k b2KeyInterface +} + func (r *beRoot) backoff(err error) time.Duration { return r.b2i.backoff(err) } func (r *beRoot) reauth(err error) bool { return r.b2i.reauth(err) } func (r *beRoot) reupload(err error) bool { return r.b2i.reupload(err) } func (r *beRoot) transient(err error) bool { return r.b2i.transient(err) } -func (r *beRoot) authorizeAccount(ctx context.Context, account, key string, opts ...ClientOption) error { +func (r *beRoot) authorizeAccount(ctx context.Context, account, key string, c clientOptions) error { f := func() error { - if err := r.b2i.authorizeAccount(ctx, account, key, opts...); err != nil { + if err := r.b2i.authorizeAccount(ctx, account, key, c); err != nil { return err } r.account = account r.key = key - r.options = opts + r.options = c return nil } return withBackoff(ctx, r, f) } func (r *beRoot) reauthorizeAccount(ctx context.Context) error { - return r.authorizeAccount(ctx, r.account, r.key, r.options...) + return r.authorizeAccount(ctx, r.account, r.key, r.options) } func (r *beRoot) createBucket(ctx context.Context, name, btype string, info map[string]string, rules []LifecycleRule) (beBucketInterface, error) { @@ -213,17 +229,58 @@ func (r *beRoot) listBuckets(ctx context.Context) ([]beBucketInterface, error) { return buckets, nil } -func (b *beBucket) name() string { - return b.b2bucket.name() +func (r *beRoot) createKey(ctx context.Context, name string, caps []string, valid time.Duration, bucketID string, prefix string) (beKeyInterface, error) { + var k *beKey + f := func() error { + g := func() error { + got, err := r.b2i.createKey(ctx, name, caps, valid, bucketID, prefix) + if err != nil { + return err + } + k = &beKey{ + b2i: r, + k: got, + } + return nil + } + return withReauth(ctx, r, g) + } + if err := withBackoff(ctx, r, f); err != nil { + return nil, err + } + return k, nil } -func (b *beBucket) btype() BucketType { - return BucketType(b.b2bucket.btype()) +func (r *beRoot) listKeys(ctx context.Context, max int, next string) ([]beKeyInterface, string, error) { + var keys []beKeyInterface + var cur string + f := func() error { + g := func() error { + got, n, err := r.b2i.listKeys(ctx, max, next) + if err != nil { + return err + } + cur = n + for _, g := range got { + keys = append(keys, &beKey{ + b2i: r, + k: g, + }) + } + return nil + } + return withReauth(ctx, r, g) + } + if err := withBackoff(ctx, r, f); err != nil { + return nil, "", err + } + return keys, cur, nil } -func (b *beBucket) attrs() *BucketAttrs { - return b.b2bucket.attrs() -} +func (b *beBucket) name() string { return b.b2bucket.name() } +func (b *beBucket) btype() BucketType { return BucketType(b.b2bucket.btype()) } +func (b *beBucket) attrs() *BucketAttrs { return b.b2bucket.attrs() } +func (b *beBucket) id() string { return b.b2bucket.id() } func (b *beBucket) updateBucket(ctx context.Context, attrs *BucketAttrs) error { f := func() error { @@ -412,11 +469,11 @@ func (b *beBucket) hideFile(ctx context.Context, name string) (beFileInterface, return file, nil } -func (b *beBucket) getDownloadAuthorization(ctx context.Context, p string, v time.Duration) (string, error) { +func (b *beBucket) getDownloadAuthorization(ctx context.Context, p string, v time.Duration, s string) (string, error) { var tok string f := func() error { g := func() error { - t, err := b.b2bucket.getDownloadAuthorization(ctx, p, v) + t, err := b.b2bucket.getDownloadAuthorization(ctx, p, v, s) if err != nil { return err } @@ -649,6 +706,12 @@ func (b *beFilePart) number() int { return b.b2filePart.number() } func (b *beFilePart) sha1() string { return b.b2filePart.sha1() } func (b *beFilePart) size() int64 { return b.b2filePart.size() } +func (b *beKey) del(ctx context.Context) error { return b.k.del(ctx) } +func (b *beKey) caps() []string { return b.k.caps() } +func (b *beKey) name() string { return b.k.name() } +func (b *beKey) expires() time.Time { return b.k.expires() } +func (b *beKey) secret() string { return b.k.secret() } + func jitter(d time.Duration) time.Duration { f := float64(d) f /= 50 @@ -657,8 +720,8 @@ func jitter(d time.Duration) time.Duration { } func getBackoff(d time.Duration) time.Duration { - if d > 15*time.Second { - return d + jitter(d) + if d > 30*time.Second { + return 30*time.Second + jitter(d) } return d*2 + jitter(d*2) } diff --git a/vendor/github.com/kurin/blazer/b2/baseline.go b/vendor/github.com/kurin/blazer/b2/baseline.go index ffbe8d5ec..5ca43e6fa 100644 --- a/vendor/github.com/kurin/blazer/b2/baseline.go +++ b/vendor/github.com/kurin/blazer/b2/baseline.go @@ -27,19 +27,22 @@ import ( // the only file in b2 that imports base. type b2RootInterface interface { - authorizeAccount(context.Context, string, string, ...ClientOption) error + authorizeAccount(context.Context, string, string, clientOptions) error transient(error) bool backoff(error) time.Duration reauth(error) bool reupload(error) bool createBucket(context.Context, string, string, map[string]string, []LifecycleRule) (b2BucketInterface, error) listBuckets(context.Context) ([]b2BucketInterface, error) + createKey(context.Context, string, []string, time.Duration, string, string) (b2KeyInterface, error) + listKeys(context.Context, int, string) ([]b2KeyInterface, string, error) } type b2BucketInterface interface { name() string btype() string attrs() *BucketAttrs + id() string updateBucket(context.Context, *BucketAttrs) error deleteBucket(context.Context) error getUploadURL(context.Context) (b2URLInterface, error) @@ -49,7 +52,7 @@ type b2BucketInterface interface { listUnfinishedLargeFiles(context.Context, int, string) ([]b2FileInterface, string, error) downloadFileByName(context.Context, string, int64, int64) (b2FileReaderInterface, error) hideFile(context.Context, string) (b2FileInterface, error) - getDownloadAuthorization(context.Context, string, time.Duration) (string, error) + getDownloadAuthorization(context.Context, string, time.Duration, string) (string, error) baseURL() string file(string, string) b2FileInterface } @@ -96,6 +99,14 @@ type b2FilePartInterface interface { size() int64 } +type b2KeyInterface interface { + del(context.Context) error + caps() []string + name() string + expires() time.Time + secret() string +} + type b2Root struct { b *base.B2 } @@ -132,11 +143,11 @@ type b2FilePart struct { b *base.FilePart } -func (b *b2Root) authorizeAccount(ctx context.Context, account, key string, opts ...ClientOption) error { - c := &clientOptions{} - for _, f := range opts { - f(c) - } +type b2Key struct { + b *base.Key +} + +func (b *b2Root) authorizeAccount(ctx context.Context, account, key string, c clientOptions) error { var aopts []base.AuthOption ct := &clientTransport{client: c.client} if c.transport != nil { @@ -152,6 +163,9 @@ func (b *b2Root) authorizeAccount(ctx context.Context, account, key string, opts if c.capExceeded { aopts = append(aopts, base.ForceCapExceeded()) } + if c.apiBase != "" { + aopts = append(aopts, base.SetAPIBase(c.apiBase)) + } for _, agent := range c.userAgents { aopts = append(aopts, base.UserAgent(agent)) } @@ -249,6 +263,26 @@ func (b *b2Bucket) updateBucket(ctx context.Context, attrs *BucketAttrs) error { return err } +func (b *b2Root) createKey(ctx context.Context, name string, caps []string, valid time.Duration, bucketID string, prefix string) (b2KeyInterface, error) { + k, err := b.b.CreateKey(ctx, name, caps, valid, bucketID, prefix) + if err != nil { + return nil, err + } + return &b2Key{k}, nil +} + +func (b *b2Root) listKeys(ctx context.Context, max int, next string) ([]b2KeyInterface, string, error) { + keys, next, err := b.b.ListKeys(ctx, max, next) + if err != nil { + return nil, "", err + } + var k []b2KeyInterface + for _, key := range keys { + k = append(k, &b2Key{key}) + } + return k, next, nil +} + func (b *b2Bucket) deleteBucket(ctx context.Context) error { return b.b.DeleteBucket(ctx) } @@ -277,6 +311,8 @@ func (b *b2Bucket) attrs() *BucketAttrs { } } +func (b *b2Bucket) id() string { return b.b.ID } + func (b *b2Bucket) getUploadURL(ctx context.Context) (b2URLInterface, error) { url, err := b.b.GetUploadURL(ctx) if err != nil { @@ -352,8 +388,8 @@ func (b *b2Bucket) hideFile(ctx context.Context, name string) (b2FileInterface, return &b2File{f}, nil } -func (b *b2Bucket) getDownloadAuthorization(ctx context.Context, p string, v time.Duration) (string, error) { - return b.b.GetDownloadAuthorization(ctx, p, v) +func (b *b2Bucket) getDownloadAuthorization(ctx context.Context, p string, v time.Duration, s string) (string, error) { + return b.b.GetDownloadAuthorization(ctx, p, v, s) } func (b *b2Bucket) baseURL() string { @@ -466,3 +502,9 @@ func (b *b2FileInfo) stats() (string, string, int64, string, map[string]string, func (b *b2FilePart) number() int { return b.b.Number } func (b *b2FilePart) sha1() string { return b.b.SHA1 } func (b *b2FilePart) size() int64 { return b.b.Size } + +func (b *b2Key) del(ctx context.Context) error { return b.b.Delete(ctx) } +func (b *b2Key) caps() []string { return b.b.Capabilities } +func (b *b2Key) name() string { return b.b.Name } +func (b *b2Key) expires() time.Time { return b.b.Expires } +func (b *b2Key) secret() string { return b.b.Secret } diff --git a/vendor/github.com/kurin/blazer/b2/integration_test.go b/vendor/github.com/kurin/blazer/b2/integration_test.go index 1f7acefd6..401becac5 100644 --- a/vendor/github.com/kurin/blazer/b2/integration_test.go +++ b/vendor/github.com/kurin/blazer/b2/integration_test.go @@ -22,6 +22,7 @@ import ( "encoding/hex" "fmt" "io" + "io/ioutil" "net/http" "os" "reflect" @@ -29,6 +30,7 @@ import ( "testing" "time" + "github.com/kurin/blazer/internal/blog" "github.com/kurin/blazer/x/transport" ) @@ -137,6 +139,9 @@ func TestReaderFromLive(t *testing.T) { if rn != n { t.Errorf("Read from B2: got %d bytes, want %d bytes", rn, n) } + if err, ok := r.Verify(); ok && err != nil { + t.Errorf("Read from B2: %v", err) + } if err := r.Close(); err != nil { t.Errorf("r.Close(): %v", err) } @@ -323,6 +328,7 @@ func TestAttrs(t *testing.T) { for _, attrs := range attrlist { o := bucket.Object(e.name) w := o.NewWriter(ctx).WithAttrs(attrs) + w.ChunkSize = 5e6 if _, err := io.Copy(w, io.LimitReader(zReader{}, e.size)); err != nil { t.Error(err) continue @@ -429,6 +435,57 @@ func TestAuthTokLive(t *testing.T) { } } +func TestObjAuthTokLive(t *testing.T) { + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, time.Minute) + defer cancel() + bucket, done := startLiveTest(ctx, t) + defer done() + + table := []struct { + obj string + d time.Duration + b2cd string + }{ + { + obj: "foo/bar", + d: time.Minute, + }, + { + obj: "foo2/thing.pdf", + d: time.Minute, + b2cd: "attachment", + }, + { + obj: "foo2/thing.pdf", + d: time.Minute, + b2cd: `attachment; filename="what.png"`, + }, + } + + for _, e := range table { + fw := bucket.Object(e.obj).NewWriter(ctx) + io.Copy(fw, io.LimitReader(zReader{}, 1e5)) + if err := fw.Close(); err != nil { + t.Fatal(err) + } + + url, err := bucket.Object(e.obj).AuthURL(ctx, e.d, e.b2cd) + if err != nil { + t.Fatal(err) + } + + blog.V(2).Infof("downloading %s", url.String()) + frsp, err := http.Get(url.String()) + if err != nil { + t.Fatal(err) + } + if frsp.StatusCode != 200 { + t.Fatalf("%s: got %s, want 200", url.String(), frsp.Status) + } + } +} + func TestRangeReaderLive(t *testing.T) { ctx := context.Background() ctx, cancel := context.WithTimeout(ctx, time.Minute) @@ -510,6 +567,9 @@ func TestRangeReaderLive(t *testing.T) { if got != want { t.Errorf("NewRangeReader(_, %d, %d): got %q, want %q", e.offset, e.length, got, want) } + if err, ok := r.Verify(); ok && err != nil { + t.Errorf("NewRangeReader(_, %d, %d): %v", e.offset, e.length, err) + } } } @@ -863,29 +923,161 @@ func TestReauthPreservesOptions(t *testing.T) { bucket, done := startLiveTest(ctx, t) defer done() - var first []ClientOption - opts := bucket.r.(*beRoot).options - for _, o := range opts { - first = append(first, o) - } - + first := bucket.r.(*beRoot).options if err := bucket.r.reauthorizeAccount(ctx); err != nil { t.Fatalf("reauthorizeAccount: %v", err) } - second := bucket.r.(*beRoot).options - if len(second) != len(first) { - t.Fatalf("options mismatch: got %d options, wanted %d", len(second), len(first)) + if !reflect.DeepEqual(first, second) { + // Test that they are literally the same set of options, which is an + // implementation detail but is fine for now. + t.Errorf("options mismatch: got %v, want %v", second, first) + } +} + +func TestVerifyReader(t *testing.T) { + ctx := context.Background() + bucket, done := startLiveTest(ctx, t) + defer done() + + table := []struct { + name string + fakeSHA string + size int64 + off, len int64 + valid bool + }{ + { + name: "first", + size: 100, + off: 0, + len: -1, + valid: true, + }, + { + name: "second", + size: 100, + off: 0, + len: 100, + valid: true, + }, + { + name: "third", + size: 100, + off: 0, + len: 99, + valid: false, + }, + { + name: "fourth", + size: 5e6 + 100, + off: 0, + len: -1, + valid: false, + }, + { + name: "fifth", + size: 5e6 + 100, + off: 0, + len: -1, + fakeSHA: "fbc815f2d6518858dec83ccb46263875fc894d88", + valid: true, + }, } - var f, s clientOptions - for i := range first { - first[i](&f) - second[i](&s) + for _, e := range table { + o := bucket.Object(e.name) + w := o.NewWriter(ctx) + if e.fakeSHA != "" { + w = w.WithAttrs(&Attrs{SHA1: e.fakeSHA}) + } + w.ChunkSize = 5e6 + if _, err := io.Copy(w, io.LimitReader(zReader{}, e.size)); err != nil { + t.Error(err) + continue + } + if err := w.Close(); err != nil { + t.Error(err) + continue + } + r := o.NewRangeReader(ctx, e.off, e.len) + if _, err := io.Copy(ioutil.Discard, r); err != nil { + t.Error(err) + } + err, ok := r.Verify() + if ok != e.valid { + t.Errorf("%s: bad validity: got %v, want %v", e.name, ok, e.valid) + } + if e.valid && err != nil { + t.Errorf("%s does not verify: %v", e.name, err) + } + } +} + +func TestCreateDeleteKey(t *testing.T) { + ctx := context.Background() + bucket, done := startLiveTest(ctx, t) + defer done() + + table := []struct { + d time.Duration + e time.Time + bucket bool + cap []string + pfx string + }{ + { + cap: []string{"deleteKeys"}, + }, + { + d: time.Minute, + cap: []string{"deleteKeys"}, + pfx: "prefox", + }, + { + e: time.Now().Add(time.Minute), // + cap: []string{"writeFiles", "listFiles"}, + bucket: true, + }, + { + d: time.Minute, + cap: []string{"writeFiles", "listFiles"}, + pfx: "prefox", + bucket: true, + }, } - if !f.eq(s) { - t.Errorf("options mismatch: got %v, want %v", s, f) + for _, e := range table { + var opts []KeyOption + for _, cap := range e.cap { + opts = append(opts, Capability(cap)) + } + if e.d != 0 { + opts = append(opts, Lifetime(e.d)) + } + if !e.e.IsZero() { + opts = append(opts, Deadline(e.e)) + } + var key *Key + if e.bucket { + opts = append(opts, Prefix(e.pfx)) + bkey, err := bucket.CreateKey(ctx, "whee", opts...) + if err != nil { + t.Errorf("Bucket.CreateKey(%v, %v): %v", bucket.Name(), e, err) + continue + } + key = bkey + } else { + gkey, err := bucket.c.CreateKey(ctx, "whee", opts...) + if err != nil { + t.Errorf("Client.CreateKey(%v): %v", e, err) + continue + } + key = gkey + } + if err := key.Delete(ctx); err != nil { + t.Errorf("key.Delete(): %v", err) + } } } diff --git a/vendor/github.com/kurin/blazer/b2/key.go b/vendor/github.com/kurin/blazer/b2/key.go new file mode 100644 index 000000000..950780237 --- /dev/null +++ b/vendor/github.com/kurin/blazer/b2/key.go @@ -0,0 +1,148 @@ +// Copyright 2018, Google +// +// 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 b2 + +import ( + "context" + "errors" + "io" + "time" +) + +// Key is a B2 application key. A Key grants limited access on a global or +// per-bucket basis. +type Key struct { + c *Client + k beKeyInterface +} + +// Capabilities returns the list of capabilites granted by this application +// key. +func (k *Key) Capabilities() []string { return k.k.caps() } + +// Name returns the user-supplied name of this application key. Key names are +// useless. +func (k *Key) Name() string { return k.k.name() } + +// Expires returns the expiration date of this application key. +func (k *Key) Expires() time.Time { return k.k.expires() } + +// Delete removes the key from B2. +func (k *Key) Delete(ctx context.Context) error { return k.k.del(ctx) } + +// Secret returns the value that should be passed into NewClient(). It is only +// available on newly created keys; it is not available from ListKey +// operations. +func (k *Key) Secret() string { return k.k.secret() } + +type keyOptions struct { + caps []string + prefix string + lifetime time.Duration +} + +// KeyOption specifies desired properties for application keys. +type KeyOption func(*keyOptions) + +// Lifetime requests a key with the given lifetime. +func Lifetime(d time.Duration) KeyOption { + return func(k *keyOptions) { + k.lifetime = d + } +} + +// Deadline requests a key that expires after the given date. +func Deadline(t time.Time) KeyOption { + d := t.Sub(time.Now()) + return Lifetime(d) +} + +// Capability requests a key with the given capability. +func Capability(cap string) KeyOption { + return func(k *keyOptions) { + k.caps = append(k.caps, cap) + } +} + +// Prefix limits the requested application key to be valid only for objects +// that begin with prefix. This can only be used when requesting an +// application key within a specific bucket. +func Prefix(prefix string) KeyOption { + return func(k *keyOptions) { + k.prefix = prefix + } +} + +// CreateKey creates a global application key that is valid for all buckets in +// this project. The key's secret will only be accessible on the object +// returned from this call. +func (c *Client) CreateKey(ctx context.Context, name string, opts ...KeyOption) (*Key, error) { + var ko keyOptions + for _, o := range opts { + o(&ko) + } + if ko.prefix != "" { + return nil, errors.New("Prefix is not a valid option for global application keys") + } + ki, err := c.backend.createKey(ctx, name, ko.caps, ko.lifetime, "", "") + if err != nil { + return nil, err + } + return &Key{ + c: c, + k: ki, + }, nil +} + +// ListKeys lists all the keys associated with this project. It takes the +// maximum number of keys it should return in a call, as well as a cursor +// (which should be empty for the initial call). It will return up to count +// keys, as well as the cursor for the next invocation. +// +// ListKeys returns io.EOF when there are no more keys, although it may do so +// concurrently with the final set of keys. +func (c *Client) ListKeys(ctx context.Context, count int, cursor string) ([]*Key, string, error) { + ks, next, err := c.backend.listKeys(ctx, count, cursor) + if err != nil { + return nil, "", err + } + if len(ks) == 0 { + return nil, "", io.EOF + } + var keys []*Key + for _, k := range ks { + keys = append(keys, &Key{ + c: c, + k: k, + }) + } + return keys, next, nil +} + +// CreateKey creates a scoped application key that is valid only for this bucket. +func (b *Bucket) CreateKey(ctx context.Context, name string, opts ...KeyOption) (*Key, error) { + var ko keyOptions + for _, o := range opts { + o(&ko) + } + ki, err := b.r.createKey(ctx, name, ko.caps, ko.lifetime, b.b.id(), ko.prefix) + if err != nil { + return nil, err + } + return &Key{ + c: b.c, + k: ki, + }, nil +} diff --git a/vendor/github.com/kurin/blazer/b2/reader.go b/vendor/github.com/kurin/blazer/b2/reader.go index 643e17dcf..37a90fd9c 100644 --- a/vendor/github.com/kurin/blazer/b2/reader.go +++ b/vendor/github.com/kurin/blazer/b2/reader.go @@ -17,9 +17,13 @@ package b2 import ( "bytes" "context" + "crypto/sha1" "errors" + "fmt" + "hash" "io" "sync" + "time" "github.com/kurin/blazer/internal/blog" ) @@ -38,21 +42,25 @@ type Reader struct { // 10MB. ChunkSize int - ctx context.Context - cancel context.CancelFunc // cancels ctx - o *Object - name string - offset int64 // the start of the file - length int64 // the length to read, or -1 - csize int // chunk size - read int // amount read - chwid int // chunks written - chrid int // chunks read - chbuf chan *rchunk - init sync.Once - rmux sync.Mutex // guards rcond - rcond *sync.Cond - chunks map[int]*rchunk + ctx context.Context + cancel context.CancelFunc // cancels ctx + o *Object + name string + offset int64 // the start of the file + length int64 // the length to read, or -1 + csize int // chunk size + read int // amount read + chwid int // chunks written + chrid int // chunks read + chbuf chan *rchunk + init sync.Once + chunks map[int]*rchunk + vrfy hash.Hash + readOffEnd bool + sha1 string + + rmux sync.Mutex // guards rcond + rcond *sync.Cond emux sync.RWMutex // guards err, believe it or not err error @@ -122,10 +130,12 @@ func (r *Reader) thread() { } r.length -= size } + var b backoff redo: fr, err := r.o.b.b.downloadFileByName(r.ctx, r.name, offset, size) if err == errNoMoreContent { // this read generated a 416 so we are entirely past the end of the object + r.readOffEnd = true buf.final = true r.rmux.Lock() r.chunks[chunkID] = buf @@ -138,7 +148,10 @@ func (r *Reader) thread() { r.rcond.Broadcast() return } - rsize, _, _, _ := fr.stats() + rsize, _, sha1, _ := fr.stats() + if len(sha1) == 40 && r.sha1 != sha1 { + r.sha1 = sha1 + } mr := &meteredReader{r: noopResetter{fr}, size: int(rsize)} r.smux.Lock() r.smap[chunkID] = mr @@ -150,7 +163,12 @@ func (r *Reader) thread() { r.smux.Unlock() if i < int64(rsize) || err == io.ErrUnexpectedEOF { // Probably the network connection was closed early. Retry. - blog.V(1).Infof("b2 reader %d: got %dB of %dB; retrying", chunkID, i, rsize) + blog.V(1).Infof("b2 reader %d: got %dB of %dB; retrying after %v", chunkID, i, rsize, b) + if err := b.wait(r.ctx); err != nil { + r.setErr(err) + r.rcond.Broadcast() + return + } buf.Reset() goto redo } @@ -211,13 +229,13 @@ func (r *Reader) initFunc() { r.thread() r.chbuf <- &rchunk{} } + r.vrfy = sha1.New() } func (r *Reader) Read(p []byte) (int, error) { if err := r.getErr(); err != nil { return 0, err } - // TODO: check the SHA1 hash here and verify it on Close. r.init.Do(r.initFunc) chunk, err := r.curChunk() if err != nil { @@ -225,6 +243,7 @@ func (r *Reader) Read(p []byte) (int, error) { return 0, err } n, err := chunk.Read(p) + r.vrfy.Write(p[:n]) // Hash.Write never returns an error. r.read += n if err == io.EOF { if chunk.final { @@ -256,38 +275,49 @@ func (r *Reader) status() *ReaderStatus { return rs } -// copied from io.Copy, basically. -func copyContext(ctx context.Context, dst io.Writer, src io.Reader) (written int64, err error) { - buf := make([]byte, 32*1024) - for { - if ctx.Err() != nil { - err = ctx.Err() - return - } - nr, er := src.Read(buf) - if nr > 0 { - nw, ew := dst.Write(buf[0:nr]) - if nw > 0 { - written += int64(nw) - } - if ew != nil { - err = ew - break - } - if nr != nw { - err = io.ErrShortWrite - break - } - } - if er == io.EOF { - break - } - if er != nil { - err = er - break - } +// Verify checks the SHA1 hash on download and compares it to the SHA1 hash +// submitted on upload. If the two differ, this returns an error. If the +// correct hash could not be calculated (if, for example, the entire object was +// not read, or if the object was uploaded as a "large file" and thus the SHA1 +// hash was not sent), this returns (nil, false). +func (r *Reader) Verify() (error, bool) { + got := fmt.Sprintf("%x", r.vrfy.Sum(nil)) + if r.sha1 == got { + return nil, true + } + // TODO: if the exact length of the file is requested AND the checksum is + // bad, this will return (nil, false) instead of (an error, true). This is + // because there's no good way that I can tell to determine that we've hit + // the end of the file without reading off the end. Consider reading N+1 + // bytes at the very end to close this hole. + if r.offset > 0 || !r.readOffEnd || len(r.sha1) != 40 { + return nil, false + } + return fmt.Errorf("bad hash: got %v, want %v", got, r.sha1), true +} + +// strip a writer of any non-Write methods +type onlyWriter struct{ w io.Writer } + +func (ow onlyWriter) Write(p []byte) (int, error) { return ow.w.Write(p) } + +func copyContext(ctx context.Context, w io.Writer, r io.Reader) (int64, error) { + var n int64 + var err error + done := make(chan struct{}) + go func() { + if _, ok := w.(*Writer); ok { + w = onlyWriter{w} + } + n, err = io.Copy(w, r) + close(done) + }() + select { + case <-done: + return n, err + case <-ctx.Done(): + return 0, ctx.Err() } - return written, err } type noopResetter struct { @@ -295,3 +325,24 @@ type noopResetter struct { } func (noopResetter) Reset() error { return nil } + +type backoff time.Duration + +func (b *backoff) wait(ctx context.Context) error { + if *b == 0 { + *b = backoff(time.Millisecond) + } + select { + case <-time.After(time.Duration(*b)): + if time.Duration(*b) < time.Second*10 { + *b <<= 1 + } + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func (b backoff) String() string { + return time.Duration(b).String() +} diff --git a/vendor/github.com/kurin/blazer/b2/writer.go b/vendor/github.com/kurin/blazer/b2/writer.go index becfc5844..ce8e69092 100644 --- a/vendor/github.com/kurin/blazer/b2/writer.go +++ b/vendor/github.com/kurin/blazer/b2/writer.go @@ -476,18 +476,42 @@ func (w *Writer) Close() error { // WithAttrs sets the writable attributes of the resulting file to given // values. WithAttrs must be called before the first call to Write. +// +// DEPRECATED: Use WithAttrsOption instead. func (w *Writer) WithAttrs(attrs *Attrs) *Writer { w.contentType = attrs.ContentType w.info = make(map[string]string) for k, v := range attrs.Info { w.info[k] = v } + if len(w.info) < 10 && attrs.SHA1 != "" { + w.info["large_file_sha1"] = attrs.SHA1 + } if len(w.info) < 10 && !attrs.LastModified.IsZero() { w.info["src_last_modified_millis"] = fmt.Sprintf("%d", attrs.LastModified.UnixNano()/1e6) } return w } +// A WriterOption sets Writer-specific behavior. +type WriterOption func(*Writer) + +// WithAttrs attaches the given Attrs to the writer. +func WithAttrsOption(attrs *Attrs) WriterOption { + return func(w *Writer) { + w.WithAttrs(attrs) + } +} + +// DefaultWriterOptions returns a ClientOption that will apply the given +// WriterOptions to every Writer. These options can be overridden by passing +// new options to NewWriter. +func DefaultWriterOptions(opts ...WriterOption) ClientOption { + return func(c *clientOptions) { + c.writerOpts = opts + } +} + func (w *Writer) status() *WriterStatus { w.smux.RLock() defer w.smux.RUnlock() diff --git a/vendor/github.com/kurin/blazer/base/base.go b/vendor/github.com/kurin/blazer/base/base.go index 11cd0da5a..db8867ea2 100644 --- a/vendor/github.com/kurin/blazer/base/base.go +++ b/vendor/github.com/kurin/blazer/base/base.go @@ -42,7 +42,7 @@ import ( const ( APIBase = "https://api.backblazeb2.com" - DefaultUserAgent = "blazer/0.4.4" + DefaultUserAgent = "blazer/0.5.0" ) type b2err struct { @@ -427,7 +427,7 @@ func AuthorizeAccount(ctx context.Context, account, key string, opts ...AuthOpti authToken: b2resp.AuthToken, apiURI: b2resp.URI, downloadURI: b2resp.DownloadURI, - minPartSize: b2resp.MinPartSize, + minPartSize: b2resp.PartSize, opts: b2opts, }, nil } @@ -479,6 +479,14 @@ func ForceCapExceeded() AuthOption { } } +// SetAPIBase returns an AuthOption that uses the given URL as the base for API +// requests. +func SetAPIBase(url string) AuthOption { + return func(o *b2Options) { + o.apiBase = url + } +} + type LifecycleRule struct { Prefix string DaysNewUntilHidden int @@ -524,7 +532,7 @@ func (b *B2) CreateBucket(ctx context.Context, name, btype string, info map[stri Name: name, Info: b2resp.Info, LifecycleRules: respRules, - id: b2resp.BucketID, + ID: b2resp.BucketID, rev: b2resp.Revision, b2: b, }, nil @@ -534,7 +542,7 @@ func (b *B2) CreateBucket(ctx context.Context, name, btype string, info map[stri func (b *Bucket) DeleteBucket(ctx context.Context) error { b2req := &b2types.DeleteBucketRequest{ AccountID: b.b2.accountID, - BucketID: b.id, + BucketID: b.ID, } headers := map[string]string{ "Authorization": b.b2.authToken, @@ -548,7 +556,7 @@ type Bucket struct { Type string Info map[string]string LifecycleRules []LifecycleRule - id string + ID string rev int b2 *B2 } @@ -565,7 +573,7 @@ func (b *Bucket) Update(ctx context.Context) (*Bucket, error) { } b2req := &b2types.UpdateBucketRequest{ AccountID: b.b2.accountID, - BucketID: b.id, + BucketID: b.ID, // Name: b.Name, Type: b.Type, Info: b.Info, @@ -592,7 +600,7 @@ func (b *Bucket) Update(ctx context.Context) (*Bucket, error) { Type: b2resp.Type, Info: b2resp.Info, LifecycleRules: respRules, - id: b2resp.BucketID, + ID: b2resp.BucketID, b2: b.b2, }, nil } @@ -629,7 +637,7 @@ func (b *B2) ListBuckets(ctx context.Context) ([]*Bucket, error) { Type: bucket.Type, Info: bucket.Info, LifecycleRules: rules, - id: bucket.BucketID, + ID: bucket.BucketID, rev: bucket.Revision, b2: b, }) @@ -660,7 +668,7 @@ func (url *URL) Reload(ctx context.Context) error { // GetUploadURL wraps b2_get_upload_url. func (b *Bucket) GetUploadURL(ctx context.Context) (*URL, error) { b2req := &b2types.GetUploadURLRequest{ - BucketID: b.id, + BucketID: b.ID, } b2resp := &b2types.GetUploadURLResponse{} headers := map[string]string{ @@ -745,7 +753,7 @@ type LargeFile struct { // StartLargeFile wraps b2_start_large_file. func (b *Bucket) StartLargeFile(ctx context.Context, name, contentType string, info map[string]string) (*LargeFile, error) { b2req := &b2types.StartLargeFileRequest{ - BucketID: b.id, + BucketID: b.ID, Name: name, ContentType: contentType, Info: info, @@ -927,7 +935,7 @@ func (l *LargeFile) FinishLargeFile(ctx context.Context) (*File, error) { // ListUnfinishedLargeFiles wraps b2_list_unfinished_large_files. func (b *Bucket) ListUnfinishedLargeFiles(ctx context.Context, count int, continuation string) ([]*File, string, error) { b2req := &b2types.ListUnfinishedLargeFilesRequest{ - BucketID: b.id, + BucketID: b.ID, Continuation: continuation, Count: count, } @@ -962,7 +970,7 @@ func (b *Bucket) ListFileNames(ctx context.Context, count int, continuation, pre b2req := &b2types.ListFileNamesRequest{ Count: count, Continuation: continuation, - BucketID: b.id, + BucketID: b.ID, Prefix: prefix, Delimiter: delimiter, } @@ -1000,7 +1008,7 @@ func (b *Bucket) ListFileNames(ctx context.Context, count int, continuation, pre // ListFileVersions wraps b2_list_file_versions. func (b *Bucket) ListFileVersions(ctx context.Context, count int, startName, startID, prefix, delimiter string) ([]*File, string, string, error) { b2req := &b2types.ListFileVersionsRequest{ - BucketID: b.id, + BucketID: b.ID, Count: count, StartName: startName, StartID: startID, @@ -1038,11 +1046,12 @@ func (b *Bucket) ListFileVersions(ctx context.Context, count int, startName, sta } // GetDownloadAuthorization wraps b2_get_download_authorization. -func (b *Bucket) GetDownloadAuthorization(ctx context.Context, prefix string, valid time.Duration) (string, error) { +func (b *Bucket) GetDownloadAuthorization(ctx context.Context, prefix string, valid time.Duration, contentDisposition string) (string, error) { b2req := &b2types.GetDownloadAuthorizationRequest{ - BucketID: b.id, - Prefix: prefix, - Valid: int(valid.Seconds()), + BucketID: b.ID, + Prefix: prefix, + Valid: int(valid.Seconds()), + ContentDisposition: contentDisposition, } b2resp := &b2types.GetDownloadAuthorizationResponse{} headers := map[string]string{ @@ -1121,9 +1130,13 @@ func (b *Bucket) DownloadFileByName(ctx context.Context, name string, offset, si } info[name] = val } + sha1 := resp.Header.Get("X-Bz-Content-Sha1") + if sha1 == "none" && info["Large_file_sha1"] != "" { + sha1 = info["Large_file_sha1"] + } return &FileReader{ ReadCloser: resp.Body, - SHA1: resp.Header.Get("X-Bz-Content-Sha1"), + SHA1: sha1, ID: resp.Header.Get("X-Bz-File-Id"), ContentType: resp.Header.Get("Content-Type"), ContentLength: int(clen), @@ -1134,7 +1147,7 @@ func (b *Bucket) DownloadFileByName(ctx context.Context, name string, offset, si // HideFile wraps b2_hide_file. func (b *Bucket) HideFile(ctx context.Context, name string) (*File, error) { b2req := &b2types.HideFileRequest{ - BucketID: b.id, + BucketID: b.ID, File: name, } b2resp := &b2types.HideFileResponse{} @@ -1190,3 +1203,78 @@ func (f *File) GetFileInfo(ctx context.Context) (*FileInfo, error) { } return f.Info, nil } + +// Key is a B2 application key. +type Key struct { + ID string + Secret string + Name string + Capabilities []string + Expires time.Time + b2 *B2 +} + +// CreateKey wraps b2_create_key. +func (b *B2) CreateKey(ctx context.Context, name string, caps []string, valid time.Duration, bucketID string, prefix string) (*Key, error) { + b2req := &b2types.CreateKeyRequest{ + AccountID: b.accountID, + Capabilities: caps, + Name: name, + Valid: int(valid.Seconds()), + BucketID: bucketID, + Prefix: prefix, + } + b2resp := &b2types.CreateKeyResponse{} + headers := map[string]string{ + "Authorization": b.authToken, + } + if err := b.opts.makeRequest(ctx, "b2_create_key", "POST", b.apiURI+b2types.V1api+"b2_create_key", b2req, b2resp, headers, nil); err != nil { + return nil, err + } + return &Key{ + Name: b2resp.Name, + ID: b2resp.ID, + Secret: b2resp.Secret, + Capabilities: b2resp.Capabilities, + Expires: millitime(b2resp.Expires), + b2: b, + }, nil +} + +// Delete wraps b2_delete_key. +func (k *Key) Delete(ctx context.Context) error { + b2req := &b2types.DeleteKeyRequest{ + KeyID: k.ID, + } + headers := map[string]string{ + "Authorization": k.b2.authToken, + } + return k.b2.opts.makeRequest(ctx, "b2_delete_key", "POST", k.b2.apiURI+b2types.V1api+"b2_delete_key", b2req, nil, headers, nil) +} + +// ListKeys wraps b2_list_keys. +func (b *B2) ListKeys(ctx context.Context, max int, next string) ([]*Key, string, error) { + b2req := &b2types.ListKeysRequest{ + AccountID: b.accountID, + Max: max, + Next: next, + } + headers := map[string]string{ + "Authorization": b.authToken, + } + b2resp := &b2types.ListKeysResponse{} + if err := b.opts.makeRequest(ctx, "b2_create_key", "POST", b.apiURI+b2types.V1api+"b2_create_key", b2req, b2resp, headers, nil); err != nil { + return nil, "", err + } + var keys []*Key + for _, key := range b2resp.Keys { + keys = append(keys, &Key{ + Name: key.Name, + ID: key.ID, + Capabilities: key.Capabilities, + Expires: millitime(key.Expires), + b2: b, + }) + } + return keys, b2resp.Next, nil +} diff --git a/vendor/github.com/kurin/blazer/base/integration_test.go b/vendor/github.com/kurin/blazer/base/integration_test.go index 7e615bca9..1e4ce1b6c 100644 --- a/vendor/github.com/kurin/blazer/base/integration_test.go +++ b/vendor/github.com/kurin/blazer/base/integration_test.go @@ -265,7 +265,7 @@ func TestStorage(t *testing.T) { } // b2_get_download_authorization - if _, err := bucket.GetDownloadAuthorization(ctx, "foo/", 24*time.Hour); err != nil { + if _, err := bucket.GetDownloadAuthorization(ctx, "foo/", 24*time.Hour, "attachment"); err != nil { t.Errorf("failed to get download auth token: %v", err) } } @@ -280,7 +280,7 @@ func TestUploadAuthAfterConnectionHang(t *testing.T) { hung := make(chan struct{}) - // An http.RoundTripper that dies after sending ~10k bytes. + // An http.RoundTripper that dies and hangs after sending ~10k bytes. hang := func() { close(hung) select {} @@ -317,7 +317,6 @@ func TestUploadAuthAfterConnectionHang(t *testing.T) { go func() { ue.UploadFile(ctx, buf, buf.Len(), smallFileName, "application/octet-stream", smallSHA1, nil) - t.Fatal("this ought not to be reachable") }() <-hung diff --git a/vendor/github.com/kurin/blazer/bin/b2keys/b2keys.go b/vendor/github.com/kurin/blazer/bin/b2keys/b2keys.go new file mode 100644 index 000000000..2a29bb8a6 --- /dev/null +++ b/vendor/github.com/kurin/blazer/bin/b2keys/b2keys.go @@ -0,0 +1,98 @@ +// b2keys is a small utility for managing Backblaze B2 keys. +package main + +import ( + "context" + "flag" + "fmt" + "os" + "time" + + "github.com/google/subcommands" + "github.com/kurin/blazer/b2" +) + +const ( + apiID = "B2_ACCOUNT_ID" + apiKey = "B2_SECRET_KEY" +) + +func main() { + subcommands.Register(&create{}, "") + flag.Parse() + ctx := context.Background() + os.Exit(int(subcommands.Execute(ctx))) +} + +type create struct { + d *time.Duration + bucket *string + pfx *string +} + +func (c *create) Name() string { return "create" } +func (c *create) Synopsis() string { return "create a new application key" } +func (c *create) Usage() string { + return "b2keys create [-bucket bucket] [-duration duration] [-prefix pfx] name capability [capability ...]" +} + +func (c *create) SetFlags(fs *flag.FlagSet) { + c.d = fs.Duration("duration", 0, "the lifetime of the new key") + c.bucket = fs.String("bucket", "", "limit the key to the given bucket") + c.pfx = fs.String("prefix", "", "limit the key to the objects starting with prefix") +} + +func (c *create) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus { + id := os.Getenv(apiID) + key := os.Getenv(apiKey) + if id == "" || key == "" { + fmt.Fprintf(os.Stderr, "both %s and %s must be set in the environment", apiID, apiKey) + return subcommands.ExitUsageError + } + + args := f.Args() + if len(args) < 2 { + fmt.Fprintf(os.Stderr, "%s\n", c.Usage()) + return subcommands.ExitUsageError + } + name := args[0] + caps := args[1:] + + var opts []b2.KeyOption + if *c.d > 0 { + opts = append(opts, b2.Lifetime(*c.d)) + } + if *c.pfx != "" { + opts = append(opts, b2.Prefix(*c.pfx)) + } + for _, c := range caps { + opts = append(opts, b2.Capability(c)) + } + + client, err := b2.NewClient(ctx, id, key, b2.UserAgent("b2keys")) + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return subcommands.ExitFailure + } + + var cr creater = client + + if *c.bucket != "" { + bucket, err := client.Bucket(ctx, *c.bucket) + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return subcommands.ExitFailure + } + cr = bucket + } + + if _, err := cr.CreateKey(ctx, name, opts...); err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return subcommands.ExitFailure + } + return subcommands.ExitSuccess +} + +type creater interface { + CreateKey(context.Context, string, ...b2.KeyOption) (*b2.Key, error) +} diff --git a/vendor/github.com/kurin/blazer/bin/bonfire/bonfire.go b/vendor/github.com/kurin/blazer/bin/bonfire/bonfire.go new file mode 100644 index 000000000..9b62b0bd8 --- /dev/null +++ b/vendor/github.com/kurin/blazer/bin/bonfire/bonfire.go @@ -0,0 +1,43 @@ +package main + +import ( + "context" + "fmt" + "net/http" + + "github.com/kurin/blazer/bonfire" + "github.com/kurin/blazer/internal/pyre" +) + +type superManager struct { + *bonfire.LocalBucket + bonfire.FS +} + +func main() { + ctx := context.Background() + mux := http.NewServeMux() + + fs := bonfire.FS("/tmp/b2") + bm := &bonfire.LocalBucket{Port: 8822} + + if err := pyre.RegisterServerOnMux(ctx, &pyre.Server{ + Account: bonfire.Localhost(8822), + LargeFile: fs, + Bucket: bm, + }, mux); err != nil { + fmt.Println(err) + return + } + + sm := superManager{ + LocalBucket: bm, + FS: fs, + } + + pyre.RegisterLargeFileManagerOnMux(fs, mux) + pyre.RegisterSimpleFileManagerOnMux(fs, mux) + pyre.RegisterDownloadManagerOnMux(sm, mux) + fmt.Println("ok") + fmt.Println(http.ListenAndServe("localhost:8822", mux)) +} diff --git a/vendor/github.com/kurin/blazer/bonfire/bonfire.go b/vendor/github.com/kurin/blazer/bonfire/bonfire.go new file mode 100644 index 000000000..4a1a09015 --- /dev/null +++ b/vendor/github.com/kurin/blazer/bonfire/bonfire.go @@ -0,0 +1,257 @@ +// Copyright 2018, Google +// +// 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 bonfire implements the B2 service. +package bonfire + +import ( + "crypto/sha1" + "encoding/json" + "errors" + "fmt" + "io" + "os" + "path/filepath" + "sort" + "strconv" + "sync" + + "github.com/kurin/blazer/internal/pyre" +) + +type FS string + +func (f FS) open(fp string) (io.WriteCloser, error) { + if err := os.MkdirAll(filepath.Dir(fp), 0755); err != nil { + return nil, err + } + return os.Create(fp) +} + +func (f FS) PartWriter(id string, part int) (io.WriteCloser, error) { + fp := filepath.Join(string(f), id, fmt.Sprintf("%d", part)) + return f.open(fp) +} + +func (f FS) Writer(bucket, name, id string) (io.WriteCloser, error) { + fp := filepath.Join(string(f), bucket, name, id) + return f.open(fp) +} + +func (f FS) Parts(id string) ([]string, error) { + dir := filepath.Join(string(f), id) + file, err := os.Open(dir) + if err != nil { + return nil, err + } + defer file.Close() + fs, err := file.Readdir(0) + if err != nil { + return nil, err + } + shas := make([]string, len(fs)-1) + for _, fi := range fs { + if fi.Name() == "info" { + continue + } + i, err := strconv.ParseInt(fi.Name(), 10, 32) + if err != nil { + return nil, err + } + p, err := os.Open(filepath.Join(dir, fi.Name())) + if err != nil { + return nil, err + } + sha := sha1.New() + if _, err := io.Copy(sha, p); err != nil { + p.Close() + return nil, err + } + p.Close() + shas[int(i)-1] = fmt.Sprintf("%x", sha.Sum(nil)) + } + return shas, nil +} + +type fi struct { + Name string + Bucket string +} + +func (f FS) Start(bucketId, fileName, fileId string, bs []byte) error { + w, err := f.open(filepath.Join(string(f), fileId, "info")) + if err != nil { + return err + } + if err := json.NewEncoder(w).Encode(fi{Name: fileName, Bucket: bucketId}); err != nil { + w.Close() + return err + } + return w.Close() +} + +func (f FS) Finish(fileId string) error { + r, err := os.Open(filepath.Join(string(f), fileId, "info")) + if err != nil { + return err + } + defer r.Close() + var info fi + if err := json.NewDecoder(r).Decode(&info); err != nil { + return err + } + shas, err := f.Parts(fileId) // oh my god this is terrible + if err != nil { + return err + } + w, err := f.open(filepath.Join(string(f), info.Bucket, info.Name, fileId)) + if err != nil { + return err + } + for i := 1; i <= len(shas); i++ { + r, err := os.Open(filepath.Join(string(f), fileId, fmt.Sprintf("%d", i))) + if err != nil { + w.Close() + return err + } + if _, err := io.Copy(w, r); err != nil { + w.Close() + r.Close() + return err + } + r.Close() + } + if err := w.Close(); err != nil { + return err + } + return os.RemoveAll(filepath.Join(string(f), fileId)) +} + +func (f FS) ObjectByName(bucket, name string) (pyre.DownloadableObject, error) { + dir := filepath.Join(string(f), bucket, name) + d, err := os.Open(dir) + if err != nil { + return nil, err + } + defer d.Close() + fis, err := d.Readdir(0) + if err != nil { + return nil, err + } + sort.Slice(fis, func(i, j int) bool { return fis[i].ModTime().Before(fis[j].ModTime()) }) + o, err := os.Open(filepath.Join(dir, fis[0].Name())) + if err != nil { + return nil, err + } + return do{ + o: o, + size: fis[0].Size(), + }, nil +} + +type do struct { + size int64 + o *os.File +} + +func (d do) Size() int64 { return d.size } +func (d do) Reader() io.ReaderAt { return d.o } +func (d do) Close() error { return d.o.Close() } + +func (f FS) Get(fileId string) ([]byte, error) { return nil, nil } + +type Localhost int + +func (l Localhost) String() string { return fmt.Sprintf("http://localhost:%d", l) } +func (l Localhost) UploadHost(id string) (string, error) { return l.String(), nil } +func (Localhost) Authorize(string, string) (string, error) { return "ok", nil } +func (Localhost) CheckCreds(string, string) error { return nil } +func (l Localhost) APIRoot(string) string { return l.String() } +func (l Localhost) DownloadRoot(string) string { return l.String() } +func (Localhost) Sizes(string) (int32, int32) { return 1e5, 1 } +func (l Localhost) UploadPartHost(fileId string) (string, error) { return l.String(), nil } + +type LocalBucket struct { + Port int + + mux sync.Mutex + b map[string][]byte + nti map[string]string +} + +func (lb *LocalBucket) AddBucket(id, name string, bs []byte) error { + lb.mux.Lock() + defer lb.mux.Unlock() + + if lb.b == nil { + lb.b = make(map[string][]byte) + } + + if lb.nti == nil { + lb.nti = make(map[string]string) + } + + lb.b[id] = bs + lb.nti[name] = id + return nil +} + +func (lb *LocalBucket) RemoveBucket(id string) error { + lb.mux.Lock() + defer lb.mux.Unlock() + + if lb.b == nil { + lb.b = make(map[string][]byte) + } + + delete(lb.b, id) + return nil +} + +func (lb *LocalBucket) UpdateBucket(id string, rev int, bs []byte) error { + return errors.New("no") +} + +func (lb *LocalBucket) ListBuckets(acct string) ([][]byte, error) { + lb.mux.Lock() + defer lb.mux.Unlock() + + var bss [][]byte + for _, bs := range lb.b { + bss = append(bss, bs) + } + return bss, nil +} + +func (lb *LocalBucket) GetBucket(id string) ([]byte, error) { + lb.mux.Lock() + defer lb.mux.Unlock() + + bs, ok := lb.b[id] + if !ok { + return nil, errors.New("not found") + } + return bs, nil +} + +func (lb *LocalBucket) GetBucketID(name string) (string, error) { + lb.mux.Lock() + defer lb.mux.Unlock() + + id, ok := lb.nti[name] + if !ok { + return "", errors.New("not found") + } + return id, nil +} diff --git a/vendor/github.com/kurin/blazer/internal/b2types/b2types.go b/vendor/github.com/kurin/blazer/internal/b2types/b2types.go index 4730110b3..3523e4148 100644 --- a/vendor/github.com/kurin/blazer/internal/b2types/b2types.go +++ b/vendor/github.com/kurin/blazer/internal/b2types/b2types.go @@ -29,11 +29,14 @@ type ErrorMessage struct { } type AuthorizeAccountResponse struct { - AccountID string `json:"accountId"` - AuthToken string `json:"authorizationToken"` - URI string `json:"apiUrl"` - DownloadURI string `json:"downloadUrl"` - MinPartSize int `json:"minimumPartSize"` + AccountID string `json:"accountId"` + AuthToken string `json:"authorizationToken"` + URI string `json:"apiUrl"` + DownloadURI string `json:"downloadUrl"` + MinPartSize int `json:"minimumPartSize"` + PartSize int `json:"recommendedPartSize"` + AbsMinPartSize int `json:"absoluteMinimumPartSize"` + Capabilities []string `json:"capabilities"` } type LifecycleRule struct { @@ -73,15 +76,8 @@ type ListBucketsResponse struct { } type UpdateBucketRequest struct { - AccountID string `json:"accountId"` - BucketID string `json:"bucketId"` - // bucketName is a required field according to - // https://www.backblaze.com/b2/docs/b2_update_bucket.html. - // - // However, actually setting it returns 400: unknown field in - // com.backblaze.modules.b2.data.UpdateBucketRequest: bucketName - // - //Name string `json:"bucketName"` + AccountID string `json:"accountId"` + BucketID string `json:"bucketId"` Type string `json:"bucketType,omitempty"` Info map[string]string `json:"bucketInfo,omitempty"` LifecycleRules []LifecycleRule `json:"lifecycleRules,omitempty"` @@ -99,11 +95,7 @@ type GetUploadURLResponse struct { Token string `json:"authorizationToken"` } -type UploadFileResponse struct { - FileID string `json:"fileId"` - Timestamp int64 `json:"uploadTimestamp"` - Action string `json:"action"` -} +type UploadFileResponse GetFileInfoResponse type DeleteFileVersionRequest struct { Name string `json:"fileName"` @@ -206,20 +198,23 @@ type GetFileInfoRequest struct { } type GetFileInfoResponse struct { - FileID string `json:"fileId"` - Name string `json:"fileName"` - SHA1 string `json:"contentSha1"` - Size int64 `json:"contentLength"` - ContentType string `json:"contentType"` - Info map[string]string `json:"fileInfo"` - Action string `json:"action"` - Timestamp int64 `json:"uploadTimestamp"` + FileID string `json:"fileId,omitempty"` + Name string `json:"fileName,omitempty"` + AccountID string `json:"accountId,omitempty"` + BucketID string `json:"bucketId,omitempty"` + Size int64 `json:"contentLength,omitempty"` + SHA1 string `json:"contentSha1,omitempty"` + ContentType string `json:"contentType,omitempty"` + Info map[string]string `json:"fileInfo,omitempty"` + Action string `json:"action,omitempty"` + Timestamp int64 `json:"uploadTimestamp,omitempty"` } type GetDownloadAuthorizationRequest struct { - BucketID string `json:"bucketId"` - Prefix string `json:"fileNamePrefix"` - Valid int `json:"validDurationInSeconds"` + BucketID string `json:"bucketId"` + Prefix string `json:"fileNamePrefix"` + Valid int `json:"validDurationInSeconds"` + ContentDisposition string `json:"b2ContentDisposition,omitempty"` } type GetDownloadAuthorizationResponse struct { @@ -238,3 +233,42 @@ type ListUnfinishedLargeFilesResponse struct { Files []GetFileInfoResponse `json:"files"` Continuation string `json:"nextFileId"` } + +type CreateKeyRequest struct { + AccountID string `json:"accountId"` + Capabilities []string `json:"capabilities"` + Name string `json:"keyName"` + Valid int `json:"validDurationInSeconds,omitempty"` + BucketID string `json:"bucketId,omitempty"` + Prefix string `json:"namePrefix,omitempty"` +} + +type Key struct { + ID string `json:"applicationKeyId"` + Secret string `json:"applicationKey"` + AccountID string `json:"accountId"` + Capabilities []string `json:"capabilities"` + Name string `json:"keyName"` + Expires int64 `json:"expirationTimestamp"` + BucketID string `json:"bucketId"` + Prefix string `json:"namePrefix"` +} + +type CreateKeyResponse Key + +type DeleteKeyRequest struct { + KeyID string `json:"applicationKeyId"` +} + +type DeleteKeyResponse Key + +type ListKeysRequest struct { + AccountID string `json:"accountId"` + Max int `json:"maxKeyCount,omitempty"` + Next string `json:"startApplicationKeyId,omitempty"` +} + +type ListKeysResponse struct { + Keys []Key `json:"keys"` + Next string `json:"nextApplicationKeyId"` +} diff --git a/vendor/github.com/kurin/blazer/internal/pyre/api.go b/vendor/github.com/kurin/blazer/internal/pyre/api.go new file mode 100644 index 000000000..ba17c0c38 --- /dev/null +++ b/vendor/github.com/kurin/blazer/internal/pyre/api.go @@ -0,0 +1,325 @@ +// Copyright 2018, Google +// +// 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 pyre + +import ( + "context" + "encoding/base64" + "errors" + "fmt" + "net" + "net/http" + "os" + "reflect" + "strings" + + "github.com/golang/protobuf/proto" + "github.com/google/uuid" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" + + pb "github.com/kurin/blazer/internal/pyre/proto" +) + +type apiErr struct { + Status int `json:"status"` + Code string `json:"code"` + Message string `json:"message"` +} + +func serveMuxOptions() []runtime.ServeMuxOption { + return []runtime.ServeMuxOption{ + runtime.WithMarshalerOption("*", &runtime.JSONPb{}), + runtime.WithProtoErrorHandler(func(ctx context.Context, mux *runtime.ServeMux, m runtime.Marshaler, rw http.ResponseWriter, req *http.Request, err error) { + aErr := apiErr{ + Status: 400, + Code: "uh oh", + Message: err.Error(), + } + rw.WriteHeader(aErr.Status) + if err := m.NewEncoder(rw).Encode(aErr); err != nil { + fmt.Fprintln(os.Stdout, err) + } + }), + } +} + +func getAuth(ctx context.Context) (string, error) { + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return "", errors.New("no metadata") + } + data := md.Get("authorization") + if len(data) == 0 { + return "", nil + } + return data[0], nil +} + +func RegisterServerOnMux(ctx context.Context, srv *Server, mux *http.ServeMux) error { + rmux := runtime.NewServeMux(serveMuxOptions()...) + l, err := net.Listen("tcp", "localhost:0") + if err != nil { + return err + } + gsrv := grpc.NewServer() + if err := pb.RegisterPyreServiceHandlerFromEndpoint(ctx, rmux, l.Addr().String(), []grpc.DialOption{grpc.WithInsecure()}); err != nil { + return err + } + pb.RegisterPyreServiceServer(gsrv, srv) + mux.Handle("/b2api/v1/", rmux) + go gsrv.Serve(l) + go func() { + <-ctx.Done() + gsrv.GracefulStop() + }() + return nil +} + +type AccountManager interface { + Authorize(acct, key string) (string, error) + CheckCreds(token, api string) error + APIRoot(acct string) string + DownloadRoot(acct string) string + UploadPartHost(fileID string) (string, error) + UploadHost(id string) (string, error) + Sizes(acct string) (recommended, minimum int32) +} + +type BucketManager interface { + AddBucket(id, name string, bs []byte) error + RemoveBucket(id string) error + UpdateBucket(id string, rev int, bs []byte) error + ListBuckets(acct string) ([][]byte, error) + GetBucket(id string) ([]byte, error) +} + +type LargeFileOrganizer interface { + Start(bucketID, fileName, fileID string, bs []byte) error + Get(fileID string) ([]byte, error) + Parts(fileID string) ([]string, error) + Finish(fileID string) error +} + +type Server struct { + Account AccountManager + Bucket BucketManager + LargeFile LargeFileOrganizer + List ListManager +} + +func (s *Server) AuthorizeAccount(ctx context.Context, req *pb.AuthorizeAccountRequest) (*pb.AuthorizeAccountResponse, error) { + auth, err := getAuth(ctx) + if err != nil { + return nil, err + } + if !strings.HasPrefix(auth, "Basic ") { + return nil, errors.New("basic auth required") + } + auth = strings.TrimPrefix(auth, "Basic ") + bs, err := base64.StdEncoding.DecodeString(auth) + if err != nil { + return nil, err + } + split := strings.Split(string(bs), ":") + if len(split) != 2 { + return nil, errors.New("bad auth") + } + acct, key := split[0], split[1] + token, err := s.Account.Authorize(acct, key) + if err != nil { + return nil, err + } + rec, min := s.Account.Sizes(acct) + return &pb.AuthorizeAccountResponse{ + AuthorizationToken: token, + ApiUrl: s.Account.APIRoot(acct), + DownloadUrl: s.Account.DownloadRoot(acct), + RecommendedPartSize: rec, + MinimumPartSize: rec, + AbsoluteMinimumPartSize: min, + }, nil +} + +func (s *Server) ListBuckets(ctx context.Context, req *pb.ListBucketsRequest) (*pb.ListBucketsResponse, error) { + resp := &pb.ListBucketsResponse{} + buckets, err := s.Bucket.ListBuckets(req.AccountId) + if err != nil { + return nil, err + } + for _, bs := range buckets { + var bucket pb.Bucket + if err := proto.Unmarshal(bs, &bucket); err != nil { + return nil, err + } + resp.Buckets = append(resp.Buckets, &bucket) + } + return resp, nil +} + +func (s *Server) CreateBucket(ctx context.Context, req *pb.Bucket) (*pb.Bucket, error) { + req.BucketId = uuid.New().String() + bs, err := proto.Marshal(req) + if err != nil { + return nil, err + } + if err := s.Bucket.AddBucket(req.BucketId, req.BucketName, bs); err != nil { + return nil, err + } + return req, nil +} + +func (s *Server) DeleteBucket(ctx context.Context, req *pb.Bucket) (*pb.Bucket, error) { + bs, err := s.Bucket.GetBucket(req.BucketId) + if err != nil { + return nil, err + } + var bucket pb.Bucket + if err := proto.Unmarshal(bs, &bucket); err != nil { + return nil, err + } + if err := s.Bucket.RemoveBucket(req.BucketId); err != nil { + return nil, err + } + return &bucket, nil +} + +func (s *Server) GetUploadUrl(ctx context.Context, req *pb.GetUploadUrlRequest) (*pb.GetUploadUrlResponse, error) { + host, err := s.Account.UploadHost(req.BucketId) + if err != nil { + return nil, err + } + return &pb.GetUploadUrlResponse{ + UploadUrl: fmt.Sprintf("%s/b2api/v1/b2_upload_file/%s", host, req.BucketId), + BucketId: req.BucketId, + }, nil +} + +func (s *Server) StartLargeFile(ctx context.Context, req *pb.StartLargeFileRequest) (*pb.StartLargeFileResponse, error) { + fileID := uuid.New().String() + resp := &pb.StartLargeFileResponse{ + FileId: fileID, + FileName: req.FileName, + BucketId: req.BucketId, + ContentType: req.ContentType, + FileInfo: req.FileInfo, + } + bs, err := proto.Marshal(resp) + if err != nil { + return nil, err + } + if err := s.LargeFile.Start(req.BucketId, req.FileName, fileID, bs); err != nil { + return nil, err + } + return resp, nil +} + +func (s *Server) GetUploadPartUrl(ctx context.Context, req *pb.GetUploadPartUrlRequest) (*pb.GetUploadPartUrlResponse, error) { + host, err := s.Account.UploadPartHost(req.FileId) + if err != nil { + return nil, err + } + return &pb.GetUploadPartUrlResponse{ + UploadUrl: fmt.Sprintf("%s/b2api/v1/b2_upload_part/%s", host, req.FileId), + }, nil +} + +func (s *Server) FinishLargeFile(ctx context.Context, req *pb.FinishLargeFileRequest) (*pb.FinishLargeFileResponse, error) { + parts, err := s.LargeFile.Parts(req.FileId) + if err != nil { + return nil, err + } + if !reflect.DeepEqual(parts, req.PartSha1Array) { + return nil, errors.New("sha1 array mismatch") + } + if err := s.LargeFile.Finish(req.FileId); err != nil { + return nil, err + } + return &pb.FinishLargeFileResponse{}, nil +} + +func (s *Server) ListFileVersions(ctx context.Context, req *pb.ListFileVersionsRequest) (*pb.ListFileVersionsResponse, error) { + return nil, nil +} + +//type objTuple struct { +// name, version string +//} + +type ListManager interface { + // NextN returns the next n objects, sorted by lexicographical order by name, + // beginning at and including, if it exists, fileName. If withPrefix is not + // empty, it only returns names that begin with that prefix. If skipPrefix + // is not empty, then the no files with that prefix are returned. If the two + // conflict, skipPrefix wins (i.e., do not return the entry). + // + // If fewer than n entries are returned, this signifies that no more names + // exist that meet these criteria. + NextN(bucketID, fileName, withPrefix, skipPrefix string, n int) ([]VersionedObject, error) +} + +type VersionedObject interface { + Name() string + NextNVersions(begin string, n int) ([]string, error) +} + +//func getNextObjects(lm ListManager, bucket, name, prefix, delimiter string, n int) ([]VersionedObject, error) { +// if delimiter == "" { +// return lm.NextN(bucket, name, prefix, "", n) +// } +// afterPfx := strings.TrimPrefix(name, prefix) +// i := strings.Index(afterPfx, delimiter) +// if i == 0 { +// +// } +// if i < 0 { +// return lm.NextN(bucket, name, prefix, "", n) +// } +// skipPfx := name[:len(prefix)+i] +// // TO +//} +// +//func listFileVersions(lm ListManager, bucket, name, version, prefix, delimiter string, n int) ([]objTuple, error) { +// var tups []objTuple +// var got int +// for { +// objs, err := getNextObjects(bucket, name, prefix, delimiter, n-got) +// if err != nil { +// return nil, err +// } +// if len(objs) == 0 { +// break +// } +// for _, o := range objs { +// var begin string +// if len(tups) == 0 { +// begin = version +// } +// vers, err := lm.NextNVersions(begin, n-got) +// if err != nil { +// return nil, err +// } +// got += len(vers) +// for _, ver := range vers { +// tups = append(tups, objTuple{name: o.Name(), version: ver}) +// } +// if got >= n { +// return tups[:n], nil +// } +// } +// } +// return tups, nil +//} diff --git a/vendor/github.com/kurin/blazer/internal/pyre/download.go b/vendor/github.com/kurin/blazer/internal/pyre/download.go new file mode 100644 index 000000000..334d55c94 --- /dev/null +++ b/vendor/github.com/kurin/blazer/internal/pyre/download.go @@ -0,0 +1,136 @@ +// Copyright 2018, Google +// +// 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 pyre + +import ( + "fmt" + "io" + "net/http" + "strconv" + "strings" +) + +type DownloadableObject interface { + Size() int64 + Reader() io.ReaderAt + io.Closer +} + +type DownloadManager interface { + ObjectByName(bucketID, name string) (DownloadableObject, error) + GetBucketID(bucket string) (string, error) + GetBucket(id string) ([]byte, error) +} + +type downloadServer struct { + dm DownloadManager +} + +type downloadRequest struct { + off, n int64 +} + +func parseDownloadHeaders(r *http.Request) (*downloadRequest, error) { + rang := r.Header.Get("Range") + if rang == "" { + return &downloadRequest{}, nil + } + if !strings.HasPrefix(rang, "bytes=") { + return nil, fmt.Errorf("unknown range format: %q", rang) + } + rang = strings.TrimPrefix(rang, "bytes=") + if !strings.Contains(rang, "-") { + return nil, fmt.Errorf("unknown range format: %q", rang) + } + parts := strings.Split(rang, "-") + off, err := strconv.ParseInt(parts[0], 10, 64) + if err != nil { + return nil, err + } + end, err := strconv.ParseInt(parts[1], 10, 64) + if err != nil { + return nil, err + } + return &downloadRequest{ + off: off, + n: (end + 1) - off, + }, nil +} + +func (fs *downloadServer) serveWholeObject(rw http.ResponseWriter, obj DownloadableObject) { + rw.Header().Set("Content-Length", fmt.Sprintf("%d", obj.Size())) + sr := io.NewSectionReader(obj.Reader(), 0, obj.Size()) + if _, err := io.Copy(rw, sr); err != nil { + http.Error(rw, err.Error(), 503) + fmt.Println("no reader", err) + } +} + +func (fs *downloadServer) servePartialObject(rw http.ResponseWriter, obj DownloadableObject, off, len int64) { + if off >= obj.Size() { + http.Error(rw, "hell naw", 416) + fmt.Printf("range not good (%d-%d for %d)\n", off, len, obj.Size()) + return + } + if off+len > obj.Size() { + len = obj.Size() - off + } + sr := io.NewSectionReader(obj.Reader(), off, len) + rw.Header().Set("Content-Length", fmt.Sprintf("%d", len)) + rw.WriteHeader(206) // this goes after headers are set + if _, err := io.Copy(rw, sr); err != nil { + fmt.Println("bad read:", err) + } +} + +func (fs *downloadServer) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + req, err := parseDownloadHeaders(r) + if err != nil { + http.Error(rw, err.Error(), 503) + fmt.Println("weird header") + return + } + path := strings.TrimPrefix(r.URL.Path, "/") + parts := strings.Split(path, "/") + if len(parts) < 3 { + http.Error(rw, err.Error(), 404) + fmt.Println("weird file") + return + } + bucket := parts[1] + bid, err := fs.dm.GetBucketID(bucket) + if err != nil { + http.Error(rw, err.Error(), 503) + fmt.Println("no bucket:", err) + return + } + file := strings.Join(parts[2:], "/") + obj, err := fs.dm.ObjectByName(bid, file) + if err != nil { + http.Error(rw, err.Error(), 503) + fmt.Println("no reader", err) + return + } + defer obj.Close() + if req.off == 0 && req.n == 0 { + fs.serveWholeObject(rw, obj) + return + } + fs.servePartialObject(rw, obj, req.off, req.n) +} + +func RegisterDownloadManagerOnMux(d DownloadManager, mux *http.ServeMux) { + mux.Handle("/file/", &downloadServer{dm: d}) +} diff --git a/vendor/github.com/kurin/blazer/internal/pyre/large.go b/vendor/github.com/kurin/blazer/internal/pyre/large.go new file mode 100644 index 000000000..d642a633e --- /dev/null +++ b/vendor/github.com/kurin/blazer/internal/pyre/large.go @@ -0,0 +1,91 @@ +// Copyright 2018, Google +// +// 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 pyre + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "strconv" + "strings" +) + +const uploadFilePartPrefix = "/b2api/v1/b2_upload_part/" + +type LargeFileManager interface { + PartWriter(id string, part int) (io.WriteCloser, error) +} + +type largeFileServer struct { + fm LargeFileManager +} + +type uploadPartRequest struct { + ID string `json:"fileId"` + Part int `json:"partNumber"` + Size int64 `json:"contentLength"` + Hash string `json:"contentSha1"` +} + +func parseUploadPartHeaders(r *http.Request) (uploadPartRequest, error) { + var ur uploadPartRequest + ur.Hash = r.Header.Get("X-Bz-Content-Sha1") + part, err := strconv.ParseInt(r.Header.Get("X-Bz-Part-Number"), 10, 64) + if err != nil { + return ur, err + } + ur.Part = int(part) + size, err := strconv.ParseInt(r.Header.Get("Content-Length"), 10, 64) + if err != nil { + return ur, err + } + ur.Size = size + ur.ID = strings.TrimPrefix(r.URL.Path, uploadFilePartPrefix) + return ur, nil +} + +func (fs *largeFileServer) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + req, err := parseUploadPartHeaders(r) + if err != nil { + http.Error(rw, err.Error(), 500) + fmt.Println("oh no") + return + } + w, err := fs.fm.PartWriter(req.ID, req.Part) + if err != nil { + http.Error(rw, err.Error(), 500) + fmt.Println("oh no") + return + } + if _, err := io.Copy(w, io.LimitReader(r.Body, req.Size)); err != nil { + w.Close() + http.Error(rw, err.Error(), 500) + fmt.Println("oh no") + return + } + if err := w.Close(); err != nil { + http.Error(rw, err.Error(), 500) + fmt.Println("oh no") + return + } + if err := json.NewEncoder(rw).Encode(req); err != nil { + fmt.Println("oh no") + } +} + +func RegisterLargeFileManagerOnMux(f LargeFileManager, mux *http.ServeMux) { + mux.Handle(uploadFilePartPrefix, &largeFileServer{fm: f}) +} diff --git a/vendor/github.com/kurin/blazer/internal/pyre/proto/pyre.pb.go b/vendor/github.com/kurin/blazer/internal/pyre/proto/pyre.pb.go new file mode 100644 index 000000000..29a906eb9 --- /dev/null +++ b/vendor/github.com/kurin/blazer/internal/pyre/proto/pyre.pb.go @@ -0,0 +1,1896 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: proto/pyre.proto + +package pyre_proto + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "google.golang.org/genproto/googleapis/api/annotations" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type AuthorizeAccountRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AuthorizeAccountRequest) Reset() { *m = AuthorizeAccountRequest{} } +func (m *AuthorizeAccountRequest) String() string { return proto.CompactTextString(m) } +func (*AuthorizeAccountRequest) ProtoMessage() {} +func (*AuthorizeAccountRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{0} +} +func (m *AuthorizeAccountRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AuthorizeAccountRequest.Unmarshal(m, b) +} +func (m *AuthorizeAccountRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AuthorizeAccountRequest.Marshal(b, m, deterministic) +} +func (dst *AuthorizeAccountRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_AuthorizeAccountRequest.Merge(dst, src) +} +func (m *AuthorizeAccountRequest) XXX_Size() int { + return xxx_messageInfo_AuthorizeAccountRequest.Size(m) +} +func (m *AuthorizeAccountRequest) XXX_DiscardUnknown() { + xxx_messageInfo_AuthorizeAccountRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_AuthorizeAccountRequest proto.InternalMessageInfo + +type AuthorizeAccountResponse struct { + // The identifier for the account. + AccountId string `protobuf:"bytes,1,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` + // An authorization token to use with all calls, other than + // b2_authorize_account, that need an Authorization header. This + // authorization token is valid for at most 24 hours. + AuthorizationToken string `protobuf:"bytes,2,opt,name=authorization_token,json=authorizationToken,proto3" json:"authorization_token,omitempty"` + // The base URL to use for all API calls except for uploading and downloading + // files. + ApiUrl string `protobuf:"bytes,3,opt,name=api_url,json=apiUrl,proto3" json:"api_url,omitempty"` + // The base URL to use for downloading files. + DownloadUrl string `protobuf:"bytes,4,opt,name=download_url,json=downloadUrl,proto3" json:"download_url,omitempty"` + // The recommended size for each part of a large file. We recommend using + // this part size for optimal upload performance. + RecommendedPartSize int32 `protobuf:"varint,5,opt,name=recommended_part_size,json=recommendedPartSize,proto3" json:"recommended_part_size,omitempty"` + // The smallest possible size of a part of a large file (except the last + // one). This is smaller than the recommended part size. If you use it, you + // may find that it takes longer overall to upload a large file. + AbsoluteMinimumPartSize int32 `protobuf:"varint,6,opt,name=absolute_minimum_part_size,json=absoluteMinimumPartSize,proto3" json:"absolute_minimum_part_size,omitempty"` + MinimumPartSize int32 `protobuf:"varint,7,opt,name=minimum_part_size,json=minimumPartSize,proto3" json:"minimum_part_size,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AuthorizeAccountResponse) Reset() { *m = AuthorizeAccountResponse{} } +func (m *AuthorizeAccountResponse) String() string { return proto.CompactTextString(m) } +func (*AuthorizeAccountResponse) ProtoMessage() {} +func (*AuthorizeAccountResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{1} +} +func (m *AuthorizeAccountResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AuthorizeAccountResponse.Unmarshal(m, b) +} +func (m *AuthorizeAccountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AuthorizeAccountResponse.Marshal(b, m, deterministic) +} +func (dst *AuthorizeAccountResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_AuthorizeAccountResponse.Merge(dst, src) +} +func (m *AuthorizeAccountResponse) XXX_Size() int { + return xxx_messageInfo_AuthorizeAccountResponse.Size(m) +} +func (m *AuthorizeAccountResponse) XXX_DiscardUnknown() { + xxx_messageInfo_AuthorizeAccountResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_AuthorizeAccountResponse proto.InternalMessageInfo + +func (m *AuthorizeAccountResponse) GetAccountId() string { + if m != nil { + return m.AccountId + } + return "" +} + +func (m *AuthorizeAccountResponse) GetAuthorizationToken() string { + if m != nil { + return m.AuthorizationToken + } + return "" +} + +func (m *AuthorizeAccountResponse) GetApiUrl() string { + if m != nil { + return m.ApiUrl + } + return "" +} + +func (m *AuthorizeAccountResponse) GetDownloadUrl() string { + if m != nil { + return m.DownloadUrl + } + return "" +} + +func (m *AuthorizeAccountResponse) GetRecommendedPartSize() int32 { + if m != nil { + return m.RecommendedPartSize + } + return 0 +} + +func (m *AuthorizeAccountResponse) GetAbsoluteMinimumPartSize() int32 { + if m != nil { + return m.AbsoluteMinimumPartSize + } + return 0 +} + +func (m *AuthorizeAccountResponse) GetMinimumPartSize() int32 { + if m != nil { + return m.MinimumPartSize + } + return 0 +} + +type ListBucketsRequest struct { + // The ID of your account. + AccountId string `protobuf:"bytes,1,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` + // When specified, the result will be a list containing just this bucket, if + // it's present in the account, or no buckets if the account does not have a + // bucket with this ID. + BucketId string `protobuf:"bytes,2,opt,name=bucket_id,json=bucketId,proto3" json:"bucket_id,omitempty"` + // When specified, the result will be a list containing just this bucket, if + // it's present in the account, or no buckets if the account does not have a + // bucket with this ID. + BucketName string `protobuf:"bytes,3,opt,name=bucket_name,json=bucketName,proto3" json:"bucket_name,omitempty"` + // If present, B2 will use it as a filter for bucket types returned in the + // list buckets response. If not present, only buckets with bucket types + // "allPublic", "allPrivate" and "snapshot" will be returned. A special + // filter value of ["all"] will return all bucket types. + // + // If present, it must be in the form of a json array of strings containing + // valid bucket types in quotes and separated by a comma. Valid bucket types + // include "allPrivate", "allPublic", "snapshot", and other values added in + // the future. + // + // A bad request error will be returned if "all" is used with other bucket + // types, this field is empty, or invalid bucket types are requested. + BucketTypes []string `protobuf:"bytes,4,rep,name=bucket_types,json=bucketTypes,proto3" json:"bucket_types,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListBucketsRequest) Reset() { *m = ListBucketsRequest{} } +func (m *ListBucketsRequest) String() string { return proto.CompactTextString(m) } +func (*ListBucketsRequest) ProtoMessage() {} +func (*ListBucketsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{2} +} +func (m *ListBucketsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ListBucketsRequest.Unmarshal(m, b) +} +func (m *ListBucketsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ListBucketsRequest.Marshal(b, m, deterministic) +} +func (dst *ListBucketsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListBucketsRequest.Merge(dst, src) +} +func (m *ListBucketsRequest) XXX_Size() int { + return xxx_messageInfo_ListBucketsRequest.Size(m) +} +func (m *ListBucketsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ListBucketsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ListBucketsRequest proto.InternalMessageInfo + +func (m *ListBucketsRequest) GetAccountId() string { + if m != nil { + return m.AccountId + } + return "" +} + +func (m *ListBucketsRequest) GetBucketId() string { + if m != nil { + return m.BucketId + } + return "" +} + +func (m *ListBucketsRequest) GetBucketName() string { + if m != nil { + return m.BucketName + } + return "" +} + +func (m *ListBucketsRequest) GetBucketTypes() []string { + if m != nil { + return m.BucketTypes + } + return nil +} + +type LifecycleRule struct { + // After a file is uploaded, the number of days before it can be hidden. + DaysFromUploadingToHiding int32 `protobuf:"varint,1,opt,name=days_from_uploading_to_hiding,json=daysFromUploadingToHiding,proto3" json:"days_from_uploading_to_hiding,omitempty"` + // After a file is hidden, the number of days before it can be deleted. + DaysFromHidingToDeleting int32 `protobuf:"varint,2,opt,name=days_from_hiding_to_deleting,json=daysFromHidingToDeleting,proto3" json:"days_from_hiding_to_deleting,omitempty"` + // The rule applies to files whose names start with this prefix. + FileNamePrefix string `protobuf:"bytes,3,opt,name=file_name_prefix,json=fileNamePrefix,proto3" json:"file_name_prefix,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LifecycleRule) Reset() { *m = LifecycleRule{} } +func (m *LifecycleRule) String() string { return proto.CompactTextString(m) } +func (*LifecycleRule) ProtoMessage() {} +func (*LifecycleRule) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{3} +} +func (m *LifecycleRule) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LifecycleRule.Unmarshal(m, b) +} +func (m *LifecycleRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LifecycleRule.Marshal(b, m, deterministic) +} +func (dst *LifecycleRule) XXX_Merge(src proto.Message) { + xxx_messageInfo_LifecycleRule.Merge(dst, src) +} +func (m *LifecycleRule) XXX_Size() int { + return xxx_messageInfo_LifecycleRule.Size(m) +} +func (m *LifecycleRule) XXX_DiscardUnknown() { + xxx_messageInfo_LifecycleRule.DiscardUnknown(m) +} + +var xxx_messageInfo_LifecycleRule proto.InternalMessageInfo + +func (m *LifecycleRule) GetDaysFromUploadingToHiding() int32 { + if m != nil { + return m.DaysFromUploadingToHiding + } + return 0 +} + +func (m *LifecycleRule) GetDaysFromHidingToDeleting() int32 { + if m != nil { + return m.DaysFromHidingToDeleting + } + return 0 +} + +func (m *LifecycleRule) GetFileNamePrefix() string { + if m != nil { + return m.FileNamePrefix + } + return "" +} + +type CorsRule struct { + // A name for humans to recognize the rule in a user interface. Names must be + // unique within a bucket. Names can consist of upper-case and lower-case + // English letters, numbers, and "-". No other characters are allowed. A name + // must be at least 6 characters long, and can be at most 50 characters long. + // These are all allowed names: myPhotosSite, allowAnyHttps, + // backblaze-images. Names that start with "b2-" are reserved for Backblaze + // use. + CorsRuleName string `protobuf:"bytes,1,opt,name=cors_rule_name,json=corsRuleName,proto3" json:"cors_rule_name,omitempty"` + // A non-empty list specifying which origins the rule covers. Each value may + // have one of many formats: + // + // * The origin can be fully specified, such as http://www.example.com:8180 + // or https://www.example.com:4433. + // + // * The origin can omit a default port, such as https://www.example.com. + // + // * The origin may have a single '*' as part of the domain name, such as + // https://*.example.com, https://*:8443 or https://*. + // + // * The origin may be 'https' to match any origin that uses HTTPS. (This is + // broader than 'https://*' because it matches any port.) + // + // * Finally, the origin can be a single '*' to match any origin. + // + // If any entry is "*", it must be the only entry. There can be at most one + // "https" entry and no entry after it may start with "https:". + AllowedOrigins []string `protobuf:"bytes,2,rep,name=allowed_origins,json=allowedOrigins,proto3" json:"allowed_origins,omitempty"` + // A list specifying which operations the rule allows. At least one value + // must be specified. All values must be from the following list. More values + // may be added to this list at any time. + // + // b2_download_file_by_name + // b2_download_file_by_id + // b2_upload_file + // b2_upload_part + AllowedOperations []string `protobuf:"bytes,3,rep,name=allowed_operations,json=allowedOperations,proto3" json:"allowed_operations,omitempty"` + // If present, this is a list of headers that are allowed in a pre-flight + // OPTIONS's request's Access-Control-Request-Headers header value. Each + // value may have one of many formats: + // + // * It may be a complete header name, such as x-bz-content-sha1. + // + // * It may end with an asterisk, such as x-bz-info-*. + // + // * Finally, it may be a single '*' to match any header. + // + // If any entry is "*", it must be the only entry in the list. If this list + // is missing, it is be treated as if it is a list with no entries. + AllowedHeaders []string `protobuf:"bytes,4,rep,name=allowed_headers,json=allowedHeaders,proto3" json:"allowed_headers,omitempty"` + // If present, this is a list of headers that may be exposed to an + // application inside the client (eg. exposed to Javascript in a browser). + // Each entry in the list must be a complete header name (eg. + // "x-bz-content-sha1"). If this list is missing or empty, no headers will be + // exposed. + ExposeHeaders []string `protobuf:"bytes,5,rep,name=expose_headers,json=exposeHeaders,proto3" json:"expose_headers,omitempty"` + // This specifies the maximum number of seconds that a browser may cache the + // response to a preflight request. The value must not be negative and it + // must not be more than 86,400 seconds (one day). + MaxAgeSeconds int32 `protobuf:"varint,6,opt,name=max_age_seconds,json=maxAgeSeconds,proto3" json:"max_age_seconds,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CorsRule) Reset() { *m = CorsRule{} } +func (m *CorsRule) String() string { return proto.CompactTextString(m) } +func (*CorsRule) ProtoMessage() {} +func (*CorsRule) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{4} +} +func (m *CorsRule) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CorsRule.Unmarshal(m, b) +} +func (m *CorsRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CorsRule.Marshal(b, m, deterministic) +} +func (dst *CorsRule) XXX_Merge(src proto.Message) { + xxx_messageInfo_CorsRule.Merge(dst, src) +} +func (m *CorsRule) XXX_Size() int { + return xxx_messageInfo_CorsRule.Size(m) +} +func (m *CorsRule) XXX_DiscardUnknown() { + xxx_messageInfo_CorsRule.DiscardUnknown(m) +} + +var xxx_messageInfo_CorsRule proto.InternalMessageInfo + +func (m *CorsRule) GetCorsRuleName() string { + if m != nil { + return m.CorsRuleName + } + return "" +} + +func (m *CorsRule) GetAllowedOrigins() []string { + if m != nil { + return m.AllowedOrigins + } + return nil +} + +func (m *CorsRule) GetAllowedOperations() []string { + if m != nil { + return m.AllowedOperations + } + return nil +} + +func (m *CorsRule) GetAllowedHeaders() []string { + if m != nil { + return m.AllowedHeaders + } + return nil +} + +func (m *CorsRule) GetExposeHeaders() []string { + if m != nil { + return m.ExposeHeaders + } + return nil +} + +func (m *CorsRule) GetMaxAgeSeconds() int32 { + if m != nil { + return m.MaxAgeSeconds + } + return 0 +} + +type Bucket struct { + AccountId string `protobuf:"bytes,1,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` + BucketId string `protobuf:"bytes,2,opt,name=bucket_id,json=bucketId,proto3" json:"bucket_id,omitempty"` + BucketName string `protobuf:"bytes,3,opt,name=bucket_name,json=bucketName,proto3" json:"bucket_name,omitempty"` + BucketType string `protobuf:"bytes,4,opt,name=bucket_type,json=bucketType,proto3" json:"bucket_type,omitempty"` + BucketInfo map[string]string `protobuf:"bytes,5,rep,name=bucket_info,json=bucketInfo,proto3" json:"bucket_info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + CoresRules []*CorsRule `protobuf:"bytes,6,rep,name=cores_rules,json=coresRules,proto3" json:"cores_rules,omitempty"` + LifecycleRules []*LifecycleRule `protobuf:"bytes,7,rep,name=lifecycle_rules,json=lifecycleRules,proto3" json:"lifecycle_rules,omitempty"` + Revision int32 `protobuf:"varint,8,opt,name=revision,proto3" json:"revision,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Bucket) Reset() { *m = Bucket{} } +func (m *Bucket) String() string { return proto.CompactTextString(m) } +func (*Bucket) ProtoMessage() {} +func (*Bucket) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{5} +} +func (m *Bucket) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Bucket.Unmarshal(m, b) +} +func (m *Bucket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Bucket.Marshal(b, m, deterministic) +} +func (dst *Bucket) XXX_Merge(src proto.Message) { + xxx_messageInfo_Bucket.Merge(dst, src) +} +func (m *Bucket) XXX_Size() int { + return xxx_messageInfo_Bucket.Size(m) +} +func (m *Bucket) XXX_DiscardUnknown() { + xxx_messageInfo_Bucket.DiscardUnknown(m) +} + +var xxx_messageInfo_Bucket proto.InternalMessageInfo + +func (m *Bucket) GetAccountId() string { + if m != nil { + return m.AccountId + } + return "" +} + +func (m *Bucket) GetBucketId() string { + if m != nil { + return m.BucketId + } + return "" +} + +func (m *Bucket) GetBucketName() string { + if m != nil { + return m.BucketName + } + return "" +} + +func (m *Bucket) GetBucketType() string { + if m != nil { + return m.BucketType + } + return "" +} + +func (m *Bucket) GetBucketInfo() map[string]string { + if m != nil { + return m.BucketInfo + } + return nil +} + +func (m *Bucket) GetCoresRules() []*CorsRule { + if m != nil { + return m.CoresRules + } + return nil +} + +func (m *Bucket) GetLifecycleRules() []*LifecycleRule { + if m != nil { + return m.LifecycleRules + } + return nil +} + +func (m *Bucket) GetRevision() int32 { + if m != nil { + return m.Revision + } + return 0 +} + +type ListBucketsResponse struct { + Buckets []*Bucket `protobuf:"bytes,1,rep,name=buckets,proto3" json:"buckets,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListBucketsResponse) Reset() { *m = ListBucketsResponse{} } +func (m *ListBucketsResponse) String() string { return proto.CompactTextString(m) } +func (*ListBucketsResponse) ProtoMessage() {} +func (*ListBucketsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{6} +} +func (m *ListBucketsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ListBucketsResponse.Unmarshal(m, b) +} +func (m *ListBucketsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ListBucketsResponse.Marshal(b, m, deterministic) +} +func (dst *ListBucketsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListBucketsResponse.Merge(dst, src) +} +func (m *ListBucketsResponse) XXX_Size() int { + return xxx_messageInfo_ListBucketsResponse.Size(m) +} +func (m *ListBucketsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ListBucketsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ListBucketsResponse proto.InternalMessageInfo + +func (m *ListBucketsResponse) GetBuckets() []*Bucket { + if m != nil { + return m.Buckets + } + return nil +} + +type GetUploadUrlRequest struct { + BucketId string `protobuf:"bytes,1,opt,name=bucket_id,json=bucketId,proto3" json:"bucket_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetUploadUrlRequest) Reset() { *m = GetUploadUrlRequest{} } +func (m *GetUploadUrlRequest) String() string { return proto.CompactTextString(m) } +func (*GetUploadUrlRequest) ProtoMessage() {} +func (*GetUploadUrlRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{7} +} +func (m *GetUploadUrlRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetUploadUrlRequest.Unmarshal(m, b) +} +func (m *GetUploadUrlRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetUploadUrlRequest.Marshal(b, m, deterministic) +} +func (dst *GetUploadUrlRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetUploadUrlRequest.Merge(dst, src) +} +func (m *GetUploadUrlRequest) XXX_Size() int { + return xxx_messageInfo_GetUploadUrlRequest.Size(m) +} +func (m *GetUploadUrlRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetUploadUrlRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetUploadUrlRequest proto.InternalMessageInfo + +func (m *GetUploadUrlRequest) GetBucketId() string { + if m != nil { + return m.BucketId + } + return "" +} + +type GetUploadUrlResponse struct { + BucketId string `protobuf:"bytes,1,opt,name=bucket_id,json=bucketId,proto3" json:"bucket_id,omitempty"` + UploadUrl string `protobuf:"bytes,2,opt,name=upload_url,json=uploadUrl,proto3" json:"upload_url,omitempty"` + AuthorizationToken string `protobuf:"bytes,3,opt,name=authorization_token,json=authorizationToken,proto3" json:"authorization_token,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetUploadUrlResponse) Reset() { *m = GetUploadUrlResponse{} } +func (m *GetUploadUrlResponse) String() string { return proto.CompactTextString(m) } +func (*GetUploadUrlResponse) ProtoMessage() {} +func (*GetUploadUrlResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{8} +} +func (m *GetUploadUrlResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetUploadUrlResponse.Unmarshal(m, b) +} +func (m *GetUploadUrlResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetUploadUrlResponse.Marshal(b, m, deterministic) +} +func (dst *GetUploadUrlResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetUploadUrlResponse.Merge(dst, src) +} +func (m *GetUploadUrlResponse) XXX_Size() int { + return xxx_messageInfo_GetUploadUrlResponse.Size(m) +} +func (m *GetUploadUrlResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetUploadUrlResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetUploadUrlResponse proto.InternalMessageInfo + +func (m *GetUploadUrlResponse) GetBucketId() string { + if m != nil { + return m.BucketId + } + return "" +} + +func (m *GetUploadUrlResponse) GetUploadUrl() string { + if m != nil { + return m.UploadUrl + } + return "" +} + +func (m *GetUploadUrlResponse) GetAuthorizationToken() string { + if m != nil { + return m.AuthorizationToken + } + return "" +} + +type UploadFileResponse struct { + FileId string `protobuf:"bytes,1,opt,name=file_id,json=fileId,proto3" json:"file_id,omitempty"` + FileName string `protobuf:"bytes,2,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + AccountId string `protobuf:"bytes,3,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` + BucketId string `protobuf:"bytes,4,opt,name=bucket_id,json=bucketId,proto3" json:"bucket_id,omitempty"` + ContentLength int32 `protobuf:"varint,5,opt,name=content_length,json=contentLength,proto3" json:"content_length,omitempty"` + ContentSha1 string `protobuf:"bytes,6,opt,name=content_sha1,json=contentSha1,proto3" json:"content_sha1,omitempty"` + ContentType string `protobuf:"bytes,7,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + FileInfo map[string]string `protobuf:"bytes,8,rep,name=file_info,json=fileInfo,proto3" json:"file_info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Action string `protobuf:"bytes,9,opt,name=action,proto3" json:"action,omitempty"` + UploadTimestamp int64 `protobuf:"varint,10,opt,name=upload_timestamp,json=uploadTimestamp,proto3" json:"upload_timestamp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UploadFileResponse) Reset() { *m = UploadFileResponse{} } +func (m *UploadFileResponse) String() string { return proto.CompactTextString(m) } +func (*UploadFileResponse) ProtoMessage() {} +func (*UploadFileResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{9} +} +func (m *UploadFileResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UploadFileResponse.Unmarshal(m, b) +} +func (m *UploadFileResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UploadFileResponse.Marshal(b, m, deterministic) +} +func (dst *UploadFileResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_UploadFileResponse.Merge(dst, src) +} +func (m *UploadFileResponse) XXX_Size() int { + return xxx_messageInfo_UploadFileResponse.Size(m) +} +func (m *UploadFileResponse) XXX_DiscardUnknown() { + xxx_messageInfo_UploadFileResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_UploadFileResponse proto.InternalMessageInfo + +func (m *UploadFileResponse) GetFileId() string { + if m != nil { + return m.FileId + } + return "" +} + +func (m *UploadFileResponse) GetFileName() string { + if m != nil { + return m.FileName + } + return "" +} + +func (m *UploadFileResponse) GetAccountId() string { + if m != nil { + return m.AccountId + } + return "" +} + +func (m *UploadFileResponse) GetBucketId() string { + if m != nil { + return m.BucketId + } + return "" +} + +func (m *UploadFileResponse) GetContentLength() int32 { + if m != nil { + return m.ContentLength + } + return 0 +} + +func (m *UploadFileResponse) GetContentSha1() string { + if m != nil { + return m.ContentSha1 + } + return "" +} + +func (m *UploadFileResponse) GetContentType() string { + if m != nil { + return m.ContentType + } + return "" +} + +func (m *UploadFileResponse) GetFileInfo() map[string]string { + if m != nil { + return m.FileInfo + } + return nil +} + +func (m *UploadFileResponse) GetAction() string { + if m != nil { + return m.Action + } + return "" +} + +func (m *UploadFileResponse) GetUploadTimestamp() int64 { + if m != nil { + return m.UploadTimestamp + } + return 0 +} + +type StartLargeFileRequest struct { + BucketId string `protobuf:"bytes,1,opt,name=bucket_id,json=bucketId,proto3" json:"bucket_id,omitempty"` + FileName string `protobuf:"bytes,2,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + ContentType string `protobuf:"bytes,3,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + FileInfo map[string]string `protobuf:"bytes,4,rep,name=file_info,json=fileInfo,proto3" json:"file_info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StartLargeFileRequest) Reset() { *m = StartLargeFileRequest{} } +func (m *StartLargeFileRequest) String() string { return proto.CompactTextString(m) } +func (*StartLargeFileRequest) ProtoMessage() {} +func (*StartLargeFileRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{10} +} +func (m *StartLargeFileRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StartLargeFileRequest.Unmarshal(m, b) +} +func (m *StartLargeFileRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StartLargeFileRequest.Marshal(b, m, deterministic) +} +func (dst *StartLargeFileRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartLargeFileRequest.Merge(dst, src) +} +func (m *StartLargeFileRequest) XXX_Size() int { + return xxx_messageInfo_StartLargeFileRequest.Size(m) +} +func (m *StartLargeFileRequest) XXX_DiscardUnknown() { + xxx_messageInfo_StartLargeFileRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_StartLargeFileRequest proto.InternalMessageInfo + +func (m *StartLargeFileRequest) GetBucketId() string { + if m != nil { + return m.BucketId + } + return "" +} + +func (m *StartLargeFileRequest) GetFileName() string { + if m != nil { + return m.FileName + } + return "" +} + +func (m *StartLargeFileRequest) GetContentType() string { + if m != nil { + return m.ContentType + } + return "" +} + +func (m *StartLargeFileRequest) GetFileInfo() map[string]string { + if m != nil { + return m.FileInfo + } + return nil +} + +type StartLargeFileResponse struct { + FileId string `protobuf:"bytes,1,opt,name=file_id,json=fileId,proto3" json:"file_id,omitempty"` + FileName string `protobuf:"bytes,2,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + AccountId string `protobuf:"bytes,3,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` + BucketId string `protobuf:"bytes,4,opt,name=bucket_id,json=bucketId,proto3" json:"bucket_id,omitempty"` + ContentType string `protobuf:"bytes,5,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + FileInfo map[string]string `protobuf:"bytes,6,rep,name=file_info,json=fileInfo,proto3" json:"file_info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + UploadTimestamp int64 `protobuf:"varint,7,opt,name=upload_timestamp,json=uploadTimestamp,proto3" json:"upload_timestamp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StartLargeFileResponse) Reset() { *m = StartLargeFileResponse{} } +func (m *StartLargeFileResponse) String() string { return proto.CompactTextString(m) } +func (*StartLargeFileResponse) ProtoMessage() {} +func (*StartLargeFileResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{11} +} +func (m *StartLargeFileResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StartLargeFileResponse.Unmarshal(m, b) +} +func (m *StartLargeFileResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StartLargeFileResponse.Marshal(b, m, deterministic) +} +func (dst *StartLargeFileResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartLargeFileResponse.Merge(dst, src) +} +func (m *StartLargeFileResponse) XXX_Size() int { + return xxx_messageInfo_StartLargeFileResponse.Size(m) +} +func (m *StartLargeFileResponse) XXX_DiscardUnknown() { + xxx_messageInfo_StartLargeFileResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_StartLargeFileResponse proto.InternalMessageInfo + +func (m *StartLargeFileResponse) GetFileId() string { + if m != nil { + return m.FileId + } + return "" +} + +func (m *StartLargeFileResponse) GetFileName() string { + if m != nil { + return m.FileName + } + return "" +} + +func (m *StartLargeFileResponse) GetAccountId() string { + if m != nil { + return m.AccountId + } + return "" +} + +func (m *StartLargeFileResponse) GetBucketId() string { + if m != nil { + return m.BucketId + } + return "" +} + +func (m *StartLargeFileResponse) GetContentType() string { + if m != nil { + return m.ContentType + } + return "" +} + +func (m *StartLargeFileResponse) GetFileInfo() map[string]string { + if m != nil { + return m.FileInfo + } + return nil +} + +func (m *StartLargeFileResponse) GetUploadTimestamp() int64 { + if m != nil { + return m.UploadTimestamp + } + return 0 +} + +type GetUploadPartUrlRequest struct { + FileId string `protobuf:"bytes,1,opt,name=file_id,json=fileId,proto3" json:"file_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetUploadPartUrlRequest) Reset() { *m = GetUploadPartUrlRequest{} } +func (m *GetUploadPartUrlRequest) String() string { return proto.CompactTextString(m) } +func (*GetUploadPartUrlRequest) ProtoMessage() {} +func (*GetUploadPartUrlRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{12} +} +func (m *GetUploadPartUrlRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetUploadPartUrlRequest.Unmarshal(m, b) +} +func (m *GetUploadPartUrlRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetUploadPartUrlRequest.Marshal(b, m, deterministic) +} +func (dst *GetUploadPartUrlRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetUploadPartUrlRequest.Merge(dst, src) +} +func (m *GetUploadPartUrlRequest) XXX_Size() int { + return xxx_messageInfo_GetUploadPartUrlRequest.Size(m) +} +func (m *GetUploadPartUrlRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetUploadPartUrlRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetUploadPartUrlRequest proto.InternalMessageInfo + +func (m *GetUploadPartUrlRequest) GetFileId() string { + if m != nil { + return m.FileId + } + return "" +} + +type GetUploadPartUrlResponse struct { + FileId string `protobuf:"bytes,1,opt,name=file_id,json=fileId,proto3" json:"file_id,omitempty"` + UploadUrl string `protobuf:"bytes,2,opt,name=upload_url,json=uploadUrl,proto3" json:"upload_url,omitempty"` + AuthorizationToken string `protobuf:"bytes,3,opt,name=authorization_token,json=authorizationToken,proto3" json:"authorization_token,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetUploadPartUrlResponse) Reset() { *m = GetUploadPartUrlResponse{} } +func (m *GetUploadPartUrlResponse) String() string { return proto.CompactTextString(m) } +func (*GetUploadPartUrlResponse) ProtoMessage() {} +func (*GetUploadPartUrlResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{13} +} +func (m *GetUploadPartUrlResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetUploadPartUrlResponse.Unmarshal(m, b) +} +func (m *GetUploadPartUrlResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetUploadPartUrlResponse.Marshal(b, m, deterministic) +} +func (dst *GetUploadPartUrlResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetUploadPartUrlResponse.Merge(dst, src) +} +func (m *GetUploadPartUrlResponse) XXX_Size() int { + return xxx_messageInfo_GetUploadPartUrlResponse.Size(m) +} +func (m *GetUploadPartUrlResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetUploadPartUrlResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetUploadPartUrlResponse proto.InternalMessageInfo + +func (m *GetUploadPartUrlResponse) GetFileId() string { + if m != nil { + return m.FileId + } + return "" +} + +func (m *GetUploadPartUrlResponse) GetUploadUrl() string { + if m != nil { + return m.UploadUrl + } + return "" +} + +func (m *GetUploadPartUrlResponse) GetAuthorizationToken() string { + if m != nil { + return m.AuthorizationToken + } + return "" +} + +type FinishLargeFileRequest struct { + FileId string `protobuf:"bytes,1,opt,name=file_id,json=fileId,proto3" json:"file_id,omitempty"` + PartSha1Array []string `protobuf:"bytes,2,rep,name=part_sha1_array,json=partSha1Array,proto3" json:"part_sha1_array,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FinishLargeFileRequest) Reset() { *m = FinishLargeFileRequest{} } +func (m *FinishLargeFileRequest) String() string { return proto.CompactTextString(m) } +func (*FinishLargeFileRequest) ProtoMessage() {} +func (*FinishLargeFileRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{14} +} +func (m *FinishLargeFileRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FinishLargeFileRequest.Unmarshal(m, b) +} +func (m *FinishLargeFileRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FinishLargeFileRequest.Marshal(b, m, deterministic) +} +func (dst *FinishLargeFileRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_FinishLargeFileRequest.Merge(dst, src) +} +func (m *FinishLargeFileRequest) XXX_Size() int { + return xxx_messageInfo_FinishLargeFileRequest.Size(m) +} +func (m *FinishLargeFileRequest) XXX_DiscardUnknown() { + xxx_messageInfo_FinishLargeFileRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_FinishLargeFileRequest proto.InternalMessageInfo + +func (m *FinishLargeFileRequest) GetFileId() string { + if m != nil { + return m.FileId + } + return "" +} + +func (m *FinishLargeFileRequest) GetPartSha1Array() []string { + if m != nil { + return m.PartSha1Array + } + return nil +} + +type FinishLargeFileResponse struct { + FileId string `protobuf:"bytes,1,opt,name=file_id,json=fileId,proto3" json:"file_id,omitempty"` + FileName string `protobuf:"bytes,2,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + AccountId string `protobuf:"bytes,3,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` + BucketId string `protobuf:"bytes,4,opt,name=bucket_id,json=bucketId,proto3" json:"bucket_id,omitempty"` + ContentLength int64 `protobuf:"varint,5,opt,name=content_length,json=contentLength,proto3" json:"content_length,omitempty"` + ContentSha1 string `protobuf:"bytes,6,opt,name=content_sha1,json=contentSha1,proto3" json:"content_sha1,omitempty"` + ContentType string `protobuf:"bytes,7,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + FileInfo map[string]string `protobuf:"bytes,8,rep,name=file_info,json=fileInfo,proto3" json:"file_info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Action string `protobuf:"bytes,9,opt,name=action,proto3" json:"action,omitempty"` + UploadTimestamp int64 `protobuf:"varint,10,opt,name=upload_timestamp,json=uploadTimestamp,proto3" json:"upload_timestamp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FinishLargeFileResponse) Reset() { *m = FinishLargeFileResponse{} } +func (m *FinishLargeFileResponse) String() string { return proto.CompactTextString(m) } +func (*FinishLargeFileResponse) ProtoMessage() {} +func (*FinishLargeFileResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{15} +} +func (m *FinishLargeFileResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FinishLargeFileResponse.Unmarshal(m, b) +} +func (m *FinishLargeFileResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FinishLargeFileResponse.Marshal(b, m, deterministic) +} +func (dst *FinishLargeFileResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_FinishLargeFileResponse.Merge(dst, src) +} +func (m *FinishLargeFileResponse) XXX_Size() int { + return xxx_messageInfo_FinishLargeFileResponse.Size(m) +} +func (m *FinishLargeFileResponse) XXX_DiscardUnknown() { + xxx_messageInfo_FinishLargeFileResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_FinishLargeFileResponse proto.InternalMessageInfo + +func (m *FinishLargeFileResponse) GetFileId() string { + if m != nil { + return m.FileId + } + return "" +} + +func (m *FinishLargeFileResponse) GetFileName() string { + if m != nil { + return m.FileName + } + return "" +} + +func (m *FinishLargeFileResponse) GetAccountId() string { + if m != nil { + return m.AccountId + } + return "" +} + +func (m *FinishLargeFileResponse) GetBucketId() string { + if m != nil { + return m.BucketId + } + return "" +} + +func (m *FinishLargeFileResponse) GetContentLength() int64 { + if m != nil { + return m.ContentLength + } + return 0 +} + +func (m *FinishLargeFileResponse) GetContentSha1() string { + if m != nil { + return m.ContentSha1 + } + return "" +} + +func (m *FinishLargeFileResponse) GetContentType() string { + if m != nil { + return m.ContentType + } + return "" +} + +func (m *FinishLargeFileResponse) GetFileInfo() map[string]string { + if m != nil { + return m.FileInfo + } + return nil +} + +func (m *FinishLargeFileResponse) GetAction() string { + if m != nil { + return m.Action + } + return "" +} + +func (m *FinishLargeFileResponse) GetUploadTimestamp() int64 { + if m != nil { + return m.UploadTimestamp + } + return 0 +} + +type ListFileVersionsRequest struct { + BucketId string `protobuf:"bytes,1,opt,name=bucket_id,json=bucketId,proto3" json:"bucket_id,omitempty"` + StartFileName string `protobuf:"bytes,2,opt,name=start_file_name,json=startFileName,proto3" json:"start_file_name,omitempty"` + StartFileId string `protobuf:"bytes,3,opt,name=start_file_id,json=startFileId,proto3" json:"start_file_id,omitempty"` + MaxFileCount int32 `protobuf:"varint,4,opt,name=max_file_count,json=maxFileCount,proto3" json:"max_file_count,omitempty"` + Prefix string `protobuf:"bytes,5,opt,name=prefix,proto3" json:"prefix,omitempty"` + Delimiter string `protobuf:"bytes,6,opt,name=delimiter,proto3" json:"delimiter,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListFileVersionsRequest) Reset() { *m = ListFileVersionsRequest{} } +func (m *ListFileVersionsRequest) String() string { return proto.CompactTextString(m) } +func (*ListFileVersionsRequest) ProtoMessage() {} +func (*ListFileVersionsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{16} +} +func (m *ListFileVersionsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ListFileVersionsRequest.Unmarshal(m, b) +} +func (m *ListFileVersionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ListFileVersionsRequest.Marshal(b, m, deterministic) +} +func (dst *ListFileVersionsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListFileVersionsRequest.Merge(dst, src) +} +func (m *ListFileVersionsRequest) XXX_Size() int { + return xxx_messageInfo_ListFileVersionsRequest.Size(m) +} +func (m *ListFileVersionsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ListFileVersionsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ListFileVersionsRequest proto.InternalMessageInfo + +func (m *ListFileVersionsRequest) GetBucketId() string { + if m != nil { + return m.BucketId + } + return "" +} + +func (m *ListFileVersionsRequest) GetStartFileName() string { + if m != nil { + return m.StartFileName + } + return "" +} + +func (m *ListFileVersionsRequest) GetStartFileId() string { + if m != nil { + return m.StartFileId + } + return "" +} + +func (m *ListFileVersionsRequest) GetMaxFileCount() int32 { + if m != nil { + return m.MaxFileCount + } + return 0 +} + +func (m *ListFileVersionsRequest) GetPrefix() string { + if m != nil { + return m.Prefix + } + return "" +} + +func (m *ListFileVersionsRequest) GetDelimiter() string { + if m != nil { + return m.Delimiter + } + return "" +} + +type ListFileVersionsResponse struct { + Files []*File `protobuf:"bytes,1,rep,name=files,proto3" json:"files,omitempty"` + NextFileName string `protobuf:"bytes,2,opt,name=next_file_name,json=nextFileName,proto3" json:"next_file_name,omitempty"` + NextFileId string `protobuf:"bytes,3,opt,name=next_file_id,json=nextFileId,proto3" json:"next_file_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListFileVersionsResponse) Reset() { *m = ListFileVersionsResponse{} } +func (m *ListFileVersionsResponse) String() string { return proto.CompactTextString(m) } +func (*ListFileVersionsResponse) ProtoMessage() {} +func (*ListFileVersionsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{17} +} +func (m *ListFileVersionsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ListFileVersionsResponse.Unmarshal(m, b) +} +func (m *ListFileVersionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ListFileVersionsResponse.Marshal(b, m, deterministic) +} +func (dst *ListFileVersionsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListFileVersionsResponse.Merge(dst, src) +} +func (m *ListFileVersionsResponse) XXX_Size() int { + return xxx_messageInfo_ListFileVersionsResponse.Size(m) +} +func (m *ListFileVersionsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ListFileVersionsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ListFileVersionsResponse proto.InternalMessageInfo + +func (m *ListFileVersionsResponse) GetFiles() []*File { + if m != nil { + return m.Files + } + return nil +} + +func (m *ListFileVersionsResponse) GetNextFileName() string { + if m != nil { + return m.NextFileName + } + return "" +} + +func (m *ListFileVersionsResponse) GetNextFileId() string { + if m != nil { + return m.NextFileId + } + return "" +} + +type File struct { + FileId string `protobuf:"bytes,1,opt,name=file_id,json=fileId,proto3" json:"file_id,omitempty"` + FileName string `protobuf:"bytes,2,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + ContentLength int64 `protobuf:"varint,3,opt,name=content_length,json=contentLength,proto3" json:"content_length,omitempty"` + ContentType string `protobuf:"bytes,4,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + ContentSha1 string `protobuf:"bytes,5,opt,name=content_sha1,json=contentSha1,proto3" json:"content_sha1,omitempty"` + FileInfo map[string]string `protobuf:"bytes,6,rep,name=file_info,json=fileInfo,proto3" json:"file_info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Action string `protobuf:"bytes,7,opt,name=action,proto3" json:"action,omitempty"` + Size int64 `protobuf:"varint,8,opt,name=size,proto3" json:"size,omitempty"` + UploadTimestamp int64 `protobuf:"varint,9,opt,name=upload_timestamp,json=uploadTimestamp,proto3" json:"upload_timestamp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *File) Reset() { *m = File{} } +func (m *File) String() string { return proto.CompactTextString(m) } +func (*File) ProtoMessage() {} +func (*File) Descriptor() ([]byte, []int) { + return fileDescriptor_pyre_492df08819220afa, []int{18} +} +func (m *File) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_File.Unmarshal(m, b) +} +func (m *File) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_File.Marshal(b, m, deterministic) +} +func (dst *File) XXX_Merge(src proto.Message) { + xxx_messageInfo_File.Merge(dst, src) +} +func (m *File) XXX_Size() int { + return xxx_messageInfo_File.Size(m) +} +func (m *File) XXX_DiscardUnknown() { + xxx_messageInfo_File.DiscardUnknown(m) +} + +var xxx_messageInfo_File proto.InternalMessageInfo + +func (m *File) GetFileId() string { + if m != nil { + return m.FileId + } + return "" +} + +func (m *File) GetFileName() string { + if m != nil { + return m.FileName + } + return "" +} + +func (m *File) GetContentLength() int64 { + if m != nil { + return m.ContentLength + } + return 0 +} + +func (m *File) GetContentType() string { + if m != nil { + return m.ContentType + } + return "" +} + +func (m *File) GetContentSha1() string { + if m != nil { + return m.ContentSha1 + } + return "" +} + +func (m *File) GetFileInfo() map[string]string { + if m != nil { + return m.FileInfo + } + return nil +} + +func (m *File) GetAction() string { + if m != nil { + return m.Action + } + return "" +} + +func (m *File) GetSize() int64 { + if m != nil { + return m.Size + } + return 0 +} + +func (m *File) GetUploadTimestamp() int64 { + if m != nil { + return m.UploadTimestamp + } + return 0 +} + +func init() { + proto.RegisterType((*AuthorizeAccountRequest)(nil), "pyre.proto.AuthorizeAccountRequest") + proto.RegisterType((*AuthorizeAccountResponse)(nil), "pyre.proto.AuthorizeAccountResponse") + proto.RegisterType((*ListBucketsRequest)(nil), "pyre.proto.ListBucketsRequest") + proto.RegisterType((*LifecycleRule)(nil), "pyre.proto.LifecycleRule") + proto.RegisterType((*CorsRule)(nil), "pyre.proto.CorsRule") + proto.RegisterType((*Bucket)(nil), "pyre.proto.Bucket") + proto.RegisterMapType((map[string]string)(nil), "pyre.proto.Bucket.BucketInfoEntry") + proto.RegisterType((*ListBucketsResponse)(nil), "pyre.proto.ListBucketsResponse") + proto.RegisterType((*GetUploadUrlRequest)(nil), "pyre.proto.GetUploadUrlRequest") + proto.RegisterType((*GetUploadUrlResponse)(nil), "pyre.proto.GetUploadUrlResponse") + proto.RegisterType((*UploadFileResponse)(nil), "pyre.proto.UploadFileResponse") + proto.RegisterMapType((map[string]string)(nil), "pyre.proto.UploadFileResponse.FileInfoEntry") + proto.RegisterType((*StartLargeFileRequest)(nil), "pyre.proto.StartLargeFileRequest") + proto.RegisterMapType((map[string]string)(nil), "pyre.proto.StartLargeFileRequest.FileInfoEntry") + proto.RegisterType((*StartLargeFileResponse)(nil), "pyre.proto.StartLargeFileResponse") + proto.RegisterMapType((map[string]string)(nil), "pyre.proto.StartLargeFileResponse.FileInfoEntry") + proto.RegisterType((*GetUploadPartUrlRequest)(nil), "pyre.proto.GetUploadPartUrlRequest") + proto.RegisterType((*GetUploadPartUrlResponse)(nil), "pyre.proto.GetUploadPartUrlResponse") + proto.RegisterType((*FinishLargeFileRequest)(nil), "pyre.proto.FinishLargeFileRequest") + proto.RegisterType((*FinishLargeFileResponse)(nil), "pyre.proto.FinishLargeFileResponse") + proto.RegisterMapType((map[string]string)(nil), "pyre.proto.FinishLargeFileResponse.FileInfoEntry") + proto.RegisterType((*ListFileVersionsRequest)(nil), "pyre.proto.ListFileVersionsRequest") + proto.RegisterType((*ListFileVersionsResponse)(nil), "pyre.proto.ListFileVersionsResponse") + proto.RegisterType((*File)(nil), "pyre.proto.File") + proto.RegisterMapType((map[string]string)(nil), "pyre.proto.File.FileInfoEntry") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// PyreServiceClient is the client API for PyreService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type PyreServiceClient interface { + // Used to log in to the B2 API. Returns an authorization token that can be + // used for account-level operations, and a URL that should be used as the + // base URL for subsequent API calls. + AuthorizeAccount(ctx context.Context, in *AuthorizeAccountRequest, opts ...grpc.CallOption) (*AuthorizeAccountResponse, error) + // Lists buckets associated with an account, in alphabetical order by bucket + // name. + ListBuckets(ctx context.Context, in *ListBucketsRequest, opts ...grpc.CallOption) (*ListBucketsResponse, error) + // Creates a new bucket. A bucket belongs to the account used to create it. + // + // Buckets can be named. The name must be globally unique. No account can use + // a bucket with the same name. Buckets are assigned a unique bucketId which + // is used when uploading, downloading, or deleting files. + // + // There is a limit of 100 buckets per account. + CreateBucket(ctx context.Context, in *Bucket, opts ...grpc.CallOption) (*Bucket, error) + // Deletes the bucket specified. Only buckets that contain no version of any + // files can be deleted. + DeleteBucket(ctx context.Context, in *Bucket, opts ...grpc.CallOption) (*Bucket, error) + GetUploadUrl(ctx context.Context, in *GetUploadUrlRequest, opts ...grpc.CallOption) (*GetUploadUrlResponse, error) + // Prepares for uploading the parts of a large file. + StartLargeFile(ctx context.Context, in *StartLargeFileRequest, opts ...grpc.CallOption) (*StartLargeFileResponse, error) + // Gets an URL to use for uploading parts of a large file. + GetUploadPartUrl(ctx context.Context, in *GetUploadPartUrlRequest, opts ...grpc.CallOption) (*GetUploadPartUrlResponse, error) + // Converts the parts that have been uploaded into a single B2 file. + FinishLargeFile(ctx context.Context, in *FinishLargeFileRequest, opts ...grpc.CallOption) (*FinishLargeFileResponse, error) + // Lists all of the versions of all of the files contained in one bucket, in + // alphabetical order by file name, and by reverse of date/time uploaded for + // versions of files with the same name. + ListFileVersions(ctx context.Context, in *ListFileVersionsRequest, opts ...grpc.CallOption) (*ListFileVersionsResponse, error) +} + +type pyreServiceClient struct { + cc *grpc.ClientConn +} + +func NewPyreServiceClient(cc *grpc.ClientConn) PyreServiceClient { + return &pyreServiceClient{cc} +} + +func (c *pyreServiceClient) AuthorizeAccount(ctx context.Context, in *AuthorizeAccountRequest, opts ...grpc.CallOption) (*AuthorizeAccountResponse, error) { + out := new(AuthorizeAccountResponse) + err := c.cc.Invoke(ctx, "/pyre.proto.PyreService/AuthorizeAccount", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pyreServiceClient) ListBuckets(ctx context.Context, in *ListBucketsRequest, opts ...grpc.CallOption) (*ListBucketsResponse, error) { + out := new(ListBucketsResponse) + err := c.cc.Invoke(ctx, "/pyre.proto.PyreService/ListBuckets", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pyreServiceClient) CreateBucket(ctx context.Context, in *Bucket, opts ...grpc.CallOption) (*Bucket, error) { + out := new(Bucket) + err := c.cc.Invoke(ctx, "/pyre.proto.PyreService/CreateBucket", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pyreServiceClient) DeleteBucket(ctx context.Context, in *Bucket, opts ...grpc.CallOption) (*Bucket, error) { + out := new(Bucket) + err := c.cc.Invoke(ctx, "/pyre.proto.PyreService/DeleteBucket", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pyreServiceClient) GetUploadUrl(ctx context.Context, in *GetUploadUrlRequest, opts ...grpc.CallOption) (*GetUploadUrlResponse, error) { + out := new(GetUploadUrlResponse) + err := c.cc.Invoke(ctx, "/pyre.proto.PyreService/GetUploadUrl", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pyreServiceClient) StartLargeFile(ctx context.Context, in *StartLargeFileRequest, opts ...grpc.CallOption) (*StartLargeFileResponse, error) { + out := new(StartLargeFileResponse) + err := c.cc.Invoke(ctx, "/pyre.proto.PyreService/StartLargeFile", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pyreServiceClient) GetUploadPartUrl(ctx context.Context, in *GetUploadPartUrlRequest, opts ...grpc.CallOption) (*GetUploadPartUrlResponse, error) { + out := new(GetUploadPartUrlResponse) + err := c.cc.Invoke(ctx, "/pyre.proto.PyreService/GetUploadPartUrl", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pyreServiceClient) FinishLargeFile(ctx context.Context, in *FinishLargeFileRequest, opts ...grpc.CallOption) (*FinishLargeFileResponse, error) { + out := new(FinishLargeFileResponse) + err := c.cc.Invoke(ctx, "/pyre.proto.PyreService/FinishLargeFile", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *pyreServiceClient) ListFileVersions(ctx context.Context, in *ListFileVersionsRequest, opts ...grpc.CallOption) (*ListFileVersionsResponse, error) { + out := new(ListFileVersionsResponse) + err := c.cc.Invoke(ctx, "/pyre.proto.PyreService/ListFileVersions", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PyreServiceServer is the server API for PyreService service. +type PyreServiceServer interface { + // Used to log in to the B2 API. Returns an authorization token that can be + // used for account-level operations, and a URL that should be used as the + // base URL for subsequent API calls. + AuthorizeAccount(context.Context, *AuthorizeAccountRequest) (*AuthorizeAccountResponse, error) + // Lists buckets associated with an account, in alphabetical order by bucket + // name. + ListBuckets(context.Context, *ListBucketsRequest) (*ListBucketsResponse, error) + // Creates a new bucket. A bucket belongs to the account used to create it. + // + // Buckets can be named. The name must be globally unique. No account can use + // a bucket with the same name. Buckets are assigned a unique bucketId which + // is used when uploading, downloading, or deleting files. + // + // There is a limit of 100 buckets per account. + CreateBucket(context.Context, *Bucket) (*Bucket, error) + // Deletes the bucket specified. Only buckets that contain no version of any + // files can be deleted. + DeleteBucket(context.Context, *Bucket) (*Bucket, error) + GetUploadUrl(context.Context, *GetUploadUrlRequest) (*GetUploadUrlResponse, error) + // Prepares for uploading the parts of a large file. + StartLargeFile(context.Context, *StartLargeFileRequest) (*StartLargeFileResponse, error) + // Gets an URL to use for uploading parts of a large file. + GetUploadPartUrl(context.Context, *GetUploadPartUrlRequest) (*GetUploadPartUrlResponse, error) + // Converts the parts that have been uploaded into a single B2 file. + FinishLargeFile(context.Context, *FinishLargeFileRequest) (*FinishLargeFileResponse, error) + // Lists all of the versions of all of the files contained in one bucket, in + // alphabetical order by file name, and by reverse of date/time uploaded for + // versions of files with the same name. + ListFileVersions(context.Context, *ListFileVersionsRequest) (*ListFileVersionsResponse, error) +} + +func RegisterPyreServiceServer(s *grpc.Server, srv PyreServiceServer) { + s.RegisterService(&_PyreService_serviceDesc, srv) +} + +func _PyreService_AuthorizeAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AuthorizeAccountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PyreServiceServer).AuthorizeAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pyre.proto.PyreService/AuthorizeAccount", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PyreServiceServer).AuthorizeAccount(ctx, req.(*AuthorizeAccountRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PyreService_ListBuckets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListBucketsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PyreServiceServer).ListBuckets(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pyre.proto.PyreService/ListBuckets", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PyreServiceServer).ListBuckets(ctx, req.(*ListBucketsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PyreService_CreateBucket_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Bucket) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PyreServiceServer).CreateBucket(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pyre.proto.PyreService/CreateBucket", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PyreServiceServer).CreateBucket(ctx, req.(*Bucket)) + } + return interceptor(ctx, in, info, handler) +} + +func _PyreService_DeleteBucket_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Bucket) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PyreServiceServer).DeleteBucket(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pyre.proto.PyreService/DeleteBucket", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PyreServiceServer).DeleteBucket(ctx, req.(*Bucket)) + } + return interceptor(ctx, in, info, handler) +} + +func _PyreService_GetUploadUrl_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUploadUrlRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PyreServiceServer).GetUploadUrl(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pyre.proto.PyreService/GetUploadUrl", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PyreServiceServer).GetUploadUrl(ctx, req.(*GetUploadUrlRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PyreService_StartLargeFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StartLargeFileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PyreServiceServer).StartLargeFile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pyre.proto.PyreService/StartLargeFile", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PyreServiceServer).StartLargeFile(ctx, req.(*StartLargeFileRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PyreService_GetUploadPartUrl_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUploadPartUrlRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PyreServiceServer).GetUploadPartUrl(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pyre.proto.PyreService/GetUploadPartUrl", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PyreServiceServer).GetUploadPartUrl(ctx, req.(*GetUploadPartUrlRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PyreService_FinishLargeFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FinishLargeFileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PyreServiceServer).FinishLargeFile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pyre.proto.PyreService/FinishLargeFile", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PyreServiceServer).FinishLargeFile(ctx, req.(*FinishLargeFileRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PyreService_ListFileVersions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListFileVersionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PyreServiceServer).ListFileVersions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pyre.proto.PyreService/ListFileVersions", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PyreServiceServer).ListFileVersions(ctx, req.(*ListFileVersionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _PyreService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pyre.proto.PyreService", + HandlerType: (*PyreServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "AuthorizeAccount", + Handler: _PyreService_AuthorizeAccount_Handler, + }, + { + MethodName: "ListBuckets", + Handler: _PyreService_ListBuckets_Handler, + }, + { + MethodName: "CreateBucket", + Handler: _PyreService_CreateBucket_Handler, + }, + { + MethodName: "DeleteBucket", + Handler: _PyreService_DeleteBucket_Handler, + }, + { + MethodName: "GetUploadUrl", + Handler: _PyreService_GetUploadUrl_Handler, + }, + { + MethodName: "StartLargeFile", + Handler: _PyreService_StartLargeFile_Handler, + }, + { + MethodName: "GetUploadPartUrl", + Handler: _PyreService_GetUploadPartUrl_Handler, + }, + { + MethodName: "FinishLargeFile", + Handler: _PyreService_FinishLargeFile_Handler, + }, + { + MethodName: "ListFileVersions", + Handler: _PyreService_ListFileVersions_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "proto/pyre.proto", +} + +func init() { proto.RegisterFile("proto/pyre.proto", fileDescriptor_pyre_492df08819220afa) } + +var fileDescriptor_pyre_492df08819220afa = []byte{ + // 1591 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcb, 0x6f, 0x1b, 0x55, + 0x17, 0xd7, 0xd8, 0x71, 0x1c, 0x1f, 0xc7, 0xb1, 0x7b, 0xd3, 0x36, 0x13, 0xb7, 0x4d, 0xdc, 0xdb, + 0x24, 0x5f, 0x9a, 0xaf, 0x5f, 0xfc, 0x25, 0x08, 0x09, 0xb5, 0x02, 0x91, 0x06, 0x42, 0x23, 0xa5, + 0xa5, 0x72, 0x52, 0x24, 0x16, 0x68, 0x74, 0xe3, 0xb9, 0xb1, 0xaf, 0x3a, 0x0f, 0x73, 0x67, 0x9c, + 0xc6, 0x5d, 0xf1, 0x50, 0x17, 0x74, 0x0b, 0xff, 0x00, 0x7f, 0x07, 0x12, 0x1b, 0x36, 0xec, 0xd9, + 0xb3, 0xea, 0x86, 0x7f, 0x81, 0x0d, 0xe8, 0x3e, 0xc6, 0x9e, 0x47, 0x9c, 0x14, 0x68, 0x45, 0x57, + 0x9e, 0x39, 0xf7, 0x77, 0xce, 0x3d, 0xf7, 0x77, 0x1e, 0x73, 0xae, 0xa1, 0xd6, 0xe3, 0x7e, 0xe8, + 0x37, 0x7b, 0x03, 0x4e, 0xd7, 0xe5, 0x23, 0x82, 0xd1, 0x73, 0xfd, 0x6a, 0xc7, 0xf7, 0x3b, 0x0e, + 0x6d, 0x92, 0x1e, 0x6b, 0x12, 0xcf, 0xf3, 0x43, 0x12, 0x32, 0xdf, 0x0b, 0xd4, 0x2a, 0x9e, 0x87, + 0xb9, 0xad, 0x7e, 0xd8, 0xf5, 0x39, 0x7b, 0x4a, 0xb7, 0xda, 0x6d, 0xbf, 0xef, 0x85, 0x2d, 0xfa, + 0x79, 0x9f, 0x06, 0x21, 0xfe, 0x29, 0x07, 0x66, 0x76, 0x2d, 0xe8, 0xf9, 0x5e, 0x40, 0xd1, 0x35, + 0x00, 0xa2, 0x44, 0x16, 0xb3, 0x4d, 0xa3, 0x61, 0xac, 0x96, 0x5a, 0x25, 0x2d, 0xd9, 0xb5, 0x51, + 0x13, 0x66, 0x89, 0x56, 0x95, 0xdb, 0x59, 0xa1, 0xff, 0x98, 0x7a, 0x66, 0x4e, 0xe2, 0x50, 0x62, + 0xe9, 0x40, 0xac, 0xa0, 0x39, 0x28, 0x92, 0x1e, 0xb3, 0xfa, 0xdc, 0x31, 0xf3, 0x12, 0x34, 0x49, + 0x7a, 0xec, 0x11, 0x77, 0xd0, 0x75, 0x98, 0xb6, 0xfd, 0x27, 0x9e, 0xe3, 0x13, 0x5b, 0xae, 0x4e, + 0xc8, 0xd5, 0x72, 0x24, 0x13, 0x90, 0x4d, 0xb8, 0xc4, 0x69, 0xdb, 0x77, 0x5d, 0xea, 0xd9, 0xd4, + 0xb6, 0x7a, 0x84, 0x87, 0x56, 0xc0, 0x9e, 0x52, 0xb3, 0xd0, 0x30, 0x56, 0x0b, 0xad, 0xd9, 0xd8, + 0xe2, 0x43, 0xc2, 0xc3, 0x7d, 0xf6, 0x94, 0xa2, 0x3b, 0x50, 0x27, 0x87, 0x81, 0xef, 0xf4, 0x43, + 0x6a, 0xb9, 0xcc, 0x63, 0x6e, 0xdf, 0x8d, 0x29, 0x4e, 0x4a, 0xc5, 0xb9, 0x08, 0x71, 0x5f, 0x01, + 0x86, 0xca, 0x6b, 0x70, 0x21, 0xab, 0x53, 0x94, 0x3a, 0x55, 0x37, 0x89, 0xc5, 0xdf, 0x19, 0x80, + 0xf6, 0x58, 0x10, 0xde, 0xed, 0xb7, 0x1f, 0xd3, 0x30, 0xd0, 0xe4, 0x9e, 0xc7, 0xdf, 0x15, 0x28, + 0x1d, 0x4a, 0x05, 0xb1, 0xaa, 0x58, 0x9b, 0x52, 0x82, 0x5d, 0x1b, 0x2d, 0x42, 0x59, 0x2f, 0x7a, + 0xc4, 0xa5, 0x9a, 0x2f, 0x50, 0xa2, 0x07, 0xc4, 0xa5, 0x82, 0x33, 0x0d, 0x08, 0x07, 0x3d, 0x1a, + 0x98, 0x13, 0x8d, 0xbc, 0xe0, 0x4c, 0xc9, 0x0e, 0x84, 0x08, 0xff, 0x60, 0x40, 0x65, 0x8f, 0x1d, + 0xd1, 0xf6, 0xa0, 0xed, 0xd0, 0x56, 0xdf, 0xa1, 0xe8, 0x7d, 0xb8, 0x66, 0x93, 0x41, 0x60, 0x1d, + 0x71, 0xdf, 0xb5, 0xfa, 0x3d, 0x41, 0x2e, 0xf3, 0x3a, 0x56, 0xe8, 0x5b, 0x5d, 0x26, 0x9e, 0xa4, + 0x93, 0x85, 0xd6, 0xbc, 0x00, 0xed, 0x70, 0xdf, 0x7d, 0x14, 0x41, 0x0e, 0xfc, 0x7b, 0x12, 0x80, + 0xde, 0x83, 0xab, 0x23, 0x0b, 0x4a, 0x49, 0xa8, 0xdb, 0xd4, 0xa1, 0xa1, 0x30, 0x90, 0x93, 0x06, + 0xcc, 0xc8, 0x80, 0xd2, 0x3a, 0xf0, 0x3f, 0xd0, 0xeb, 0x68, 0x15, 0x6a, 0x47, 0xcc, 0xa1, 0xf2, + 0x54, 0x56, 0x8f, 0xd3, 0x23, 0x76, 0xa2, 0x0f, 0x37, 0x23, 0xe4, 0xe2, 0x68, 0x0f, 0xa5, 0x14, + 0x7f, 0x91, 0x83, 0xa9, 0x6d, 0x9f, 0x07, 0xd2, 0xf1, 0x25, 0x98, 0x69, 0xfb, 0x3c, 0xb0, 0x78, + 0x5f, 0xeb, 0x6a, 0x3a, 0xa7, 0xdb, 0x1a, 0x21, 0x39, 0xf9, 0x0f, 0x54, 0x89, 0xe3, 0xf8, 0x4f, + 0xa8, 0x6d, 0xf9, 0x9c, 0x75, 0x98, 0x17, 0x98, 0x39, 0x49, 0xcb, 0x8c, 0x16, 0x7f, 0xac, 0xa4, + 0xe8, 0x7f, 0x80, 0x86, 0xc0, 0x1e, 0xe5, 0xaa, 0x5a, 0xcc, 0xbc, 0xc4, 0x5e, 0x88, 0xb0, 0xc3, + 0x85, 0xb8, 0xdd, 0x2e, 0x25, 0x36, 0xe5, 0x11, 0xdd, 0x91, 0xdd, 0x7b, 0x4a, 0x8a, 0x96, 0x61, + 0x86, 0x9e, 0xf4, 0xfc, 0x80, 0x0e, 0x71, 0x05, 0x89, 0xab, 0x28, 0x69, 0x04, 0x5b, 0x81, 0xaa, + 0x4b, 0x4e, 0x2c, 0xd2, 0xa1, 0x56, 0x40, 0xdb, 0xbe, 0x67, 0x07, 0x3a, 0x1b, 0x2b, 0x2e, 0x39, + 0xd9, 0xea, 0xd0, 0x7d, 0x25, 0xc4, 0xdf, 0xe7, 0x61, 0x52, 0xe5, 0xd4, 0xeb, 0xcd, 0xa5, 0x11, + 0x40, 0xe4, 0x92, 0x2e, 0x3f, 0x18, 0xa5, 0x12, 0xda, 0x1e, 0x02, 0x98, 0x77, 0xe4, 0xcb, 0x43, + 0x95, 0x37, 0xf1, 0xfa, 0xa8, 0x03, 0xad, 0x2b, 0x37, 0xf5, 0xcf, 0xae, 0x77, 0xe4, 0x7f, 0xe8, + 0x85, 0x7c, 0x10, 0x19, 0x11, 0x02, 0xf4, 0x36, 0x94, 0xdb, 0x3e, 0xa7, 0x2a, 0x88, 0xe2, 0xc4, + 0xc2, 0xc8, 0xc5, 0xb8, 0x91, 0x28, 0xdc, 0x2d, 0x90, 0x40, 0xf1, 0x18, 0xa0, 0xbb, 0x50, 0x75, + 0xa2, 0x24, 0xd6, 0xaa, 0x45, 0xa9, 0x3a, 0x1f, 0x57, 0x4d, 0xe4, 0x79, 0x6b, 0xc6, 0x89, 0xbf, + 0x06, 0xa8, 0x0e, 0x53, 0x9c, 0x1e, 0xb3, 0x80, 0xf9, 0x9e, 0x39, 0x25, 0x99, 0x1e, 0xbe, 0xd7, + 0xdf, 0x85, 0x6a, 0xca, 0x6b, 0x54, 0x83, 0xfc, 0x63, 0x3a, 0xd0, 0x2c, 0x8b, 0x47, 0x74, 0x11, + 0x0a, 0xc7, 0xc4, 0xe9, 0x53, 0xcd, 0xad, 0x7a, 0xb9, 0x9d, 0x7b, 0xc7, 0xc0, 0xdb, 0x30, 0x9b, + 0x28, 0x7d, 0xdd, 0x3b, 0x6f, 0x41, 0x51, 0x1d, 0x3d, 0x30, 0x0d, 0xe9, 0x2d, 0xca, 0xb2, 0xd5, + 0x8a, 0x20, 0x78, 0x13, 0x66, 0x3f, 0xa2, 0xa1, 0xaa, 0xb6, 0x47, 0xdc, 0x89, 0x1a, 0x48, 0x22, + 0xaa, 0x46, 0x32, 0xaa, 0xf8, 0x6b, 0x03, 0x2e, 0x26, 0x95, 0xf4, 0xd6, 0x67, 0x69, 0x89, 0x3c, + 0x52, 0x75, 0x2f, 0x1b, 0xad, 0x3a, 0x4d, 0xa9, 0x1f, 0xd9, 0x18, 0xd7, 0xd3, 0xf3, 0xe3, 0x7a, + 0x3a, 0xfe, 0x31, 0x0f, 0x48, 0xb9, 0xb0, 0xc3, 0x1c, 0x3a, 0xf4, 0x61, 0x0e, 0x8a, 0xb2, 0xcc, + 0x87, 0x1e, 0x4c, 0x8a, 0x57, 0x95, 0xa8, 0xc3, 0xfa, 0x8f, 0x12, 0x35, 0x2a, 0xfc, 0x54, 0x92, + 0xe7, 0xcf, 0x4c, 0xf2, 0x89, 0xd4, 0xc1, 0x96, 0x45, 0x87, 0xf0, 0x42, 0xea, 0x85, 0x96, 0x43, + 0xbd, 0x4e, 0xd8, 0xd5, 0x5f, 0x86, 0x8a, 0x96, 0xee, 0x49, 0xa1, 0x68, 0x9b, 0x11, 0x2c, 0xe8, + 0x92, 0x0d, 0x59, 0x77, 0xa5, 0x56, 0x59, 0xcb, 0xf6, 0xbb, 0x64, 0x23, 0x0e, 0x91, 0xe5, 0x50, + 0x4c, 0x40, 0x64, 0x3d, 0xec, 0xea, 0x53, 0xc8, 0x6a, 0x98, 0x92, 0xf1, 0xbd, 0x15, 0x8f, 0x6f, + 0x96, 0x91, 0x75, 0xf1, 0x32, 0xaa, 0x0b, 0x79, 0x66, 0x59, 0x15, 0x97, 0x61, 0x92, 0xb4, 0x05, + 0x9f, 0x66, 0x49, 0x7f, 0x13, 0xe5, 0x1b, 0xba, 0x09, 0x35, 0x1d, 0xa8, 0x90, 0xb9, 0x34, 0x08, + 0x89, 0xdb, 0x33, 0xa1, 0x61, 0xac, 0xe6, 0x5b, 0x55, 0x25, 0x3f, 0x88, 0xc4, 0xf5, 0x3b, 0x50, + 0x49, 0x58, 0xff, 0x4b, 0xf9, 0xfb, 0x87, 0x01, 0x97, 0xf6, 0x43, 0xc2, 0xc3, 0x3d, 0xc2, 0x3b, + 0x54, 0xb9, 0x7c, 0x7e, 0xf6, 0x9d, 0x1d, 0xc7, 0x34, 0x83, 0xf9, 0x2c, 0x83, 0x7b, 0x71, 0x06, + 0x27, 0x24, 0x83, 0xcd, 0x38, 0x83, 0xa7, 0xba, 0x34, 0x8e, 0xc4, 0x7f, 0xc6, 0xc0, 0x8b, 0x1c, + 0x5c, 0x4e, 0x6f, 0xf7, 0xaf, 0xa5, 0x71, 0x9a, 0xba, 0x42, 0x96, 0xba, 0xfb, 0x71, 0xea, 0x54, + 0x17, 0xfd, 0xff, 0x59, 0xd4, 0x9d, 0x93, 0x80, 0xa7, 0x25, 0x5a, 0xf1, 0x35, 0x24, 0xda, 0x26, + 0xcc, 0x0d, 0xdb, 0x95, 0x98, 0x9c, 0x62, 0x7d, 0x6e, 0x1c, 0xcd, 0xa2, 0xc7, 0x99, 0x59, 0xa5, + 0xf3, 0x82, 0xf3, 0xaa, 0x7b, 0xdc, 0xa7, 0x70, 0x79, 0x87, 0x79, 0x2c, 0xe8, 0x66, 0x4a, 0x64, + 0xac, 0x0b, 0x2b, 0x50, 0x55, 0x53, 0x63, 0x97, 0x6c, 0x58, 0x84, 0x73, 0x32, 0xd0, 0x93, 0x48, + 0x45, 0x88, 0x45, 0x9b, 0xd9, 0x12, 0x42, 0xfc, 0x73, 0x1e, 0xe6, 0x32, 0xb6, 0xdf, 0xb0, 0x1e, + 0x9a, 0x7f, 0x3d, 0x3d, 0xf4, 0x41, 0xb6, 0x87, 0x6e, 0xc4, 0xd3, 0x78, 0x0c, 0x2d, 0x6f, 0x6c, + 0x23, 0xfd, 0xd5, 0x80, 0x39, 0x31, 0x09, 0x08, 0x0b, 0x9f, 0x50, 0x2e, 0x66, 0x8b, 0xe0, 0xa5, + 0x5a, 0xe9, 0x0a, 0x54, 0x03, 0x51, 0xb2, 0x56, 0x3a, 0xa8, 0x15, 0x29, 0xde, 0x89, 0x22, 0x8b, + 0xa1, 0x12, 0xc3, 0x0d, 0x83, 0x5b, 0x1e, 0xa2, 0x76, 0x6d, 0x31, 0x27, 0x8b, 0xc9, 0x52, 0x22, + 0x64, 0xc8, 0x65, 0x8c, 0x0b, 0xad, 0x69, 0x97, 0x9c, 0x08, 0xc8, 0xb6, 0x90, 0x09, 0xaa, 0xf4, + 0xe8, 0xad, 0xda, 0x8b, 0x7e, 0x43, 0x57, 0xa1, 0x64, 0x53, 0x87, 0xb9, 0x2c, 0xa4, 0x5c, 0x47, + 0x75, 0x24, 0xc0, 0xcf, 0x0d, 0x30, 0xb3, 0x07, 0xd4, 0xc9, 0xba, 0x02, 0x05, 0xb1, 0x69, 0x34, + 0xed, 0xd4, 0x92, 0x91, 0x74, 0x68, 0x4b, 0x2d, 0x0b, 0x07, 0x3d, 0x7a, 0x92, 0x3d, 0xeb, 0xb4, + 0x90, 0x0e, 0x8f, 0xda, 0x80, 0xe9, 0x11, 0x6a, 0x78, 0x52, 0x88, 0x30, 0xbb, 0x36, 0xfe, 0x3d, + 0x07, 0x13, 0xe2, 0xf1, 0x6f, 0x56, 0x49, 0x36, 0xd3, 0xf3, 0xe7, 0x64, 0x7a, 0x6c, 0x32, 0x4e, + 0xa4, 0x71, 0xba, 0x18, 0x0a, 0xd9, 0x62, 0xb8, 0x93, 0x6d, 0xd8, 0x0b, 0x69, 0x7e, 0x5e, 0x22, + 0xad, 0x8b, 0x89, 0xb4, 0x46, 0x30, 0x21, 0xaf, 0xa4, 0x53, 0xd2, 0x6f, 0xf9, 0x7c, 0x6a, 0xaa, + 0x97, 0x5e, 0x7d, 0xaa, 0x6f, 0xfe, 0x36, 0x05, 0xe5, 0x87, 0x03, 0x4e, 0xf7, 0x29, 0x3f, 0x66, + 0x6d, 0x8a, 0x9e, 0x19, 0x50, 0x4b, 0xff, 0x8b, 0x80, 0x6e, 0xc4, 0x8f, 0x38, 0xe6, 0xff, 0x87, + 0xfa, 0xd2, 0xd9, 0x20, 0x95, 0x5c, 0x78, 0xe5, 0xab, 0x5f, 0x5e, 0x7c, 0x9b, 0x6b, 0xa0, 0x85, + 0xe6, 0xe1, 0x26, 0xe9, 0xb1, 0xe6, 0xf1, 0x46, 0xf3, 0x70, 0xd3, 0x8a, 0x3a, 0x35, 0xb5, 0x74, + 0x7b, 0x43, 0x21, 0x94, 0x63, 0xb3, 0x38, 0x5a, 0x48, 0x5e, 0x10, 0xd2, 0xf7, 0xf3, 0xfa, 0xe2, + 0xd8, 0x75, 0xbd, 0xef, 0x92, 0xdc, 0x77, 0x01, 0xcf, 0x27, 0xf6, 0x75, 0x58, 0x10, 0x5a, 0x7a, + 0x72, 0xbf, 0x6d, 0xac, 0xa1, 0xcf, 0x60, 0x7a, 0x9b, 0x53, 0x12, 0x52, 0x7d, 0x55, 0x3b, 0x65, + 0xd2, 0xaf, 0x9f, 0x22, 0xc3, 0xcb, 0xd2, 0xfa, 0x22, 0xae, 0x27, 0xac, 0xb7, 0xa5, 0x29, 0x6d, + 0x5f, 0x9b, 0x97, 0xb7, 0xe7, 0x57, 0x63, 0x5e, 0x5e, 0xd4, 0xe3, 0xe6, 0x07, 0x30, 0x1d, 0xbf, + 0x45, 0xa0, 0x04, 0x29, 0xa7, 0x5c, 0x4a, 0xea, 0x8d, 0xf1, 0x80, 0x64, 0xb8, 0xf0, 0x95, 0xc4, + 0xce, 0x1d, 0x1a, 0x5a, 0xa3, 0xcf, 0xb2, 0xd8, 0xfa, 0x4b, 0x03, 0x66, 0x92, 0xc3, 0x0a, 0xba, + 0x7e, 0xee, 0x0c, 0x58, 0xc7, 0xe7, 0xcf, 0x3a, 0x78, 0x55, 0x7a, 0x80, 0xf1, 0xb5, 0x84, 0x07, + 0xaa, 0x7b, 0x3a, 0x02, 0x2d, 0x3b, 0x8b, 0xf0, 0xe1, 0xb9, 0x01, 0xb5, 0xf4, 0x84, 0x91, 0x4c, + 0xdd, 0x31, 0x43, 0x4b, 0x32, 0x75, 0xc7, 0x0d, 0x29, 0xf8, 0xbf, 0xd2, 0x93, 0x65, 0xdc, 0x18, + 0xc7, 0x85, 0x1c, 0x13, 0x34, 0x21, 0xcf, 0x0c, 0xa8, 0xa6, 0x3e, 0x7b, 0x08, 0x9f, 0xf9, 0x4d, + 0x54, 0xae, 0xdc, 0x78, 0x89, 0xef, 0x26, 0xbe, 0x29, 0x3d, 0xb9, 0x81, 0x93, 0x45, 0x74, 0x24, + 0xd1, 0x29, 0x52, 0xbe, 0x31, 0xa0, 0x96, 0xee, 0xf4, 0x49, 0x52, 0xc6, 0x7c, 0xe8, 0x92, 0xa4, + 0x8c, 0xfb, 0x58, 0xe0, 0x35, 0xe9, 0xca, 0x12, 0x5e, 0xcc, 0xd6, 0x95, 0x6c, 0x94, 0xc7, 0x5a, + 0xe1, 0xb6, 0xb1, 0x76, 0x38, 0x29, 0x6d, 0xbd, 0xf5, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0x09, + 0x84, 0xd9, 0x63, 0x01, 0x15, 0x00, 0x00, +} diff --git a/vendor/github.com/kurin/blazer/internal/pyre/proto/pyre.pb.gw.go b/vendor/github.com/kurin/blazer/internal/pyre/proto/pyre.pb.gw.go new file mode 100644 index 000000000..f3765a28b --- /dev/null +++ b/vendor/github.com/kurin/blazer/internal/pyre/proto/pyre.pb.gw.go @@ -0,0 +1,484 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: proto/pyre.proto + +/* +Package pyre_proto is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package pyre_proto + +import ( + "io" + "net/http" + + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray + +func request_PyreService_AuthorizeAccount_0(ctx context.Context, marshaler runtime.Marshaler, client PyreServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AuthorizeAccountRequest + var metadata runtime.ServerMetadata + + msg, err := client.AuthorizeAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_PyreService_ListBuckets_0(ctx context.Context, marshaler runtime.Marshaler, client PyreServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListBucketsRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListBuckets(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_PyreService_CreateBucket_0(ctx context.Context, marshaler runtime.Marshaler, client PyreServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq Bucket + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreateBucket(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_PyreService_DeleteBucket_0(ctx context.Context, marshaler runtime.Marshaler, client PyreServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq Bucket + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.DeleteBucket(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_PyreService_GetUploadUrl_0(ctx context.Context, marshaler runtime.Marshaler, client PyreServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetUploadUrlRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetUploadUrl(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_PyreService_StartLargeFile_0(ctx context.Context, marshaler runtime.Marshaler, client PyreServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq StartLargeFileRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.StartLargeFile(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_PyreService_GetUploadPartUrl_0(ctx context.Context, marshaler runtime.Marshaler, client PyreServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetUploadPartUrlRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetUploadPartUrl(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_PyreService_FinishLargeFile_0(ctx context.Context, marshaler runtime.Marshaler, client PyreServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq FinishLargeFileRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.FinishLargeFile(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_PyreService_ListFileVersions_0(ctx context.Context, marshaler runtime.Marshaler, client PyreServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListFileVersionsRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListFileVersions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +// RegisterPyreServiceHandlerFromEndpoint is same as RegisterPyreServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterPyreServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterPyreServiceHandler(ctx, mux, conn) +} + +// RegisterPyreServiceHandler registers the http handlers for service PyreService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterPyreServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterPyreServiceHandlerClient(ctx, mux, NewPyreServiceClient(conn)) +} + +// RegisterPyreServiceHandlerClient registers the http handlers for service PyreService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "PyreServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "PyreServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "PyreServiceClient" to call the correct interceptors. +func RegisterPyreServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client PyreServiceClient) error { + + mux.Handle("GET", pattern_PyreService_AuthorizeAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_PyreService_AuthorizeAccount_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_PyreService_AuthorizeAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_PyreService_ListBuckets_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_PyreService_ListBuckets_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_PyreService_ListBuckets_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_PyreService_CreateBucket_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_PyreService_CreateBucket_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_PyreService_CreateBucket_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_PyreService_DeleteBucket_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_PyreService_DeleteBucket_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_PyreService_DeleteBucket_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_PyreService_GetUploadUrl_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_PyreService_GetUploadUrl_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_PyreService_GetUploadUrl_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_PyreService_StartLargeFile_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_PyreService_StartLargeFile_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_PyreService_StartLargeFile_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_PyreService_GetUploadPartUrl_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_PyreService_GetUploadPartUrl_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_PyreService_GetUploadPartUrl_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_PyreService_FinishLargeFile_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_PyreService_FinishLargeFile_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_PyreService_FinishLargeFile_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_PyreService_ListFileVersions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_PyreService_ListFileVersions_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_PyreService_ListFileVersions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_PyreService_AuthorizeAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"b2api", "v1", "b2_authorize_account"}, "")) + + pattern_PyreService_ListBuckets_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"b2api", "v1", "b2_list_buckets"}, "")) + + pattern_PyreService_CreateBucket_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"b2api", "v1", "b2_create_bucket"}, "")) + + pattern_PyreService_DeleteBucket_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"b2api", "v1", "b2_delete_bucket"}, "")) + + pattern_PyreService_GetUploadUrl_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"b2api", "v1", "b2_get_upload_url"}, "")) + + pattern_PyreService_StartLargeFile_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"b2api", "v1", "b2_start_large_file"}, "")) + + pattern_PyreService_GetUploadPartUrl_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"b2api", "v1", "b2_get_upload_part_url"}, "")) + + pattern_PyreService_FinishLargeFile_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"b2api", "v1", "b2_finish_large_file"}, "")) + + pattern_PyreService_ListFileVersions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"b2api", "v1", "b2_list_file_versions"}, "")) +) + +var ( + forward_PyreService_AuthorizeAccount_0 = runtime.ForwardResponseMessage + + forward_PyreService_ListBuckets_0 = runtime.ForwardResponseMessage + + forward_PyreService_CreateBucket_0 = runtime.ForwardResponseMessage + + forward_PyreService_DeleteBucket_0 = runtime.ForwardResponseMessage + + forward_PyreService_GetUploadUrl_0 = runtime.ForwardResponseMessage + + forward_PyreService_StartLargeFile_0 = runtime.ForwardResponseMessage + + forward_PyreService_GetUploadPartUrl_0 = runtime.ForwardResponseMessage + + forward_PyreService_FinishLargeFile_0 = runtime.ForwardResponseMessage + + forward_PyreService_ListFileVersions_0 = runtime.ForwardResponseMessage +) diff --git a/vendor/github.com/kurin/blazer/internal/pyre/proto/pyre.proto b/vendor/github.com/kurin/blazer/internal/pyre/proto/pyre.proto new file mode 100644 index 000000000..814481e95 --- /dev/null +++ b/vendor/github.com/kurin/blazer/internal/pyre/proto/pyre.proto @@ -0,0 +1,335 @@ +// Copyright 2018, Google +// +// 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. + +syntax = "proto3"; + +import "google/api/annotations.proto"; + +package pyre.proto; + +message AuthorizeAccountRequest {} + +message AuthorizeAccountResponse { + // The identifier for the account. + string account_id = 1; + // An authorization token to use with all calls, other than + // b2_authorize_account, that need an Authorization header. This + // authorization token is valid for at most 24 hours. + string authorization_token = 2; + // The base URL to use for all API calls except for uploading and downloading + // files. + string api_url = 3; + // The base URL to use for downloading files. + string download_url = 4; + // The recommended size for each part of a large file. We recommend using + // this part size for optimal upload performance. + int32 recommended_part_size = 5; + // The smallest possible size of a part of a large file (except the last + // one). This is smaller than the recommended part size. If you use it, you + // may find that it takes longer overall to upload a large file. + int32 absolute_minimum_part_size = 6; + int32 minimum_part_size = 7; // alias for recommended_part_size +} + +message ListBucketsRequest { + // The ID of your account. + string account_id = 1; + // When specified, the result will be a list containing just this bucket, if + // it's present in the account, or no buckets if the account does not have a + // bucket with this ID. + string bucket_id = 2; + // When specified, the result will be a list containing just this bucket, if + // it's present in the account, or no buckets if the account does not have a + // bucket with this ID. + string bucket_name = 3; + // If present, B2 will use it as a filter for bucket types returned in the + // list buckets response. If not present, only buckets with bucket types + // "allPublic", "allPrivate" and "snapshot" will be returned. A special + // filter value of ["all"] will return all bucket types. + // + // If present, it must be in the form of a json array of strings containing + // valid bucket types in quotes and separated by a comma. Valid bucket types + // include "allPrivate", "allPublic", "snapshot", and other values added in + // the future. + // + // A bad request error will be returned if "all" is used with other bucket + // types, this field is empty, or invalid bucket types are requested. + repeated string bucket_types = 4; +} + +message LifecycleRule { + // After a file is uploaded, the number of days before it can be hidden. + int32 days_from_uploading_to_hiding = 1; + // After a file is hidden, the number of days before it can be deleted. + int32 days_from_hiding_to_deleting = 2; + // The rule applies to files whose names start with this prefix. + string file_name_prefix = 3; +} + +message CorsRule { + // A name for humans to recognize the rule in a user interface. Names must be + // unique within a bucket. Names can consist of upper-case and lower-case + // English letters, numbers, and "-". No other characters are allowed. A name + // must be at least 6 characters long, and can be at most 50 characters long. + // These are all allowed names: myPhotosSite, allowAnyHttps, + // backblaze-images. Names that start with "b2-" are reserved for Backblaze + // use. + string cors_rule_name = 1; + // A non-empty list specifying which origins the rule covers. Each value may + // have one of many formats: + // + // * The origin can be fully specified, such as http://www.example.com:8180 + // or https://www.example.com:4433. + // + // * The origin can omit a default port, such as https://www.example.com. + // + // * The origin may have a single '*' as part of the domain name, such as + // https://*.example.com, https://*:8443 or https://*. + // + // * The origin may be 'https' to match any origin that uses HTTPS. (This is + // broader than 'https://*' because it matches any port.) + // + // * Finally, the origin can be a single '*' to match any origin. + // + // If any entry is "*", it must be the only entry. There can be at most one + // "https" entry and no entry after it may start with "https:". + repeated string allowed_origins = 2; + // A list specifying which operations the rule allows. At least one value + // must be specified. All values must be from the following list. More values + // may be added to this list at any time. + // + // b2_download_file_by_name + // b2_download_file_by_id + // b2_upload_file + // b2_upload_part + repeated string allowed_operations = 3; + // If present, this is a list of headers that are allowed in a pre-flight + // OPTIONS's request's Access-Control-Request-Headers header value. Each + // value may have one of many formats: + // + // * It may be a complete header name, such as x-bz-content-sha1. + // + // * It may end with an asterisk, such as x-bz-info-*. + // + // * Finally, it may be a single '*' to match any header. + // + // If any entry is "*", it must be the only entry in the list. If this list + // is missing, it is be treated as if it is a list with no entries. + repeated string allowed_headers = 4; + // If present, this is a list of headers that may be exposed to an + // application inside the client (eg. exposed to Javascript in a browser). + // Each entry in the list must be a complete header name (eg. + // "x-bz-content-sha1"). If this list is missing or empty, no headers will be + // exposed. + repeated string expose_headers = 5; + // This specifies the maximum number of seconds that a browser may cache the + // response to a preflight request. The value must not be negative and it + // must not be more than 86,400 seconds (one day). + int32 max_age_seconds = 6; +} + +message Bucket { + string account_id = 1; + string bucket_id = 2; + string bucket_name = 3; + string bucket_type = 4; + map bucket_info = 5; + repeated CorsRule cores_rules = 6; + repeated LifecycleRule lifecycle_rules = 7; + int32 revision = 8; +} + +message ListBucketsResponse { + repeated Bucket buckets = 1; +} + +message GetUploadUrlRequest { + string bucket_id = 1; +} + +message GetUploadUrlResponse { + string bucket_id = 1; + string upload_url = 2; + string authorization_token = 3; +} + +message UploadFileResponse { + string file_id = 1; + string file_name = 2; + string account_id = 3; + string bucket_id = 4; + int32 content_length = 5; + string content_sha1 = 6; + string content_type = 7; + map file_info = 8; + string action = 9; + int64 upload_timestamp = 10; +} + +message StartLargeFileRequest { + string bucket_id = 1; + string file_name = 2; + string content_type = 3; + map file_info = 4; +} + +message StartLargeFileResponse { + string file_id = 1; + string file_name = 2; + string account_id = 3; + string bucket_id = 4; + string content_type = 5; + map file_info = 6; + int64 upload_timestamp = 7; +} + +message GetUploadPartUrlRequest { + string file_id = 1; +} + +message GetUploadPartUrlResponse { + string file_id = 1; + string upload_url = 2; + string authorization_token = 3; +} + +message FinishLargeFileRequest { + string file_id = 1; + repeated string part_sha1_array = 2; + // string sha1 = 3; +} + +message FinishLargeFileResponse { + string file_id = 1; + string file_name = 2; + string account_id = 3; + string bucket_id = 4; + int64 content_length = 5; + string content_sha1 = 6; // always "none" + string content_type = 7; + map file_info = 8; + string action = 9; + int64 upload_timestamp = 10; +} + +message ListFileVersionsRequest { + string bucket_id = 1; + string start_file_name = 2; + string start_file_id = 3; + int32 max_file_count = 4; + string prefix = 5; + string delimiter = 6; +} + +message ListFileVersionsResponse { + repeated File files = 1; + string next_file_name = 2; + string next_file_id = 3; +} + +message File { + string file_id = 1; + string file_name = 2; + int64 content_length = 3; + string content_type = 4; + string content_sha1 = 5; + map file_info = 6; + string action = 7; + int64 size = 8; + int64 upload_timestamp = 9; +} + +service PyreService { + // Used to log in to the B2 API. Returns an authorization token that can be + // used for account-level operations, and a URL that should be used as the + // base URL for subsequent API calls. + rpc AuthorizeAccount(AuthorizeAccountRequest) returns (AuthorizeAccountResponse) { + option (google.api.http) = { + get: "/b2api/v1/b2_authorize_account" + }; + } + + // Lists buckets associated with an account, in alphabetical order by bucket + // name. + rpc ListBuckets(ListBucketsRequest) returns (ListBucketsResponse) { + option (google.api.http) = { + post: "/b2api/v1/b2_list_buckets" + body: "*" + }; + } + + // Creates a new bucket. A bucket belongs to the account used to create it. + // + // Buckets can be named. The name must be globally unique. No account can use + // a bucket with the same name. Buckets are assigned a unique bucketId which + // is used when uploading, downloading, or deleting files. + // + // There is a limit of 100 buckets per account. + rpc CreateBucket(Bucket) returns (Bucket) { + option (google.api.http) = { + post: "/b2api/v1/b2_create_bucket" + body: "*" + }; + } + + // Deletes the bucket specified. Only buckets that contain no version of any + // files can be deleted. + rpc DeleteBucket(Bucket) returns (Bucket) { + option (google.api.http) = { + post: "/b2api/v1/b2_delete_bucket" + body: "*" + }; + } + + rpc GetUploadUrl(GetUploadUrlRequest) returns (GetUploadUrlResponse) { + option (google.api.http) = { + post: "/b2api/v1/b2_get_upload_url" + body: "*" + }; + } + + // Prepares for uploading the parts of a large file. + rpc StartLargeFile(StartLargeFileRequest) returns (StartLargeFileResponse) { + option (google.api.http) = { + post: "/b2api/v1/b2_start_large_file" + body: "*" + }; + } + + // Gets an URL to use for uploading parts of a large file. + rpc GetUploadPartUrl(GetUploadPartUrlRequest) returns (GetUploadPartUrlResponse) { + option (google.api.http) = { + post: "/b2api/v1/b2_get_upload_part_url" + body: "*" + }; + } + + // Converts the parts that have been uploaded into a single B2 file. + rpc FinishLargeFile(FinishLargeFileRequest) returns (FinishLargeFileResponse) { + option (google.api.http) = { + post: "/b2api/v1/b2_finish_large_file" + body: "*" + }; + } + + // Lists all of the versions of all of the files contained in one bucket, in + // alphabetical order by file name, and by reverse of date/time uploaded for + // versions of files with the same name. + rpc ListFileVersions(ListFileVersionsRequest) returns (ListFileVersionsResponse) { + option (google.api.http) = { + post: "/b2api/v1/b2_list_file_versions" + body: "*" + }; + } +} diff --git a/vendor/github.com/kurin/blazer/internal/pyre/pyre.go b/vendor/github.com/kurin/blazer/internal/pyre/pyre.go new file mode 100644 index 000000000..d8f479c40 --- /dev/null +++ b/vendor/github.com/kurin/blazer/internal/pyre/pyre.go @@ -0,0 +1,20 @@ +// Copyright 2018, Google +// +// 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 pyre provides a gRPC-based implementation of B2, as well as a +// RESTful gateway on top of it. +package pyre + +//go:generate protoc -I/usr/local/include -I. -I$GOPATH/src -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --grpc-gateway_out=logtostderr=true:. proto/pyre.proto +//go:generate protoc -I/usr/local/include -I. -I$GOPATH/src -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis --go_out=plugins=grpc:. proto/pyre.proto diff --git a/vendor/github.com/kurin/blazer/internal/pyre/simple.go b/vendor/github.com/kurin/blazer/internal/pyre/simple.go new file mode 100644 index 000000000..322d9ffce --- /dev/null +++ b/vendor/github.com/kurin/blazer/internal/pyre/simple.go @@ -0,0 +1,109 @@ +// Copyright 2018, Google +// +// 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 pyre + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "strconv" + "strings" + + "github.com/google/uuid" + "github.com/kurin/blazer/internal/b2types" +) + +const uploadFilePrefix = "/b2api/v1/b2_upload_file/" + +type SimpleFileManager interface { + Writer(bucket, name, id string) (io.WriteCloser, error) +} + +type simpleFileServer struct { + fm SimpleFileManager +} + +type uploadRequest struct { + name string + contentType string + size int64 + sha1 string + bucket string + info map[string]string +} + +func parseUploadHeaders(r *http.Request) (*uploadRequest, error) { + ur := &uploadRequest{info: make(map[string]string)} + ur.name = r.Header.Get("X-Bz-File-Name") + ur.contentType = r.Header.Get("Content-Type") + ur.sha1 = r.Header.Get("X-Bz-Content-Sha1") + size, err := strconv.ParseInt(r.Header.Get("Content-Length"), 10, 64) + if err != nil { + return nil, err + } + ur.size = size + for k := range r.Header { + if !strings.HasPrefix("X-Bz-Info-", k) { + continue + } + name := strings.TrimPrefix("X-Bz-Info-", k) + ur.info[name] = r.Header.Get(k) + } + ur.bucket = strings.TrimPrefix(r.URL.Path, uploadFilePrefix) + return ur, nil +} + +func (fs *simpleFileServer) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + req, err := parseUploadHeaders(r) + if err != nil { + http.Error(rw, err.Error(), 500) + fmt.Println("oh no") + return + } + id := uuid.New().String() + w, err := fs.fm.Writer(req.bucket, req.name, id) + if err != nil { + http.Error(rw, err.Error(), 500) + fmt.Println("oh no") + return + } + if _, err := io.Copy(w, io.LimitReader(r.Body, req.size)); err != nil { + w.Close() + http.Error(rw, err.Error(), 500) + fmt.Println("oh no") + return + } + if err := w.Close(); err != nil { + http.Error(rw, err.Error(), 500) + fmt.Println("oh no") + return + } + resp := &b2types.UploadFileResponse{ + FileID: id, + Name: req.name, + SHA1: req.sha1, + BucketID: req.bucket, + } + if err := json.NewEncoder(rw).Encode(resp); err != nil { + http.Error(rw, err.Error(), 500) + fmt.Println("oh no") + return + } +} + +func RegisterSimpleFileManagerOnMux(f SimpleFileManager, mux *http.ServeMux) { + mux.Handle(uploadFilePrefix, &simpleFileServer{fm: f}) +} diff --git a/vendor/github.com/kurin/blazer/x/consistent/consistent_test.go b/vendor/github.com/kurin/blazer/x/consistent/consistent_test.go index 0a94df72a..934317de6 100644 --- a/vendor/github.com/kurin/blazer/x/consistent/consistent_test.go +++ b/vendor/github.com/kurin/blazer/x/consistent/consistent_test.go @@ -30,9 +30,9 @@ func TestOperationLive(t *testing.T) { wg.Add(1) i := i go func() { - var n int defer wg.Done() for j := 0; j < 10; j++ { + var n int if err := g.Operate(ctx, name, func(b []byte) ([]byte, error) { if len(b) > 0 { i, err := strconv.Atoi(string(b)) From 6e2e957332ac5e725c5d0e2a648aae9655418230 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 22 Jul 2018 14:16:08 +0200 Subject: [PATCH 2/2] Add entry to changelog --- changelog/unreleased/pull-1901 | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 changelog/unreleased/pull-1901 diff --git a/changelog/unreleased/pull-1901 b/changelog/unreleased/pull-1901 new file mode 100644 index 000000000..7d9569d17 --- /dev/null +++ b/changelog/unreleased/pull-1901 @@ -0,0 +1,9 @@ +Enhancement: Update the Backblaze B2 library + +We've updated the library we're using for accessing the Backblaze B2 service to +0.5.0 to include support for upcoming so-called "application keys". With this +feature, you can create access credentials for B2 which are restricted to e.g. +a single bucket or even a sub-directory of a bucket. + +https://github.com/restic/restic/pull/1901 +https://github.com/kurin/blazer