chatdesk-ui/auth_v2.169.0/internal/utilities/request.go

118 lines
2.4 KiB
Go

package utilities
import (
"bytes"
"io"
"net"
"net/http"
"net/url"
"strings"
"github.com/supabase/auth/internal/conf"
)
// GetIPAddress returns the real IP address of the HTTP request. It parses the
// X-Forwarded-For header.
func GetIPAddress(r *http.Request) string {
if r.Header != nil {
xForwardedFor := r.Header.Get("X-Forwarded-For")
if xForwardedFor != "" {
ips := strings.Split(xForwardedFor, ",")
for i := range ips {
ips[i] = strings.TrimSpace(ips[i])
}
for _, ip := range ips {
if ip != "" {
parsed := net.ParseIP(ip)
if parsed == nil {
continue
}
return parsed.String()
}
}
}
}
ipPort := r.RemoteAddr
ip, _, err := net.SplitHostPort(ipPort)
if err != nil {
return ipPort
}
return ip
}
// GetBodyBytes reads the whole request body properly into a byte array.
func GetBodyBytes(req *http.Request) ([]byte, error) {
if req.Body == nil || req.Body == http.NoBody {
return nil, nil
}
originalBody := req.Body
defer SafeClose(originalBody)
buf, err := io.ReadAll(originalBody)
if err != nil {
return nil, err
}
req.Body = io.NopCloser(bytes.NewReader(buf))
return buf, nil
}
func GetReferrer(r *http.Request, config *conf.GlobalConfiguration) string {
// try get redirect url from query or post data first
reqref := getRedirectTo(r)
if IsRedirectURLValid(config, reqref) {
return reqref
}
// instead try referrer header value
reqref = r.Referer()
if IsRedirectURLValid(config, reqref) {
return reqref
}
return config.SiteURL
}
func IsRedirectURLValid(config *conf.GlobalConfiguration, redirectURL string) bool {
if redirectURL == "" {
return false
}
base, berr := url.Parse(config.SiteURL)
refurl, rerr := url.Parse(redirectURL)
// As long as the referrer came from the site, we will redirect back there
if berr == nil && rerr == nil && base.Hostname() == refurl.Hostname() {
return true
}
// For case when user came from mobile app or other permitted resource - redirect back
for _, pattern := range config.URIAllowListMap {
if pattern.Match(redirectURL) {
return true
}
}
return false
}
// getRedirectTo tries extract redirect url from header or from query params
func getRedirectTo(r *http.Request) (reqref string) {
reqref = r.Header.Get("redirect_to")
if reqref != "" {
return
}
if err := r.ParseForm(); err == nil {
reqref = r.Form.Get("redirect_to")
}
return
}