github.com/woremacx/kocha@v0.7.1-0.20150731103243-a5889322afc9/request.go (about)

     1  package kocha
     2  
     3  import (
     4  	"net"
     5  	"net/http"
     6  	"strings"
     7  	"sync"
     8  )
     9  
    10  var requestPool = &sync.Pool{
    11  	New: func() interface{} {
    12  		return &Request{}
    13  	},
    14  }
    15  
    16  // Request represents a request.
    17  type Request struct {
    18  	*http.Request
    19  
    20  	// RemoteAddr is similar to http.Request.RemoteAddr, but IP only.
    21  	RemoteAddr string
    22  }
    23  
    24  // newRequest returns a new Request that given a *http.Request.
    25  func newRequest(req *http.Request) *Request {
    26  	r := requestPool.Get().(*Request)
    27  	r.Request = req
    28  	r.RemoteAddr = remoteAddr(req)
    29  	return r
    30  }
    31  
    32  // Scheme returns current scheme of HTTP connection.
    33  func (r *Request) Scheme() string {
    34  	switch {
    35  	case r.Header.Get("Https") == "on", r.Header.Get("X-Forwarded-Ssl") == "on":
    36  		return "https"
    37  	case r.Header.Get("X-Forwarded-Scheme") != "":
    38  		return r.Header.Get("X-Forwarded-Scheme")
    39  	case r.Header.Get("X-Forwarded-Proto") != "":
    40  		return strings.Split(r.Header.Get("X-Forwarded-Proto"), ",")[0]
    41  	}
    42  	return "http"
    43  }
    44  
    45  // IsSSL returns whether the current connection is secure.
    46  func (r *Request) IsSSL() bool {
    47  	return r.Scheme() == "https"
    48  }
    49  
    50  // IsXHR returns whether the XHR request.
    51  func (r *Request) IsXHR() bool {
    52  	return r.Header.Get("X-Requested-With") == "XMLHttpRequest"
    53  }
    54  
    55  func (r *Request) reuse() {
    56  	requestPool.Put(r)
    57  }
    58  
    59  func remoteAddr(r *http.Request) string {
    60  	if addr := r.Header.Get("X-Forwarded-For"); addr != "" {
    61  		return strings.TrimSpace(addr[strings.LastIndex(addr, ",")+1:])
    62  	}
    63  	host, _, err := net.SplitHostPort(r.RemoteAddr)
    64  	if err != nil {
    65  		return r.RemoteAddr
    66  	}
    67  	return host
    68  }