Beispiel #1
0
func (this *GCSImageStore) Exists(obj *StoreObject) (bool, error) {
	_, err := storage.StatObject(this.ctx, this.bucketName, this.toPath(obj))
	if err != nil {
		return false, err
	}
	return true, nil
}
Beispiel #2
0
func (c *GoogleStorage) Exists(name string) (bool, error) {
	_, err := storage.StatObject(c.ctx, c.bucket, name)
	if err != nil {
		return false, err
	}
	return true, nil
}
Beispiel #3
0
// alreadyUploaded reports whether *file has already been uploaded and the correct contents
// are on cloud storage already.
func alreadyUploaded(ctx context.Context, bucket, object string) bool {
	if *file == "-" {
		return false // don't know.
	}
	o, err := storage.StatObject(ctx, bucket, object)
	if err == storage.ErrObjectNotExist {
		return false
	}
	if err != nil {
		log.Printf("Warning: stat failure: %v", err)
		return false
	}
	m5 := md5.New()
	fi, err := os.Stat(*file)
	if err != nil {
		log.Fatal(err)
	}
	if fi.Size() != o.Size {
		return false
	}
	f, err := os.Open(*file)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	n, err := io.Copy(m5, f)
	if err != nil {
		log.Fatal(err)
	}
	if n != fi.Size() {
		log.Printf("Warning: file size of %v changed", *file)
	}
	return bytes.Equal(m5.Sum(nil), o.MD5)
}
Beispiel #4
0
// Stat implements part of the VFS interface.
func (s FS) Stat(ctx context.Context, path string) (os.FileInfo, error) {
	obj, err := storage.StatObject(ctx, s.Bucket, path)
	if err != nil {
		return nil, err
	}
	return objInfo{obj}, os.ErrNotExist
}
Beispiel #5
0
func getFileLink(ctx context.Context, name string) (string, error) {
	cctx := getCloudContext(ctx)
	obj, err := storage.StatObject(cctx, bucketName, name)
	if err != nil {
		return "", err
	}
	return obj.MediaLink, nil
}
Beispiel #6
0
func storageStatObject(context context.Context, bucket string, name string) (*storage.Object, error) {
	var obj *storage.Object
	err := retry(5, func() error {
		var err error
		obj, err = storage.StatObject(context, bucket, name)
		return err
	})
	return obj, err
}
Beispiel #7
0
// statFile reads the stats of the named file in Google Cloud Storage.
func (d *demo) statFile(fileName string) {
	io.WriteString(d.w, "\nFile stat:\n")

	obj, err := storage.StatObject(d.ctx, bucket, fileName)
	if err != nil {
		d.errorf("statFile: unable to stat file from bucket %q, file %q: %v", bucket, fileName, err)
		return
	}

	d.dumpStats(obj)
}
Beispiel #8
0
func (bs *GCSBlobStore) BlobSize(blobpath string) (int64, error) {
	ctx := bs.newAuthedContext(context.TODO())

	obj, err := storage.StatObject(ctx, bs.bucketName, blobpath)
	if err != nil {
		if err == storage.ErrObjectNotExist {
			return -1, blobstore.ENOENT
		}
		return -1, err
	}

	return obj.Size, nil
}
Beispiel #9
0
func (c *GoogleStorage) Mirror(obj *Object) (*Object, error) {
	gcsObj, err := storage.StatObject(c.ctx, c.bucket, obj.Path)
	if err != nil {
		return c.Post(obj)
	}

	newPath := c.bucket + "/" + gcsObj.Name
	newUrl := "https://storage.googleapis.com/" + newPath
	newObj := &Object{
		Filename: obj.Filename,
		Bucket:   c.bucket,
		Path:     newPath,
		MimeType: gcsObj.ContentType,
		Url:      newUrl,
	}
	return newObj, nil
}
Beispiel #10
0
// ReadStream retrieves an io.ReadCloser for the content stored at "path"
// with a given byte offset.
// May be used to resume reading a stream by providing a nonzero offset.
func (d *driver) ReadStream(context ctx.Context, path string, offset int64) (io.ReadCloser, error) {
	name := d.pathToKey(path)

	// copied from google.golang.org/cloud/storage#NewReader :
	// to set the additional "Range" header
	u := &url.URL{
		Scheme: "https",
		Host:   "storage.googleapis.com",
		Path:   fmt.Sprintf("/%s/%s", d.bucket, name),
	}
	req, err := http.NewRequest("GET", u.String(), nil)
	if err != nil {
		return nil, err
	}
	if offset > 0 {
		req.Header.Set("Range", fmt.Sprintf("bytes=%v-", offset))
	}
	res, err := d.client.Do(req)
	if err != nil {
		return nil, err
	}
	if res.StatusCode == http.StatusNotFound {
		res.Body.Close()
		return nil, storagedriver.PathNotFoundError{Path: path}
	}
	if res.StatusCode == http.StatusRequestedRangeNotSatisfiable {
		res.Body.Close()
		obj, err := storage.StatObject(d.context(context), d.bucket, name)
		if err != nil {
			return nil, err
		}
		if offset == int64(obj.Size) {
			return ioutil.NopCloser(bytes.NewReader([]byte{})), nil
		}
		return nil, storagedriver.InvalidOffsetError{Path: path, Offset: offset}
	}
	if res.StatusCode < 200 || res.StatusCode > 299 {
		res.Body.Close()
		return nil, fmt.Errorf("storage: can't read object %v/%v, status code: %v", d.bucket, name, res.Status)
	}
	return res.Body, nil
}
Beispiel #11
0
// Delete removes an object by name from the bucket being used. If the object does not
// exist and there is nothing to delete, Delete returns with no error.
// TODO Delete thumbnail and web view copies too!
func Delete(filename string, r *http.Request) error {
	c := appengine.NewContext(r)
	bucket, err := file.DefaultBucketName(c)
	if err != nil {
		log.Errorf(c, "Failed to get default bucket: %v", err)
		return err
	}

	ctx, err := auth(r)
	if err != nil {
		log.Errorf(c, "Failed to get context: %v", err)
		return err
	}

	log.Infof(c, "Attempting to delete file %v from bucket %v.", filename, bucket)

	// StatObject is used here to check existence before calling DeleteObject.
	// If the object does not exist, DeleteObject returns an error that is NOT
	// ErrObjectNotExist, so it seemed more reliable to check with StatObject first...
	_, err = storage.StatObject(ctx, bucket, filename)
	if err == storage.ErrObjectNotExist {
		log.Warningf(c, "Object does not exist, nothing to delete.")
		return nil
	}

	err = storage.DeleteObject(ctx, bucket, filename)
	if err != nil {
		log.Errorf(c, "Failed to delete file.")

		log.Infof(c, "Attempting to remove public access to file...")
		aclErr := storage.DeleteACLRule(ctx, bucket, filename, storage.AllUsers)
		if aclErr != nil {
			log.Errorf(c, "Failed to remove public file access!")
		} else {
			log.Infof(c, "File access removed.")
		}

		return err
	}

	return nil
}
Beispiel #12
0
// Stat retrieves the FileInfo for the given path, including the current
// size in bytes and the creation time.
func (d *driver) Stat(context ctx.Context, path string) (storagedriver.FileInfo, error) {
	var fi storagedriver.FileInfoFields
	//try to get as file
	gcsContext := d.context(context)
	obj, err := storage.StatObject(gcsContext, d.bucket, d.pathToKey(path))
	if err == nil {
		fi = storagedriver.FileInfoFields{
			Path:    path,
			Size:    obj.Size,
			ModTime: obj.Updated,
			IsDir:   false,
		}
		return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
	}
	//try to get as folder
	dirpath := d.pathToDirKey(path)

	var query *storage.Query
	query = &storage.Query{}
	query.Prefix = dirpath
	query.MaxResults = 1

	objects, err := storage.ListObjects(gcsContext, d.bucket, query)
	if err != nil {
		return nil, err
	}
	if len(objects.Results) < 1 {
		return nil, storagedriver.PathNotFoundError{Path: path}
	}
	fi = storagedriver.FileInfoFields{
		Path:  path,
		IsDir: true,
	}
	obj = objects.Results[0]
	if obj.Name == dirpath {
		fi.Size = obj.Size
		fi.ModTime = obj.Updated
	}
	return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
}
Beispiel #13
0
func FileStats(filename string, r *http.Request) (*storage.Object, error) {
	c := appengine.NewContext(r)
	bucket, err := file.DefaultBucketName(c)
	if err != nil {
		log.Errorf(c, "Failed to get default bucket: %v", err)
		return nil, err
	}

	ctx, err := auth(r)
	if err != nil {
		log.Errorf(c, "Failed to get context: %v", err)
		return nil, err
	}

	log.Infof(c, "Getting stats for file %v from bucket %v.", filename, bucket)

	obj, err := storage.StatObject(ctx, bucket, filename)
	if err != nil {
		log.Errorf(c, "Failed to stat file: %v", err)
		return nil, err
	}

	return obj, nil
}
Beispiel #14
0
func handleUploadImage(c appengine.Context, w http.ResponseWriter, r *http.Request) {
	file, fileHeader, err := r.FormFile(uploadImageKey)
	if err != nil {
		c.Infof("Failed to get uploaded image: %v", err)
		http.Error(w, "Failed to get uploaded image", http.StatusBadRequest)
		return
	}
	defer file.Close()
	data, err := ioutil.ReadAll(file)
	if err != nil {
		c.Errorf("Failed to read uploaded image: %v", err)
		http.Error(w, "Failed to get uploaded image", http.StatusBadRequest)
		return
	}
	ext := path.Ext(fileHeader.Filename)
	mimeType := mime.TypeByExtension(ext)

	// create context for Google Cloud Storage and upload file
	gc := gappengine.NewContext(r)
	hc := &http.Client{
		Transport: &oauth2.Transport{
			Source: google.AppEngineTokenSource(gc, storage.ScopeFullControl),
			Base:   &urlfetch.Transport{Context: gc},
		},
	}
	ctx := cloud.NewContext(gappengine.AppID(gc), hc)
	c.Infof("Demo GCS Application running from Version: %v\n", appengine.VersionID(c))

	filePath := path.Join(tempImagePath, createTempImagePath, fileHeader.Filename)
	c.Infof("file: %v, size: %d, MIME: %v, path: %v", fileHeader.Filename, len(data), mimeType, filePath)
	wc := storage.NewWriter(ctx, bucketName, filePath)
	wc.ContentType = mimeType
	_, err = wc.Write(data)
	if err != nil {
		c.Errorf("Failed to upload image: %v", err)
		http.Error(w, "Failed to upload image", http.StatusInternalServerError)
		return
	}
	err = wc.Close()
	if err != nil {
		c.Errorf("Failed to close uploaded image: %v", err)
		http.Error(w, "Failed to upload image", http.StatusInternalServerError)
		return
	}
	obj, err := storage.StatObject(ctx, bucketName, filePath)
	if err != nil {
		c.Errorf("Failed to stat object: %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	// c.Infof("obj: %v", obj)
	// get blob key for GCS file
	// obj := wc.Object()
	objName := path.Join("/gs", bucketName, obj.Name)
	c.Infof("Getting blob key from path: %v", objName)
	imgKey, err := blobstore.BlobKeyForFile(c, objName)
	if err != nil {
		c.Errorf("Failed to get image blob key: %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	url, err := getImageUrl(c, imgKey)
	if err != nil {
		c.Errorf("Failed to get room image url: %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	info := ImageInfo{
		Key: imgKey,
		Url: url.String(),
	}
	outBuf, err := json.Marshal(&info)
	if err != nil {
		c.Errorf("%s", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	_, err = w.Write(outBuf)
	if err != nil {
		c.Errorf("%s", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}