blob: f9b5b728049f72411fe5fa6f67d8e5d8fdca4947 [file]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package logstore
import (
"compress/gzip"
"context"
"crypto/sha256"
"encoding/base64"
"fmt"
"io"
"path"
"cloud.google.com/go/storage"
"google.golang.org/appengine/file"
)
// Upload uploads data to logstore and returns logPath.
// data will be compressed.
func Upload(ctx context.Context, prefix string, data []byte) (_ string, rerr error) {
closeCloser := func(c io.Closer) {
err := c.Close()
if rerr == nil {
rerr = err
}
}
client, err := storage.NewClient(ctx)
if err != nil {
return "", fmt.Errorf("failed to create storage client: %v", err)
}
defer closeCloser(client)
bkt, err := file.DefaultBucketName(ctx)
if err != nil {
return "", fmt.Errorf("failed to get DefaultBucketName: %v", err)
}
hd := sha256.Sum256(data)
h := base64.URLEncoding.EncodeToString(hd[:])
logPath := path.Join("upload", fmt.Sprintf("%s.%s.gz", prefix, h))
w := client.Bucket(bkt).Object(logPath).NewWriter(ctx)
defer closeCloser(w)
// no need to set content-encoding?
// with this, uploaded file get error "gzip: invalid header".
// https://bugs.chromium.org/p/chromium/issues/detail?id=1007149
// w.ContentEncoding = "gzip"
gw := gzip.NewWriter(w)
defer closeCloser(gw)
_, err = gw.Write(data)
if err != nil {
return "", fmt.Errorf("failed to write data: %v", err)
}
return logPath, nil
}