transport.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. sep := t.config.SourceURLQuerySeparator // shortcut
  61. transp, err := generichttp.New(false, &t.config.HTTP)
  62. if err != nil {
  63. return err
  64. }
  65. if t.config.Local.Root != "" {
  66. p, err := fsTransport.New(&t.config.Local, sep)
  67. if err != nil {
  68. return err
  69. }
  70. t.RegisterProtocol("local", p)
  71. }
  72. if t.config.S3Enabled {
  73. tr, err := s3Transport.New(&t.config.S3, transp, sep)
  74. if err != nil {
  75. return err
  76. }
  77. t.RegisterProtocol("s3", tr)
  78. }
  79. if t.config.GCSEnabled {
  80. tr, err := gcsTransport.New(&t.config.GCS, transp, sep)
  81. if err != nil {
  82. return err
  83. }
  84. t.RegisterProtocol("gs", tr)
  85. }
  86. if t.config.ABSEnabled {
  87. tr, err := azureTransport.New(&t.config.ABS, transp, sep)
  88. if err != nil {
  89. return err
  90. }
  91. t.RegisterProtocol("abs", tr)
  92. }
  93. if t.config.SwiftEnabled {
  94. tr, err := swiftTransport.New(&t.config.Swift, transp, sep)
  95. if err != nil {
  96. return err
  97. }
  98. t.RegisterProtocol("swift", tr)
  99. }
  100. return nil
  101. }