Skip to content

Commit

Permalink
go-aah/aah#126 updates for websocket and around it
Browse files Browse the repository at this point in the history
  • Loading branch information
jeevatkm committed Apr 20, 2018
1 parent f339cea commit 001dd41
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 61 deletions.
55 changes: 55 additions & 0 deletions ahttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ package ahttp

import (
"io"
"net"
"net/http"
"strings"

"aahframework.org/essentials.v0"
)

// HTTP Method names
Expand Down Expand Up @@ -91,3 +95,54 @@ func WrapGzipWriter(w io.Writer) ResponseWriter {
gr.r = w.(*Response)
return gr
}

// IdentifyScheme method is to identify value of protocol value. It's is derived
// one, Go language doesn't provide directly.
// - `X-Forwarded-Proto` is not empty return value as is
// - `http.Request.TLS` is not nil value is `https`
// - `http.Request.TLS` is nil value is `http`
func IdentifyScheme(r *http.Request) string {
scheme := r.Header.Get("X-Forwarded-Proto")
if scheme == "" {
if r.TLS == nil {
return "http"
}
return "https"
}
return scheme
}

// IdentifyHost method is to correct Hosyt source value from HTTP request.
func IdentifyHost(r *http.Request) string {
if r.URL.Host == "" {
return r.Host
}
return r.URL.Host
}

// ClientIP method returns remote Client IP address aka Remote IP.
// It parses in the order of given set of headers otherwise it uses default
// default header set `X-Forwarded-For`, `X-Real-IP`, "X-Appengine-Remote-Addr"
// and finally `http.Request.RemoteAddr`.
func ClientIP(r *http.Request, hdrs ...string) string {
if len(hdrs) == 0 {
hdrs = []string{"X-Forwarded-For", "X-Real-IP", "X-Appengine-Remote-Addr"}
}

for _, hdrKey := range hdrs {
if hv := r.Header.Get(hdrKey); !ess.IsStrEmpty(hv) {
index := strings.Index(hv, ",")
if index == -1 {
return strings.TrimSpace(hv)
}
return strings.TrimSpace(hv[:index])
}
}

// Remote Address
if remoteAddr, _, err := net.SplitHostPort(r.RemoteAddr); err == nil {
return strings.TrimSpace(remoteAddr)
}

return ""
}
3 changes: 3 additions & 0 deletions content_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ var (

// ContentTypeJavascript content type.
ContentTypeJavascript = parseMediaType("application/javascript; charset=utf-8")

// ContentTypeEventStream Server-Sent Events content type.
ContentTypeEventStream = parseMediaType("text/event-stream")
)

//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
Expand Down
61 changes: 5 additions & 56 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"fmt"
"io"
"mime/multipart"
"net"
"net/http"
"net/url"
"os"
Expand All @@ -21,10 +20,8 @@ import (
)

const (
jsonpReqParamKey = "callback"
ajaxHeaderValue = "XMLHttpRequest"
wsHdrVal = "websocket"
connHdrValPartial = "upgrade"
jsonpReqParamKey = "callback"
ajaxHeaderValue = "XMLHttpRequest"
)

