github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/ginx/hlog/util.go (about)

     1  package hlog
     2  
     3  import (
     4  	"bufio"
     5  	"io/ioutil"
     6  	"net/http"
     7  	"strings"
     8  )
     9  
    10  // At returns the element of index i in the slice s.
    11  func At(s []string, i int) string {
    12  	if i < len(s) {
    13  		return s[i]
    14  	}
    15  
    16  	return ""
    17  }
    18  
    19  // Abbreviate abbreviates a string using ellipses.
    20  func Abbreviate(str string, maxWidth int) string {
    21  	size := len(str)
    22  	if str == "" || maxWidth < 4 || size <= maxWidth {
    23  		return str
    24  	}
    25  
    26  	return str[:maxWidth-3] + ("...")
    27  }
    28  
    29  // IPAddrFromRemoteAddr parses the IP Address.
    30  // Request.RemoteAddress contains port, which we want to remove i.e.: "[::1]:58292" => "[::1]".
    31  func IPAddrFromRemoteAddr(s string) string {
    32  	idx := strings.LastIndex(s, ":")
    33  	if idx == -1 {
    34  		return s
    35  	}
    36  
    37  	return s[:idx]
    38  }
    39  
    40  // GetRemoteAddress returns ip address of the client making the request, taking into account http proxies.
    41  func GetRemoteAddress(r *http.Request) string {
    42  	hdr := r.Header
    43  	hdrRealIP := hdr.Get("X-Real-Ip")
    44  	hdrForwardedFor := hdr.Get("X-Forwarded-For")
    45  
    46  	if hdrRealIP == "" && hdrForwardedFor == "" {
    47  		return IPAddrFromRemoteAddr(r.RemoteAddr)
    48  	}
    49  
    50  	if hdrForwardedFor != "" {
    51  		// X-Forwarded-For is potentially a list of addresses separated with ","
    52  		parts := strings.Split(hdrForwardedFor, ",")
    53  		for i, p := range parts {
    54  			parts[i] = strings.TrimSpace(p)
    55  		}
    56  
    57  		return parts[0]
    58  	}
    59  
    60  	return hdrRealIP
    61  }
    62  
    63  // IsWsRequest return true if this request is a websocket request.
    64  func IsWsRequest(url string) bool {
    65  	return strings.HasPrefix(url, "/ws/")
    66  }
    67  
    68  // PeekBody peeks the maxSize body from the request limit to maxSize bytes.
    69  func PeekBody(r *http.Request, maxSize int) []byte {
    70  	if r.Body == nil {
    71  		return nil
    72  	}
    73  
    74  	buf := bufio.NewReader(r.Body)
    75  	// And now set a new body, which will simulate the same rowsData we read:
    76  	r.Body = ioutil.NopCloser(buf)
    77  
    78  	// https://www.alexedwards.net/blog/how-to-properly-parse-a-json-request-body
    79  	// Use http.MaxBytesReader to enforce a maximum read of 1MB from the
    80  	// response body. A request body larger than that will now result in
    81  	// Decode() returning a "http: request body too large" error.
    82  	// r.Body = http.MaxBytesReader(w, r.Body, 1048576)
    83  
    84  	// Work / inspect body. You may even modify it!
    85  
    86  	peek, _ := buf.Peek(maxSize)
    87  
    88  	return peek
    89  }