transport.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Package transport provides a custom HTTP transport that supports multiple protocols
  2. // such as S3, GCS, ABS, Swift, and local file system.
  3. package transport
  4. import (
  5. "net/http"
  6. "github.com/imgproxy/imgproxy/v3/fetcher/transport/generichttp"
  7. azureTransport "github.com/imgproxy/imgproxy/v3/fetcher/transport/azure"
  8. fsTransport "github.com/imgproxy/imgproxy/v3/fetcher/transport/fs"
  9. gcsTransport "github.com/imgproxy/imgproxy/v3/fetcher/transport/gcs"
  10. s3Transport "github.com/imgproxy/imgproxy/v3/fetcher/transport/s3"
  11. swiftTransport "github.com/imgproxy/imgproxy/v3/fetcher/transport/swift"
  12. )
  13. // Transport is a wrapper around http.Transport which allows to track registered protocols
  14. type Transport struct {
  15. config *Config
  16. transport *http.Transport
  17. schemes map[string]struct{}
  18. }
  19. // New creates a new HTTP transport with no protocols registered
  20. func New(config *Config) (*Transport, error) {
  21. if err := config.Validate(); err != nil {
  22. return nil, err
  23. }
  24. transport, err := generichttp.New(true, &config.HTTP)
  25. if err != nil {
  26. return nil, err
  27. }
  28. // http and https are always registered
  29. schemes := map[string]struct{}{
  30. "http": {},
  31. "https": {},
  32. }
  33. t := &Transport{
  34. config: config,
  35. transport: transport,
  36. schemes: schemes,
  37. }
  38. err = t.registerAllProtocols()
  39. if err != nil {
  40. return nil, err
  41. }
  42. return t, nil
  43. }
  44. // Transport returns the underlying http.Transport
  45. func (t *Transport) Transport() *http.Transport {
  46. return t.transport
  47. }
  48. // RegisterProtocol registers a new transport protocol with the transport
  49. func (t *Transport) RegisterProtocol(scheme string, rt http.RoundTripper) {
  50. t.transport.RegisterProtocol(scheme, rt)
  51. t.schemes[scheme] = struct{}{}
  52. }
  53. // IsProtocolRegistered checks if a protocol is registered in the transport
  54. func (t *Transport) IsProtocolRegistered(scheme string) bool {
  55. _, ok := t.schemes[scheme]
  56. return ok
  57. }
  58. // RegisterAllProtocols registers all enabled protocols in the given transport
  59. func (t *Transport) registerAllProtocols() error {
  60. transp, err := generichttp.New(false, &t.config.HTTP)
  61. if err != nil {
  62. return err
  63. }
  64. if t.config.Local.Root != "" {
  65. t.RegisterProtocol("local", fsTransport.New(&t.config.Local))
  66. }
  67. if t.config.S3Enabled {
  68. if tr, err := s3Transport.New(&t.config.S3, transp); err != nil {
  69. return err
  70. } else {
  71. t.RegisterProtocol("s3", tr)
  72. }
  73. }
  74. if t.config.GCSEnabled {
  75. if tr, err := gcsTransport.New(&t.config.GCS, transp); err != nil {
  76. return err
  77. } else {
  78. t.RegisterProtocol("gs", tr)
  79. }
  80. }
  81. if t.config.ABSEnabled {
  82. if tr, err := azureTransport.New(&t.config.ABS, transp); err != nil {
  83. return err
  84. } else {
  85. t.RegisterProtocol("abs", tr)
  86. }
  87. }
  88. if t.config.SwiftEnabled {
  89. if tr, err := swiftTransport.New(&t.config.Swift, transp); err != nil {
  90. return err
  91. } else {
  92. t.RegisterProtocol("swift", tr)
  93. }
  94. }
  95. return nil
  96. }