var requestPool = &sync.Pool{New: func() interface{} { return &Request{} }}
Expand All @@ -36,8 +33,8 @@ var requestPool = &sync.Pool{New: func() interface{} { return &Request{} }}
// ParseRequest method populates the given aah framework `ahttp.Request`
// instance from Go HTTP request.
func ParseRequest(r *http.Request, req *Request) *Request {
req.Scheme = identifyScheme(r)
req.Host = host(r)
req.Scheme = IdentifyScheme(r)
req.Host = IdentifyHost(r)
req.Proto = r.Proto
req.Method = r.Method
req.Path = r.URL.Path
Expand Down Expand Up @@ -153,26 +150,7 @@ func (r *Request) SetAcceptEncoding(encoding *AcceptSpec) *Request {
// could configure headers of their choice. For e.g.
// X-Appengine-Remote-Addr, etc.
func (r *Request) ClientIP() string {
// Header X-Forwarded-For
if fwdFor := r.Header.Get(HeaderXForwardedFor); !ess.IsStrEmpty(fwdFor) {
index := strings.Index(fwdFor, ",")
if index == -1 {
return strings.TrimSpace(fwdFor)
}
return strings.TrimSpace(fwdFor[:index])
}

// Header X-Real-Ip
if realIP := r.Header.Get(HeaderXRealIP); !ess.IsStrEmpty(realIP) {
return strings.TrimSpace(realIP)
}

// Remote Address
if remoteAddr, _, err := net.SplitHostPort(r.Unwrap().RemoteAddr); err == nil {
return strings.TrimSpace(remoteAddr)
}

return ""
return ClientIP(r.Unwrap())
}

// Cookie method returns a named cookie from HTTP request otherwise error.
Expand Down Expand Up @@ -226,12 +204,6 @@ func (r *Request) IsAJAX() bool {
return r.Header.Get(HeaderXRequestedWith) == ajaxHeaderValue
}

// IsWebSocket method returns true if request is WebSocket otherwise false.
func (r *Request) IsWebSocket() bool {
return r.Header.Get(HeaderUpgrade) == wsHdrVal &&
strings.Contains(strings.ToLower(r.Header.Get(HeaderConnection)), connHdrValPartial)
}

// URL method return underlying request URL instance.
func (r *Request) URL() *url.URL {
return r.Unwrap().URL
Expand Down Expand Up @@ -452,29 +424,6 @@ func (p *Params) FormFile(key string) (multipart.File, *multipart.FileHeader, er
// Unexported methods
//___________________________________

// identifyScheme method is to identify value of protocol value. It's is derived
// one, Go language doesn't provide directly.
// - `X-Forwarded-Proto` is not empty return value as is
// - `http.Request.TLS` is not nil value is `https`
// - `http.Request.TLS` is nil value is `http`
func identifyScheme(r *http.Request) string {
scheme := r.Header.Get(HeaderXForwardedProto)
if scheme == "" {
if r.TLS == nil {
return SchemeHTTP // "http"
}
return SchemeHTTPS // "https"
}
return scheme
}

func host(r *http.Request) string {
if r.URL.Host == "" {
return r.Host
}
return r.URL.Host
}

func getReferer(hdr http.Header) string {
referer := hdr.Get(HeaderReferer)
if referer == "" {
Expand Down
9 changes: 4 additions & 5 deletions request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ func TestHTTPParseRequest(t *testing.T) {
assert.Nil(t, err)
assert.False(t, aahReq.IsJSONP())
assert.False(t, aahReq.IsAJAX())
assert.False(t, aahReq.IsWebSocket())

aahReq.SetAcceptContentType(nil)
assert.NotNil(t, aahReq.AcceptContentType())
Expand Down Expand Up @@ -186,19 +185,19 @@ func TestHTTPRequestCookies(t *testing.T) {

func TestRequestSchemeDerived(t *testing.T) {
req := httptest.NewRequest("GET", "http://127.0.0.1:8080/welcome.html", nil)
scheme1 := identifyScheme(req)
scheme1 := IdentifyScheme(req)
assert.Equal(t, "http", scheme1)

req.TLS = &tls.ConnectionState{}
scheme2 := identifyScheme(req)
scheme2 := IdentifyScheme(req)
assert.Equal(t, "https", scheme2)

req.Header.Set(HeaderXForwardedProto, "https")
scheme3 := identifyScheme(req)
scheme3 := IdentifyScheme(req)
assert.Equal(t, "https", scheme3)

req.Header.Set(HeaderXForwardedProto, "http")
scheme4 := identifyScheme(req)
scheme4 := IdentifyScheme(req)
assert.Equal(t, "http", scheme4)
}

Expand Down

0 comments on commit 001dd41

Please sign in to comment.