gcs_transport.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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. return &http.Response{
  39. Status: "200 OK",
  40. StatusCode: 200,
  41. Proto: "HTTP/1.0",
  42. ProtoMajor: 1,
  43. ProtoMinor: 0,
  44. Header: make(http.Header),
  45. ContentLength: reader.Attrs.Size,
  46. Body: reader,
  47. Close: true,
  48. Request: req,
  49. }, nil
  50. }