header.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package dpcore
  2. import (
  3. "net"
  4. "net/http"
  5. "strings"
  6. )
  7. /*
  8. Header.go
  9. This script handles headers rewrite and remove
  10. in dpcore.
  11. Added in Zoraxy v3.0.6 by tobychui
  12. */
  13. // removeHeaders Remove hop-by-hop headers listed in the "Connection" header, Remove hop-by-hop headers.
  14. func removeHeaders(header http.Header, noCache bool) {
  15. // Remove hop-by-hop headers listed in the "Connection" header.
  16. if c := header.Get("Connection"); c != "" {
  17. for _, f := range strings.Split(c, ",") {
  18. if f = strings.TrimSpace(f); f != "" {
  19. header.Del(f)
  20. }
  21. }
  22. }
  23. // Remove hop-by-hop headers
  24. for _, h := range hopHeaders {
  25. if header.Get(h) != "" {
  26. header.Del(h)
  27. }
  28. }
  29. //Restore the Upgrade header if any
  30. if header.Get("Zr-Origin-Upgrade") != "" {
  31. header.Set("Upgrade", header.Get("Zr-Origin-Upgrade"))
  32. header.Del("Zr-Origin-Upgrade")
  33. }
  34. //Disable cache if nocache is set
  35. if noCache {
  36. header.Del("Cache-Control")
  37. header.Set("Cache-Control", "no-store")
  38. }
  39. }
  40. // rewriteUserAgent rewrite the user agent based on incoming request
  41. func rewriteUserAgent(header http.Header, UA string) {
  42. //Hide Go-HTTP-Client UA if the client didnt sent us one
  43. if header.Get("User-Agent") == "" {
  44. // If the outbound request doesn't have a User-Agent header set,
  45. // don't send the default Go HTTP client User-Agent
  46. header.Del("User-Agent")
  47. header.Set("User-Agent", UA)
  48. }
  49. }
  50. // Add X-Forwarded-For Header and rewrite X-Real-Ip according to sniffing logics
  51. func addXForwardedForHeader(req *http.Request) {
  52. if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
  53. // If we aren't the first proxy retain prior
  54. // X-Forwarded-For information as a comma+space
  55. // separated list and fold multiple headers into one.
  56. if prior, ok := req.Header["X-Forwarded-For"]; ok {
  57. clientIP = strings.Join(prior, ", ") + ", " + clientIP
  58. }
  59. req.Header.Set("X-Forwarded-For", clientIP)
  60. if req.TLS != nil {
  61. req.Header.Set("X-Forwarded-Proto", "https")
  62. } else {
  63. req.Header.Set("X-Forwarded-Proto", "http")
  64. }
  65. if req.Header.Get("X-Real-Ip") == "" {
  66. //Check if CF-Connecting-IP header exists
  67. CF_Connecting_IP := req.Header.Get("CF-Connecting-IP")
  68. Fastly_Client_IP := req.Header.Get("Fastly-Client-IP")
  69. if CF_Connecting_IP != "" {
  70. //Use CF Connecting IP
  71. req.Header.Set("X-Real-Ip", CF_Connecting_IP)
  72. } else if Fastly_Client_IP != "" {
  73. //Use Fastly Client IP
  74. req.Header.Set("X-Real-Ip", Fastly_Client_IP)
  75. } else {
  76. // Not exists. Fill it in with first entry in X-Forwarded-For
  77. ips := strings.Split(clientIP, ",")
  78. if len(ips) > 0 {
  79. req.Header.Set("X-Real-Ip", strings.TrimSpace(ips[0]))
  80. }
  81. }
  82. }
  83. }
  84. }
  85. // injectUserDefinedHeaders inject the user headers from slice
  86. // if a value is empty string, the key will be removed from header.
  87. // if a key is empty string, the function will return immediately
  88. func injectUserDefinedHeaders(header http.Header, userHeaders [][]string) {
  89. for _, userHeader := range userHeaders {
  90. if len(userHeader) == 0 {
  91. //End of header slice
  92. return
  93. }
  94. headerKey := userHeader[0]
  95. headerValue := userHeader[1]
  96. if headerValue == "" {
  97. //Remove header from head
  98. header.Del(headerKey)
  99. continue
  100. }
  101. //Default: Set header value
  102. header.Del(headerKey) //Remove header if it already exists
  103. header.Set(headerKey, headerValue)
  104. }
  105. }