cookies.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package cookies
  2. import (
  3. "fmt"
  4. "net/http"
  5. "net/http/cookiejar"
  6. "net/url"
  7. "sync"
  8. "golang.org/x/net/publicsuffix"
  9. "github.com/imgproxy/imgproxy/v3/config"
  10. )
  11. type anyCookieJarEntry struct {
  12. Name string
  13. Value string
  14. Quoted bool
  15. }
  16. // anyCookieJar is a cookie jar that stores all cookies in memory
  17. // and doesn't care about domains and paths
  18. type anyCookieJar struct {
  19. entries []anyCookieJarEntry
  20. mu sync.RWMutex
  21. }
  22. func (j *anyCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie) {
  23. j.mu.Lock()
  24. defer j.mu.Unlock()
  25. for _, c := range cookies {
  26. entry := anyCookieJarEntry{
  27. Name: c.Name,
  28. Value: c.Value,
  29. Quoted: c.Quoted,
  30. }
  31. j.entries = append(j.entries, entry)
  32. }
  33. }
  34. func (j *anyCookieJar) Cookies(u *url.URL) []*http.Cookie {
  35. j.mu.RLock()
  36. defer j.mu.RUnlock()
  37. cookies := make([]*http.Cookie, 0, len(j.entries))
  38. for _, e := range j.entries {
  39. c := http.Cookie{
  40. Name: e.Name,
  41. Value: e.Value,
  42. Quoted: e.Quoted,
  43. }
  44. cookies = append(cookies, &c)
  45. }
  46. return cookies
  47. }
  48. func JarFromRequest(r *http.Request) (jar http.CookieJar, err error) {
  49. if config.CookiePassthroughAll {
  50. jar = &anyCookieJar{}
  51. } else {
  52. jar, err = cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
  53. if err != nil {
  54. return nil, err
  55. }
  56. }
  57. if r == nil {
  58. return jar, nil
  59. }
  60. var cookieBase *url.URL
  61. if !config.CookiePassthroughAll {
  62. if len(config.CookieBaseURL) > 0 {
  63. if cookieBase, err = url.Parse(config.CookieBaseURL); err != nil {
  64. return nil, fmt.Errorf("can't parse cookie base URL: %s", err)
  65. }
  66. }
  67. if cookieBase == nil {
  68. scheme := r.Header.Get("X-Forwarded-Proto")
  69. if len(scheme) == 0 {
  70. scheme = "http"
  71. }
  72. host := r.Header.Get("X-Forwarded-Host")
  73. if len(host) == 0 {
  74. host = r.Header.Get("Host")
  75. }
  76. if len(host) == 0 {
  77. host = r.Host
  78. }
  79. if len(host) == 0 {
  80. return jar, nil
  81. }
  82. port := r.Header.Get("X-Forwarded-Port")
  83. if len(port) > 0 {
  84. host = host + ":" + port
  85. }
  86. cookieBase = &url.URL{
  87. Scheme: scheme,
  88. Host: host,
  89. }
  90. }
  91. }
  92. jar.SetCookies(cookieBase, r.Cookies())
  93. return jar, nil
  94. }