gcs_transport.go 1.3 KB

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