...

Source file src/cloud.google.com/go/storage/example_test.go

Documentation: cloud.google.com/go/storage

     1  // Copyright 2014 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package storage_test
    16  
    17  import (
    18  	"bytes"
    19  	"context"
    20  	"fmt"
    21  	"hash/crc32"
    22  	"io"
    23  	"io/ioutil"
    24  	"log"
    25  	"mime/multipart"
    26  	"net/http"
    27  	"os"
    28  	"time"
    29  
    30  	"cloud.google.com/go/storage"
    31  	"google.golang.org/api/googleapi"
    32  	"google.golang.org/api/iterator"
    33  	"google.golang.org/api/option"
    34  )
    35  
    36  func ExampleNewClient() {
    37  	ctx := context.Background()
    38  	// Use Google Application Default Credentials to authorize and authenticate the client.
    39  	// More information about Application Default Credentials and how to enable is at
    40  	// https://developers.google.com/identity/protocols/application-default-credentials.
    41  	client, err := storage.NewClient(ctx)
    42  	if err != nil {
    43  		// TODO: handle error.
    44  	}
    45  	// Use the client.
    46  
    47  	// Close the client when finished.
    48  	if err := client.Close(); err != nil {
    49  		// TODO: handle error.
    50  	}
    51  }
    52  
    53  // This example shows how to create an unauthenticated client, which
    54  // can be used to access public data.
    55  func ExampleNewClient_unauthenticated() {
    56  	ctx := context.Background()
    57  	client, err := storage.NewClient(ctx, option.WithoutAuthentication())
    58  	if err != nil {
    59  		// TODO: handle error.
    60  	}
    61  	// Use the client.
    62  
    63  	// Close the client when finished.
    64  	if err := client.Close(); err != nil {
    65  		// TODO: handle error.
    66  	}
    67  }
    68  
    69  func ExampleBucketHandle_Create() {
    70  	ctx := context.Background()
    71  	client, err := storage.NewClient(ctx)
    72  	if err != nil {
    73  		// TODO: handle error.
    74  	}
    75  	if err := client.Bucket("my-bucket").Create(ctx, "my-project", nil); err != nil {
    76  		// TODO: handle error.
    77  	}
    78  }
    79  
    80  func ExampleBucketHandle_Delete() {
    81  	ctx := context.Background()
    82  	client, err := storage.NewClient(ctx)
    83  	if err != nil {
    84  		// TODO: handle error.
    85  	}
    86  	if err := client.Bucket("my-bucket").Delete(ctx); err != nil {
    87  		// TODO: handle error.
    88  	}
    89  }
    90  
    91  func ExampleBucketHandle_Attrs() {
    92  	ctx := context.Background()
    93  	client, err := storage.NewClient(ctx)
    94  	if err != nil {
    95  		// TODO: handle error.
    96  	}
    97  	attrs, err := client.Bucket("my-bucket").Attrs(ctx)
    98  	if err != nil {
    99  		// TODO: handle error.
   100  	}
   101  	fmt.Println(attrs)
   102  }
   103  
   104  func ExampleBucketHandle_Update() {
   105  	ctx := context.Background()
   106  	client, err := storage.NewClient(ctx)
   107  	if err != nil {
   108  		// TODO: handle error.
   109  	}
   110  	// Enable versioning in the bucket, regardless of its previous value.
   111  	attrs, err := client.Bucket("my-bucket").Update(ctx,
   112  		storage.BucketAttrsToUpdate{VersioningEnabled: true})
   113  	if err != nil {
   114  		// TODO: handle error.
   115  	}
   116  	fmt.Println(attrs)
   117  }
   118  
   119  // If your update is based on the bucket's previous attributes, match the
   120  // metageneration number to make sure the bucket hasn't changed since you read it.
   121  func ExampleBucketHandle_Update_readModifyWrite() {
   122  	ctx := context.Background()
   123  	client, err := storage.NewClient(ctx)
   124  	if err != nil {
   125  		// TODO: handle error.
   126  	}
   127  	b := client.Bucket("my-bucket")
   128  	attrs, err := b.Attrs(ctx)
   129  	if err != nil {
   130  		// TODO: handle error.
   131  	}
   132  	var au storage.BucketAttrsToUpdate
   133  	au.SetLabel("lab", attrs.Labels["lab"]+"-more")
   134  	if attrs.Labels["delete-me"] == "yes" {
   135  		au.DeleteLabel("delete-me")
   136  	}
   137  	attrs, err = b.
   138  		If(storage.BucketConditions{MetagenerationMatch: attrs.MetaGeneration}).
   139  		Update(ctx, au)
   140  	if err != nil {
   141  		// TODO: handle error.
   142  	}
   143  	fmt.Println(attrs)
   144  }
   145  
   146  func ExampleClient_Buckets() {
   147  	ctx := context.Background()
   148  	client, err := storage.NewClient(ctx)
   149  	if err != nil {
   150  		// TODO: handle error.
   151  	}
   152  	it := client.Buckets(ctx, "my-project")
   153  	_ = it // TODO: iterate using Next or iterator.Pager.
   154  }
   155  
   156  func ExampleBucketIterator_Next() {
   157  	ctx := context.Background()
   158  	client, err := storage.NewClient(ctx)
   159  	if err != nil {
   160  		// TODO: handle error.
   161  	}
   162  	it := client.Buckets(ctx, "my-project")
   163  	for {
   164  		bucketAttrs, err := it.Next()
   165  		if err == iterator.Done {
   166  			break
   167  		}
   168  		if err != nil {
   169  			// TODO: Handle error.
   170  		}
   171  		fmt.Println(bucketAttrs)
   172  	}
   173  }
   174  
   175  func ExampleBucketHandle_Objects() {
   176  	ctx := context.Background()
   177  	client, err := storage.NewClient(ctx)
   178  	if err != nil {
   179  		// TODO: handle error.
   180  	}
   181  	it := client.Bucket("my-bucket").Objects(ctx, nil)
   182  	_ = it // TODO: iterate using Next or iterator.Pager.
   183  }
   184  
   185  func ExampleBucketHandle_AddNotification() {
   186  	ctx := context.Background()
   187  	client, err := storage.NewClient(ctx)
   188  	if err != nil {
   189  		// TODO: handle error.
   190  	}
   191  	b := client.Bucket("my-bucket")
   192  	n, err := b.AddNotification(ctx, &storage.Notification{
   193  		TopicProjectID: "my-project",
   194  		TopicID:        "my-topic",
   195  		PayloadFormat:  storage.JSONPayload,
   196  	})
   197  	if err != nil {
   198  		// TODO: handle error.
   199  	}
   200  	fmt.Println(n.ID)
   201  }
   202  
   203  func ExampleBucketHandle_LockRetentionPolicy() {
   204  	ctx := context.Background()
   205  	client, err := storage.NewClient(ctx)
   206  	if err != nil {
   207  		// TODO: handle error.
   208  	}
   209  	b := client.Bucket("my-bucket")
   210  	attrs, err := b.Attrs(ctx)
   211  	if err != nil {
   212  		// TODO: handle error.
   213  	}
   214  	// Note that locking the bucket without first attaching a RetentionPolicy
   215  	// that's at least 1 day is a no-op
   216  	err = b.If(storage.BucketConditions{MetagenerationMatch: attrs.MetaGeneration}).LockRetentionPolicy(ctx)
   217  	if err != nil {
   218  		// TODO: handle err
   219  	}
   220  }
   221  
   222  func ExampleBucketHandle_Notifications() {
   223  	ctx := context.Background()
   224  	client, err := storage.NewClient(ctx)
   225  	if err != nil {
   226  		// TODO: handle error.
   227  	}
   228  	b := client.Bucket("my-bucket")
   229  	ns, err := b.Notifications(ctx)
   230  	if err != nil {
   231  		// TODO: handle error.
   232  	}
   233  	for id, n := range ns {
   234  		fmt.Printf("%s: %+v\n", id, n)
   235  	}
   236  }
   237  
   238  var notificationID string
   239  
   240  func ExampleBucketHandle_DeleteNotification() {
   241  	ctx := context.Background()
   242  	client, err := storage.NewClient(ctx)
   243  	if err != nil {
   244  		// TODO: handle error.
   245  	}
   246  	b := client.Bucket("my-bucket")
   247  	// TODO: Obtain notificationID from BucketHandle.AddNotification
   248  	// or BucketHandle.Notifications.
   249  	err = b.DeleteNotification(ctx, notificationID)
   250  	if err != nil {
   251  		// TODO: handle error.
   252  	}
   253  }
   254  
   255  func ExampleObjectIterator_Next() {
   256  	ctx := context.Background()
   257  	client, err := storage.NewClient(ctx)
   258  	if err != nil {
   259  		// TODO: handle error.
   260  	}
   261  	it := client.Bucket("my-bucket").Objects(ctx, nil)
   262  	for {
   263  		objAttrs, err := it.Next()
   264  		if err == iterator.Done {
   265  			break
   266  		}
   267  		if err != nil {
   268  			// TODO: Handle error.
   269  		}
   270  		fmt.Println(objAttrs)
   271  	}
   272  }
   273  
   274  func ExampleSignedURL() {
   275  	pkey, err := ioutil.ReadFile("my-private-key.pem")
   276  	if err != nil {
   277  		// TODO: handle error.
   278  	}
   279  	url, err := storage.SignedURL("my-bucket", "my-object", &storage.SignedURLOptions{
   280  		GoogleAccessID: "xxx@developer.gserviceaccount.com",
   281  		PrivateKey:     pkey,
   282  		Method:         "GET",
   283  		Expires:        time.Now().Add(48 * time.Hour),
   284  	})
   285  	if err != nil {
   286  		// TODO: handle error.
   287  	}
   288  	fmt.Println(url)
   289  }
   290  
   291  func ExampleObjectHandle_Attrs() {
   292  	ctx := context.Background()
   293  	client, err := storage.NewClient(ctx)
   294  	if err != nil {
   295  		// TODO: handle error.
   296  	}
   297  	objAttrs, err := client.Bucket("my-bucket").Object("my-object").Attrs(ctx)
   298  	if err != nil {
   299  		// TODO: handle error.
   300  	}
   301  	fmt.Println(objAttrs)
   302  }
   303  
   304  func ExampleObjectHandle_Attrs_withConditions() {
   305  	ctx := context.Background()
   306  	client, err := storage.NewClient(ctx)
   307  	if err != nil {
   308  		// TODO: handle error.
   309  	}
   310  	obj := client.Bucket("my-bucket").Object("my-object")
   311  	// Read the object.
   312  	objAttrs1, err := obj.Attrs(ctx)
   313  	if err != nil {
   314  		// TODO: handle error.
   315  	}
   316  	// Do something else for a while.
   317  	time.Sleep(5 * time.Minute)
   318  	// Now read the same contents, even if the object has been written since the last read.
   319  	objAttrs2, err := obj.Generation(objAttrs1.Generation).Attrs(ctx)
   320  	if err != nil {
   321  		// TODO: handle error.
   322  	}
   323  	fmt.Println(objAttrs1, objAttrs2)
   324  }
   325  
   326  func ExampleObjectHandle_Update() {
   327  	ctx := context.Background()
   328  	client, err := storage.NewClient(ctx)
   329  	if err != nil {
   330  		// TODO: handle error.
   331  	}
   332  	// Change only the content type of the object.
   333  	objAttrs, err := client.Bucket("my-bucket").Object("my-object").Update(ctx, storage.ObjectAttrsToUpdate{
   334  		ContentType:        "text/html",
   335  		ContentDisposition: "", // delete ContentDisposition
   336  	})
   337  	if err != nil {
   338  		// TODO: handle error.
   339  	}
   340  	fmt.Println(objAttrs)
   341  }
   342  
   343  func ExampleObjectHandle_NewReader() {
   344  	ctx := context.Background()
   345  	client, err := storage.NewClient(ctx)
   346  	if err != nil {
   347  		// TODO: handle error.
   348  	}
   349  	rc, err := client.Bucket("my-bucket").Object("my-object").NewReader(ctx)
   350  	if err != nil {
   351  		// TODO: handle error.
   352  	}
   353  	slurp, err := ioutil.ReadAll(rc)
   354  	rc.Close()
   355  	if err != nil {
   356  		// TODO: handle error.
   357  	}
   358  	fmt.Println("file contents:", slurp)
   359  }
   360  
   361  func ExampleObjectHandle_NewRangeReader() {
   362  	ctx := context.Background()
   363  	client, err := storage.NewClient(ctx)
   364  	if err != nil {
   365  		// TODO: handle error.
   366  	}
   367  	// Read only the first 64K.
   368  	rc, err := client.Bucket("bucketname").Object("filename1").NewRangeReader(ctx, 0, 64*1024)
   369  	if err != nil {
   370  		// TODO: handle error.
   371  	}
   372  	defer rc.Close()
   373  
   374  	slurp, err := ioutil.ReadAll(rc)
   375  	if err != nil {
   376  		// TODO: handle error.
   377  	}
   378  	fmt.Printf("first 64K of file contents:\n%s\n", slurp)
   379  }
   380  
   381  func ExampleObjectHandle_NewRangeReader_lastNBytes() {
   382  	ctx := context.Background()
   383  	client, err := storage.NewClient(ctx)
   384  	if err != nil {
   385  		// TODO: handle error.
   386  	}
   387  	// Read only the last 10 bytes until the end of the file.
   388  	rc, err := client.Bucket("bucketname").Object("filename1").NewRangeReader(ctx, -10, -1)
   389  	if err != nil {
   390  		// TODO: handle error.
   391  	}
   392  	defer rc.Close()
   393  
   394  	slurp, err := ioutil.ReadAll(rc)
   395  	if err != nil {
   396  		// TODO: handle error.
   397  	}
   398  	fmt.Printf("Last 10 bytes from the end of the file:\n%s\n", slurp)
   399  }
   400  
   401  func ExampleObjectHandle_NewRangeReader_untilEnd() {
   402  	ctx := context.Background()
   403  	client, err := storage.NewClient(ctx)
   404  	if err != nil {
   405  		// TODO: handle error.
   406  	}
   407  	// Read from the 101st byte until the end of the file.
   408  	rc, err := client.Bucket("bucketname").Object("filename1").NewRangeReader(ctx, 100, -1)
   409  	if err != nil {
   410  		// TODO: handle error.
   411  	}
   412  	defer rc.Close()
   413  
   414  	slurp, err := ioutil.ReadAll(rc)
   415  	if err != nil {
   416  		// TODO: handle error.
   417  	}
   418  	fmt.Printf("From 101st byte until the end:\n%s\n", slurp)
   419  }
   420  
   421  func ExampleObjectHandle_NewWriter() {
   422  	ctx := context.Background()
   423  	client, err := storage.NewClient(ctx)
   424  	if err != nil {
   425  		// TODO: handle error.
   426  	}
   427  	wc := client.Bucket("bucketname").Object("filename1").NewWriter(ctx)
   428  	_ = wc // TODO: Use the Writer.
   429  }
   430  
   431  func ExampleWriter_Write() {
   432  	ctx := context.Background()
   433  	client, err := storage.NewClient(ctx)
   434  	if err != nil {
   435  		// TODO: handle error.
   436  	}
   437  	wc := client.Bucket("bucketname").Object("filename1").NewWriter(ctx)
   438  	wc.ContentType = "text/plain"
   439  	wc.ACL = []storage.ACLRule{{Entity: storage.AllUsers, Role: storage.RoleReader}}
   440  	if _, err := wc.Write([]byte("hello world")); err != nil {
   441  		// TODO: handle error.
   442  		// Note that Write may return nil in some error situations,
   443  		// so always check the error from Close.
   444  	}
   445  	if err := wc.Close(); err != nil {
   446  		// TODO: handle error.
   447  	}
   448  	fmt.Println("updated object:", wc.Attrs())
   449  }
   450  
   451  // To limit the time to write an object (or do anything else
   452  // that takes a context), use context.WithTimeout.
   453  func ExampleWriter_Write_timeout() {
   454  	ctx := context.Background()
   455  	client, err := storage.NewClient(ctx)
   456  	if err != nil {
   457  		// TODO: handle error.
   458  	}
   459  	tctx, cancel := context.WithTimeout(ctx, 30*time.Second)
   460  	defer cancel() // Cancel when done, whether we time out or not.
   461  	wc := client.Bucket("bucketname").Object("filename1").NewWriter(tctx)
   462  	wc.ContentType = "text/plain"
   463  	wc.ACL = []storage.ACLRule{{Entity: storage.AllUsers, Role: storage.RoleReader}}
   464  	if _, err := wc.Write([]byte("hello world")); err != nil {
   465  		// TODO: handle error.
   466  		// Note that Write may return nil in some error situations,
   467  		// so always check the error from Close.
   468  	}
   469  	if err := wc.Close(); err != nil {
   470  		// TODO: handle error.
   471  	}
   472  	fmt.Println("updated object:", wc.Attrs())
   473  }
   474  
   475  // To make sure the data you write is uncorrupted, use an MD5 or CRC32c
   476  // checksum. This example illustrates CRC32c.
   477  func ExampleWriter_Write_checksum() {
   478  	ctx := context.Background()
   479  	client, err := storage.NewClient(ctx)
   480  	if err != nil {
   481  		// TODO: handle error.
   482  	}
   483  	data := []byte("verify me")
   484  	wc := client.Bucket("bucketname").Object("filename1").NewWriter(ctx)
   485  	wc.CRC32C = crc32.Checksum(data, crc32.MakeTable(crc32.Castagnoli))
   486  	wc.SendCRC32C = true
   487  	if _, err := wc.Write([]byte("hello world")); err != nil {
   488  		// TODO: handle error.
   489  		// Note that Write may return nil in some error situations,
   490  		// so always check the error from Close.
   491  	}
   492  	if err := wc.Close(); err != nil {
   493  		// TODO: handle error.
   494  	}
   495  	fmt.Println("updated object:", wc.Attrs())
   496  }
   497  
   498  func ExampleObjectHandle_Delete() {
   499  	ctx := context.Background()
   500  	client, err := storage.NewClient(ctx)
   501  	if err != nil {
   502  		// TODO: handle error.
   503  	}
   504  	// To delete multiple objects in a bucket, list them with an
   505  	// ObjectIterator, then Delete them.
   506  
   507  	// If you are using this package on the App Engine Flex runtime,
   508  	// you can init a bucket client with your app's default bucket name.
   509  	// See http://godoc.org/google.golang.org/appengine/file#DefaultBucketName.
   510  	bucket := client.Bucket("my-bucket")
   511  	it := bucket.Objects(ctx, nil)
   512  	for {
   513  		objAttrs, err := it.Next()
   514  		if err != nil && err != iterator.Done {
   515  			// TODO: Handle error.
   516  		}
   517  		if err == iterator.Done {
   518  			break
   519  		}
   520  		if err := bucket.Object(objAttrs.Name).Delete(ctx); err != nil {
   521  			// TODO: Handle error.
   522  		}
   523  	}
   524  	fmt.Println("deleted all object items in the bucket specified.")
   525  }
   526  
   527  func ExampleACLHandle_Delete() {
   528  	ctx := context.Background()
   529  	client, err := storage.NewClient(ctx)
   530  	if err != nil {
   531  		// TODO: handle error.
   532  	}
   533  	// No longer grant access to the bucket to everyone on the Internet.
   534  	if err := client.Bucket("my-bucket").ACL().Delete(ctx, storage.AllUsers); err != nil {
   535  		// TODO: handle error.
   536  	}
   537  }
   538  
   539  func ExampleACLHandle_Set() {
   540  	ctx := context.Background()
   541  	client, err := storage.NewClient(ctx)
   542  	if err != nil {
   543  		// TODO: handle error.
   544  	}
   545  	// Let any authenticated user read my-bucket/my-object.
   546  	obj := client.Bucket("my-bucket").Object("my-object")
   547  	if err := obj.ACL().Set(ctx, storage.AllAuthenticatedUsers, storage.RoleReader); err != nil {
   548  		// TODO: handle error.
   549  	}
   550  }
   551  
   552  func ExampleACLHandle_List() {
   553  	ctx := context.Background()
   554  	client, err := storage.NewClient(ctx)
   555  	if err != nil {
   556  		// TODO: handle error.
   557  	}
   558  	// List the default object ACLs for my-bucket.
   559  	aclRules, err := client.Bucket("my-bucket").DefaultObjectACL().List(ctx)
   560  	if err != nil {
   561  		// TODO: handle error.
   562  	}
   563  	fmt.Println(aclRules)
   564  }
   565  
   566  func ExampleCopier_Run() {
   567  	ctx := context.Background()
   568  	client, err := storage.NewClient(ctx)
   569  	if err != nil {
   570  		// TODO: handle error.
   571  	}
   572  	src := client.Bucket("bucketname").Object("file1")
   573  	dst := client.Bucket("another-bucketname").Object("file2")
   574  
   575  	// Copy content and modify metadata.
   576  	copier := dst.CopierFrom(src)
   577  	copier.ContentType = "text/plain"
   578  	attrs, err := copier.Run(ctx)
   579  	if err != nil {
   580  		// TODO: Handle error, possibly resuming with copier.RewriteToken.
   581  	}
   582  	fmt.Println(attrs)
   583  
   584  	// Just copy content.
   585  	attrs, err = dst.CopierFrom(src).Run(ctx)
   586  	if err != nil {
   587  		// TODO: Handle error. No way to resume.
   588  	}
   589  	fmt.Println(attrs)
   590  }
   591  
   592  func ExampleCopier_Run_progress() {
   593  	// Display progress across multiple rewrite RPCs.
   594  	ctx := context.Background()
   595  	client, err := storage.NewClient(ctx)
   596  	if err != nil {
   597  		// TODO: handle error.
   598  	}
   599  	src := client.Bucket("bucketname").Object("file1")
   600  	dst := client.Bucket("another-bucketname").Object("file2")
   601  
   602  	copier := dst.CopierFrom(src)
   603  	copier.ProgressFunc = func(copiedBytes, totalBytes uint64) {
   604  		log.Printf("copy %.1f%% done", float64(copiedBytes)/float64(totalBytes)*100)
   605  	}
   606  	if _, err := copier.Run(ctx); err != nil {
   607  		// TODO: handle error.
   608  	}
   609  }
   610  
   611  var key1, key2 []byte
   612  
   613  func ExampleObjectHandle_CopierFrom_rotateEncryptionKeys() {
   614  	// To rotate the encryption key on an object, copy it onto itself.
   615  	ctx := context.Background()
   616  	client, err := storage.NewClient(ctx)
   617  	if err != nil {
   618  		// TODO: handle error.
   619  	}
   620  	obj := client.Bucket("bucketname").Object("obj")
   621  	// Assume obj is encrypted with key1, and we want to change to key2.
   622  	_, err = obj.Key(key2).CopierFrom(obj.Key(key1)).Run(ctx)
   623  	if err != nil {
   624  		// TODO: handle error.
   625  	}
   626  }
   627  
   628  func ExampleComposer_Run() {
   629  	ctx := context.Background()
   630  	client, err := storage.NewClient(ctx)
   631  	if err != nil {
   632  		// TODO: handle error.
   633  	}
   634  	bkt := client.Bucket("bucketname")
   635  	src1 := bkt.Object("o1")
   636  	src2 := bkt.Object("o2")
   637  	dst := bkt.Object("o3")
   638  
   639  	// Compose and modify metadata.
   640  	c := dst.ComposerFrom(src1, src2)
   641  	c.ContentType = "text/plain"
   642  
   643  	// Set the expected checksum for the destination object to be validated by
   644  	// the backend (if desired).
   645  	c.CRC32C = 42
   646  	c.SendCRC32C = true
   647  
   648  	attrs, err := c.Run(ctx)
   649  	if err != nil {
   650  		// TODO: Handle error.
   651  	}
   652  	fmt.Println(attrs)
   653  	// Just compose.
   654  	attrs, err = dst.ComposerFrom(src1, src2).Run(ctx)
   655  	if err != nil {
   656  		// TODO: Handle error.
   657  	}
   658  	fmt.Println(attrs)
   659  }
   660  
   661  var gen int64
   662  
   663  func ExampleObjectHandle_Generation() {
   664  	// Read an object's contents from generation gen, regardless of the
   665  	// current generation of the object.
   666  	ctx := context.Background()
   667  	client, err := storage.NewClient(ctx)
   668  	if err != nil {
   669  		// TODO: handle error.
   670  	}
   671  	obj := client.Bucket("my-bucket").Object("my-object")
   672  	rc, err := obj.Generation(gen).NewReader(ctx)
   673  	if err != nil {
   674  		// TODO: handle error.
   675  	}
   676  	defer rc.Close()
   677  	if _, err := io.Copy(os.Stdout, rc); err != nil {
   678  		// TODO: handle error.
   679  	}
   680  }
   681  
   682  func ExampleObjectHandle_If() {
   683  	// Read from an object only if the current generation is gen.
   684  	ctx := context.Background()
   685  	client, err := storage.NewClient(ctx)
   686  	if err != nil {
   687  		// TODO: handle error.
   688  	}
   689  	obj := client.Bucket("my-bucket").Object("my-object")
   690  	rc, err := obj.If(storage.Conditions{GenerationMatch: gen}).NewReader(ctx)
   691  	if err != nil {
   692  		// TODO: handle error.
   693  	}
   694  
   695  	if _, err := io.Copy(os.Stdout, rc); err != nil {
   696  		// TODO: handle error.
   697  	}
   698  	if err := rc.Close(); err != nil {
   699  		switch ee := err.(type) {
   700  		case *googleapi.Error:
   701  			if ee.Code == http.StatusPreconditionFailed {
   702  				// The condition presented in the If failed.
   703  				// TODO: handle error.
   704  			}
   705  
   706  			// TODO: handle other status codes here.
   707  
   708  		default:
   709  			// TODO: handle error.
   710  		}
   711  	}
   712  }
   713  
   714  var secretKey []byte
   715  
   716  func ExampleObjectHandle_Key() {
   717  	ctx := context.Background()
   718  	client, err := storage.NewClient(ctx)
   719  	if err != nil {
   720  		// TODO: handle error.
   721  	}
   722  	obj := client.Bucket("my-bucket").Object("my-object")
   723  	// Encrypt the object's contents.
   724  	w := obj.Key(secretKey).NewWriter(ctx)
   725  	if _, err := w.Write([]byte("top secret")); err != nil {
   726  		// TODO: handle error.
   727  	}
   728  	if err := w.Close(); err != nil {
   729  		// TODO: handle error.
   730  	}
   731  }
   732  
   733  func ExampleClient_CreateHMACKey() {
   734  	ctx := context.Background()
   735  	client, err := storage.NewClient(ctx)
   736  	if err != nil {
   737  		// TODO: handle error.
   738  	}
   739  
   740  	hkey, err := client.CreateHMACKey(ctx, "project-id", "service-account-email")
   741  	if err != nil {
   742  		// TODO: handle error.
   743  	}
   744  	_ = hkey // TODO: Use the HMAC Key.
   745  }
   746  
   747  func ExampleHMACKeyHandle_Delete() {
   748  	ctx := context.Background()
   749  	client, err := storage.NewClient(ctx)
   750  	if err != nil {
   751  		// TODO: handle error.
   752  	}
   753  
   754  	hkh := client.HMACKeyHandle("project-id", "access-key-id")
   755  	// Make sure that the HMACKey being deleted has a status of inactive.
   756  	if err := hkh.Delete(ctx); err != nil {
   757  		// TODO: handle error.
   758  	}
   759  }
   760  
   761  func ExampleHMACKeyHandle_Get() {
   762  	ctx := context.Background()
   763  	client, err := storage.NewClient(ctx)
   764  	if err != nil {
   765  		// TODO: handle error.
   766  	}
   767  
   768  	hkh := client.HMACKeyHandle("project-id", "access-key-id")
   769  	hkey, err := hkh.Get(ctx)
   770  	if err != nil {
   771  		// TODO: handle error.
   772  	}
   773  	_ = hkey // TODO: Use the HMAC Key.
   774  }
   775  
   776  func ExampleHMACKeyHandle_Update() {
   777  	ctx := context.Background()
   778  	client, err := storage.NewClient(ctx)
   779  	if err != nil {
   780  		// TODO: handle error.
   781  	}
   782  
   783  	hkh := client.HMACKeyHandle("project-id", "access-key-id")
   784  	ukey, err := hkh.Update(ctx, storage.HMACKeyAttrsToUpdate{
   785  		State: storage.Inactive,
   786  	})
   787  	if err != nil {
   788  		// TODO: handle error.
   789  	}
   790  	_ = ukey // TODO: Use the HMAC Key.
   791  }
   792  
   793  func ExampleClient_ListHMACKeys() {
   794  	ctx := context.Background()
   795  	client, err := storage.NewClient(ctx)
   796  	if err != nil {
   797  		// TODO: handle error.
   798  	}
   799  
   800  	iter := client.ListHMACKeys(ctx, "project-id")
   801  	for {
   802  		key, err := iter.Next()
   803  		if err == iterator.Done {
   804  			break
   805  		}
   806  		if err != nil {
   807  			// TODO: handle error.
   808  		}
   809  		_ = key // TODO: Use the key.
   810  	}
   811  }
   812  
   813  func ExampleClient_ListHMACKeys_showDeletedKeys() {
   814  	ctx := context.Background()
   815  	client, err := storage.NewClient(ctx)
   816  	if err != nil {
   817  		// TODO: handle error.
   818  	}
   819  
   820  	iter := client.ListHMACKeys(ctx, "project-id", storage.ShowDeletedHMACKeys())
   821  	for {
   822  		key, err := iter.Next()
   823  		if err == iterator.Done {
   824  			break
   825  		}
   826  		if err != nil {
   827  			// TODO: handle error.
   828  		}
   829  		_ = key // TODO: Use the key.
   830  	}
   831  }
   832  
   833  func ExampleClient_ListHMACKeys_forServiceAccountEmail() {
   834  	ctx := context.Background()
   835  	client, err := storage.NewClient(ctx)
   836  	if err != nil {
   837  		// TODO: handle error.
   838  	}
   839  
   840  	iter := client.ListHMACKeys(ctx, "project-id", storage.ForHMACKeyServiceAccountEmail("service@account.email"))
   841  	for {
   842  		key, err := iter.Next()
   843  		if err == iterator.Done {
   844  			break
   845  		}
   846  		if err != nil {
   847  			// TODO: handle error.
   848  		}
   849  		_ = key // TODO: Use the key.
   850  	}
   851  }
   852  
   853  func ExampleBucketHandle_exists() {
   854  	ctx := context.Background()
   855  	client, err := storage.NewClient(ctx)
   856  	if err != nil {
   857  		// TODO: handle error.
   858  	}
   859  
   860  	attrs, err := client.Bucket("my-bucket").Attrs(ctx)
   861  	if err == storage.ErrBucketNotExist {
   862  		fmt.Println("The bucket does not exist")
   863  		return
   864  	}
   865  	if err != nil {
   866  		// TODO: handle error.
   867  	}
   868  	fmt.Printf("The bucket exists and has attributes: %#v\n", attrs)
   869  }
   870  
   871  func ExampleObjectHandle_exists() {
   872  	ctx := context.Background()
   873  	client, err := storage.NewClient(ctx)
   874  	if err != nil {
   875  		// TODO: handle error.
   876  	}
   877  
   878  	attrs, err := client.Bucket("my-bucket").Object("my-object").Attrs(ctx)
   879  	if err == storage.ErrObjectNotExist {
   880  		fmt.Println("The object does not exist")
   881  		return
   882  	}
   883  	if err != nil {
   884  		// TODO: handle error.
   885  	}
   886  	fmt.Printf("The object exists and has attributes: %#v\n", attrs)
   887  }
   888  
   889  func ExampleGenerateSignedPostPolicyV4() {
   890  	pv4, err := storage.GenerateSignedPostPolicyV4("my-bucket", "my-object.txt", &storage.PostPolicyV4Options{
   891  		GoogleAccessID: "my-access-id",
   892  		PrivateKey:     []byte("my-private-key"),
   893  
   894  		// The upload expires in 2hours.
   895  		Expires: time.Now().Add(2 * time.Hour),
   896  
   897  		Fields: &storage.PolicyV4Fields{
   898  			StatusCodeOnSuccess:    200,
   899  			RedirectToURLOnSuccess: "https://example.org/",
   900  			// It MUST only be a text file.
   901  			ContentType: "text/plain",
   902  		},
   903  
   904  		// The conditions that the uploaded file will be expected to conform to.
   905  		Conditions: []storage.PostPolicyV4Condition{
   906  			// Make the file a maximum of 10mB.
   907  			storage.ConditionContentLengthRange(0, 10<<20),
   908  		},
   909  	})
   910  	if err != nil {
   911  		// TODO: handle error.
   912  	}
   913  
   914  	// Now you can upload your file using the generated post policy
   915  	// with a plain HTTP client or even the browser.
   916  	formBuf := new(bytes.Buffer)
   917  	mw := multipart.NewWriter(formBuf)
   918  	for fieldName, value := range pv4.Fields {
   919  		if err := mw.WriteField(fieldName, value); err != nil {
   920  			// TODO: handle error.
   921  		}
   922  	}
   923  	file := bytes.NewReader(bytes.Repeat([]byte("a"), 100))
   924  
   925  	mf, err := mw.CreateFormFile("file", "myfile.txt")
   926  	if err != nil {
   927  		// TODO: handle error.
   928  	}
   929  	if _, err := io.Copy(mf, file); err != nil {
   930  		// TODO: handle error.
   931  	}
   932  	if err := mw.Close(); err != nil {
   933  		// TODO: handle error.
   934  	}
   935  
   936  	// Compose the request.
   937  	req, err := http.NewRequest("POST", pv4.URL, formBuf)
   938  	if err != nil {
   939  		// TODO: handle error.
   940  	}
   941  	// Ensure the Content-Type is derived from the multipart writer.
   942  	req.Header.Set("Content-Type", mw.FormDataContentType())
   943  	res, err := http.DefaultClient.Do(req)
   944  	if err != nil {
   945  		// TODO: handle error.
   946  	}
   947  	_ = res
   948  }
   949  

View as plain text