gcs_transport.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "strconv"
  7. "strings"
  8. "cloud.google.com/go/storage"
  9. "google.golang.org/api/option"
  10. )
  11. type gcsTransport struct {
  12. client *storage.Client
  13. }
  14. func newGCSTransport() (http.RoundTripper, error) {
  15. var (
  16. client *storage.Client
  17. err error
  18. )
  19. if len(conf.GCSKey) > 0 {
  20. client, err = storage.NewClient(context.Background(), option.WithCredentialsJSON([]byte(conf.GCSKey)))
  21. } else {
  22. client, err = storage.NewClient(context.Background())
  23. }
  24. if err != nil {
  25. return nil, fmt.Errorf("Can't create GCS client: %s", err)
  26. }
  27. return gcsTransport{client}, nil
  28. }
  29. func (t gcsTransport) RoundTrip(req *http.Request) (*http.Response, error) {
  30. bkt := t.client.Bucket(req.URL.Host)
  31. obj := bkt.Object(strings.TrimPrefix(req.URL.Path, "/"))
  32. if g, err := strconv.ParseInt(req.URL.RawQuery, 10, 64); err == nil && g > 0 {
  33. obj = obj.Generation(g)
  34. }
  35. reader, err := obj.NewReader(context.Background())
  36. if err != nil {
  37. return nil, err
  38. }
  39. header := make(http.Header)
  40. header.Set("Cache-Control", reader.Attrs.CacheControl)
  41. return &http.Response{
  42. Status: "200 OK",
  43. StatusCode: 200,
  44. Proto: "HTTP/1.0",
  45. ProtoMajor: 1,
  46. ProtoMinor: 0,
  47. Header: header,
  48. ContentLength: reader.Attrs.Size,
  49. Body: reader,
  50. Close: true,
  51. Request: req,
  52. }, nil
  53. }