Skip to content

Commit 001dd41

Browse files
committed
go-aah/aah#126 updates for websocket and around it
1 parent f339cea commit 001dd41

File tree

4 files changed

+67
-61
lines changed

4 files changed

+67
-61
lines changed

ahttp.go

+55
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ package ahttp
88

99
import (
1010
"io"
11+
"net"
1112
"net/http"
13+
"strings"
14+
15+
"aahframework.org/essentials.v0"
1216
)
1317

1418
// HTTP Method names
@@ -91,3 +95,54 @@ func WrapGzipWriter(w io.Writer) ResponseWriter {
9195
gr.r = w.(*Response)
9296
return gr
9397
}
98+
99+
// IdentifyScheme method is to identify value of protocol value. It's is derived
100+
// one, Go language doesn't provide directly.
101+
// - `X-Forwarded-Proto` is not empty return value as is
102+
// - `http.Request.TLS` is not nil value is `https`
103+
// - `http.Request.TLS` is nil value is `http`
104+
func IdentifyScheme(r *http.Request) string {
105+
scheme := r.Header.Get("X-Forwarded-Proto")
106+
if scheme == "" {
107+
if r.TLS == nil {
108+
return "http"
109+
}
110+
return "https"
111+
}
112+
return scheme
113+
}
114+
115+
// IdentifyHost method is to correct Hosyt source value from HTTP request.
116+
func IdentifyHost(r *http.Request) string {
117+
if r.URL.Host == "" {
118+
return r.Host
119+
}
120+
return r.URL.Host
121+
}
122+
123+
// ClientIP method returns remote Client IP address aka Remote IP.
124+
// It parses in the order of given set of headers otherwise it uses default
125+
// default header set `X-Forwarded-For`, `X-Real-IP`, "X-Appengine-Remote-Addr"
126+
// and finally `http.Request.RemoteAddr`.
127+
func ClientIP(r *http.Request, hdrs ...string) string {
128+
if len(hdrs) == 0 {
129+
hdrs = []string{"X-Forwarded-For", "X-Real-IP", "X-Appengine-Remote-Addr"}
130+
}
131+
132+
for _, hdrKey := range hdrs {
133+
if hv := r.Header.Get(hdrKey); !ess.IsStrEmpty(hv) {
134+
index := strings.Index(hv, ",")
135+
if index == -1 {
136+
return strings.TrimSpace(hv)
137+
}
138+
return strings.TrimSpace(hv[:index])
139+
}
140+
}
141+
142+
// Remote Address
143+
if remoteAddr, _, err := net.SplitHostPort(r.RemoteAddr); err == nil {
144+
return strings.TrimSpace(remoteAddr)
145+
}
146+
147+
return ""
148+
}

content_type.go

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ var (
3939

4040
// ContentTypeJavascript content type.
4141
ContentTypeJavascript = parseMediaType("application/javascript; charset=utf-8")
42+
43+
// ContentTypeEventStream Server-Sent Events content type.
44+
ContentTypeEventStream = parseMediaType("text/event-stream")
4245
)
4346

4447
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾

request.go

+5-56
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"fmt"
1010
"io"
1111
"mime/multipart"
12-
"net"
1312
"net/http"
1413
"net/url"
1514
"os"
@@ -21,10 +20,8 @@ import (
2120
)
2221

2322
const (
24-
jsonpReqParamKey = "callback"
25-
ajaxHeaderValue = "XMLHttpRequest"
26-
wsHdrVal = "websocket"
27-
connHdrValPartial = "upgrade"
23+
jsonpReqParamKey = "callback"
24+
ajaxHeaderValue = "XMLHttpRequest"
2825
)
2926

3027
var requestPool = &sync.Pool{New: func() interface{} { return &Request{} }}
@@ -36,8 +33,8 @@ var requestPool = &sync.Pool{New: func() interface{} { return &Request{} }}
3633
// ParseRequest method populates the given aah framework `ahttp.Request`
3734
// instance from Go HTTP request.
3835
func ParseRequest(r *http.Request, req *Request) *Request {
39-
req.Scheme = identifyScheme(r)
40-
req.Host = host(r)
36+
req.Scheme = IdentifyScheme(r)
37+
req.Host = IdentifyHost(r)
4138
req.Proto = r.Proto
4239
req.Method = r.Method
4340
req.Path = r.URL.Path
@@ -153,26 +150,7 @@ func (r *Request) SetAcceptEncoding(encoding *AcceptSpec) *Request {
153150
// could configure headers of their choice. For e.g.
154151
// X-Appengine-Remote-Addr, etc.
155152
func (r *Request) ClientIP() string {
156-
// Header X-Forwarded-For
157-
if fwdFor := r.Header.Get(HeaderXForwardedFor); !ess.IsStrEmpty(fwdFor) {
158-
index := strings.Index(fwdFor, ",")
159-
if index == -1 {
160-
return strings.TrimSpace(fwdFor)
161-
}
162-
return strings.TrimSpace(fwdFor[:index])
163-
}
164-
165-
// Header X-Real-Ip
166-
if realIP := r.Header.Get(HeaderXRealIP); !ess.IsStrEmpty(realIP) {
167-
return strings.TrimSpace(realIP)
168-
}
169-
170-
// Remote Address
171-
if remoteAddr, _, err := net.SplitHostPort(r.Unwrap().RemoteAddr); err == nil {
172-
return strings.TrimSpace(remoteAddr)
173-
}
174-
175-
return ""
153+
return ClientIP(r.Unwrap())
176154
}
177155

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

229-
// IsWebSocket method returns true if request is WebSocket otherwise false.
230-
func (r *Request) IsWebSocket() bool {
231-
return r.Header.Get(HeaderUpgrade) == wsHdrVal &&
232-
strings.Contains(strings.ToLower(r.Header.Get(HeaderConnection)), connHdrValPartial)
233-
}
234-
235207
// URL method return underlying request URL instance.
236208
func (r *Request) URL() *url.URL {
237209
return r.Unwrap().URL
@@ -452,29 +424,6 @@ func (p *Params) FormFile(key string) (multipart.File, *multipart.FileHeader, er
452424
// Unexported methods
453425
//___________________________________
454426

455-
// identifyScheme method is to identify value of protocol value. It's is derived
456-
// one, Go language doesn't provide directly.
457-
// - `X-Forwarded-Proto` is not empty return value as is
458-
// - `http.Request.TLS` is not nil value is `https`
459-
// - `http.Request.TLS` is nil value is `http`
460-
func identifyScheme(r *http.Request) string {
461-
scheme := r.Header.Get(HeaderXForwardedProto)
462-
if scheme == "" {
463-
if r.TLS == nil {
464-
return SchemeHTTP // "http"
465-
}
466-
return SchemeHTTPS // "https"
467-
}
468-
return scheme
469-
}
470-
471-
func host(r *http.Request) string {
472-
if r.URL.Host == "" {
473-
return r.Host
474-
}
475-
return r.URL.Host
476-
}
477-
478427
func getReferer(hdr http.Header) string {
479428
referer := hdr.Get(HeaderReferer)
480429
if referer == "" {

request_test.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ func TestHTTPParseRequest(t *testing.T) {
9191
assert.Nil(t, err)
9292
assert.False(t, aahReq.IsJSONP())
9393
assert.False(t, aahReq.IsAJAX())
94-
assert.False(t, aahReq.IsWebSocket())
9594

9695
aahReq.SetAcceptContentType(nil)
9796
assert.NotNil(t, aahReq.AcceptContentType())
@@ -186,19 +185,19 @@ func TestHTTPRequestCookies(t *testing.T) {
186185

187186
func TestRequestSchemeDerived(t *testing.T) {
188187
req := httptest.NewRequest("GET", "http://127.0.0.1:8080/welcome.html", nil)
189-
scheme1 := identifyScheme(req)
188+
scheme1 := IdentifyScheme(req)
190189
assert.Equal(t, "http", scheme1)
191190

192191
req.TLS = &tls.ConnectionState{}
193-
scheme2 := identifyScheme(req)
192+
scheme2 := IdentifyScheme(req)
194193
assert.Equal(t, "https", scheme2)
195194

196195
req.Header.Set(HeaderXForwardedProto, "https")
197-
scheme3 := identifyScheme(req)
196+
scheme3 := IdentifyScheme(req)
198197
assert.Equal(t, "https", scheme3)
199198

200199
req.Header.Set(HeaderXForwardedProto, "http")
201-
scheme4 := identifyScheme(req)
200+
scheme4 := IdentifyScheme(req)
202201
assert.Equal(t, "http", scheme4)
203202
}
204203

0 commit comments

Comments
 (0)