Skip to content

Commit

Permalink
Merge pull request #7 for v0.6 Release
Browse files Browse the repository at this point in the history
  • Loading branch information
jeevatkm committed May 9, 2017
2 parents e4c1354 + 27e9274 commit 1159888
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 68 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ahttp - aah framework
[![Build Status](https://travis-ci.org/go-aah/ahttp.svg?branch=master)](https://travis-ci.org/go-aah/ahttp) [![codecov](https://codecov.io/gh/go-aah/ahttp/branch/master/graph/badge.svg)](https://codecov.io/gh/go-aah/ahttp/branch/master) [![Go Report Card](https://goreportcard.com/badge/aahframework.org/ahttp.v0)](https://goreportcard.com/report/aahframework.org/ahttp.v0) [![Version](https://img.shields.io/badge/version-0.5-blue.svg)](https://github.com/go-aah/ahttp/releases/latest) [![GoDoc](https://godoc.org/aahframework.org/ahttp.v0?status.svg)](https://godoc.org/aahframework.org/ahttp.v0) [![License](https://img.shields.io/github/license/go-aah/ahttp.svg)](LICENSE)
[![Build Status](https://travis-ci.org/go-aah/ahttp.svg?branch=master)](https://travis-ci.org/go-aah/ahttp) [![codecov](https://codecov.io/gh/go-aah/ahttp/branch/master/graph/badge.svg)](https://codecov.io/gh/go-aah/ahttp/branch/master) [![Go Report Card](https://goreportcard.com/badge/aahframework.org/ahttp.v0)](https://goreportcard.com/report/aahframework.org/ahttp.v0) [![Version](https://img.shields.io/badge/version-0.6-blue.svg)](https://github.com/go-aah/ahttp/releases/latest) [![GoDoc](https://godoc.org/aahframework.org/ahttp.v0?status.svg)](https://godoc.org/aahframework.org/ahttp.v0) [![License](https://img.shields.io/github/license/go-aah/ahttp.svg)](LICENSE)

***v0.5 [released](https://github.com/go-aah/ahttp/releases/latest) and tagged on May 07, 2017***
***v0.6 [released](https://github.com/go-aah/ahttp/releases/latest) and tagged on May 08, 2017***

HTTP Library built to process, manipulate Request and Response (headers, body, gzip, etc).

Expand Down
10 changes: 9 additions & 1 deletion ahttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
// Like parse HTTP headers, ResponseWriter, content type, etc.
package ahttp

import "net/http"

// Version no. of aah framework ahttp library
const Version = "0.5"
const Version = "0.6"

// HTTP Method names
const (
Expand All @@ -22,6 +24,12 @@ const (
MethodTrace = "TRACE"
)

// TimeFormat is the time format to use when generating times in HTTP
// headers. It is like time.RFC1123 but hard-codes GMT as the time
// zone. The time being formatted must be in UTC for Format to
// generate the correct format.
const TimeFormat = http.TimeFormat

type (
// Locale value is negotiated from HTTP header `Accept-Language`
Locale struct {
Expand Down
107 changes: 64 additions & 43 deletions header.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,49 +17,70 @@ import (

// HTTP Header names
const (
HeaderAccept = "Accept"
HeaderAcceptEncoding = "Accept-Encoding"
HeaderAcceptLanguage = "Accept-Language"
HeaderAllow = "Allow"
HeaderAuthorization = "Authorization"
HeaderCacheControl = "Cache-Control"
HeaderConnection = "Connection"
HeaderContentDisposition = "Content-Disposition"
HeaderContentEncoding = "Content-Encoding"
HeaderContentLength = "Content-Length"
HeaderContentType = "Content-Type"
HeaderContentSecurityPolicy = "Content-Security-Policy"
HeaderCookie = "Cookie"
HeaderHost = "Host"
HeaderIfModifiedSince = "If-Modified-Since"
HeaderIfUnmodifiedSince = "If-Unmodified-Since"
HeaderLocation = "Location"
HeaderLastModified = "Last-Modified"
HeaderMethod = "Method"
HeaderReferer = "Referer"
HeaderServer = "Server"
HeaderSetCookie = "Set-Cookie"
HeaderStatus = "Status"
HeaderStrictTransportSecurity = "Strict-Transport-Security"
HeaderOrigin = "Origin"
HeaderTransferEncoding = "Transfer-Encoding"
HeaderUpgrade = "Upgrade"
HeaderUserAgent = "User-Agent"
HeaderVary = "Vary"
HeaderWWWAuthenticate = "WWW-Authenticate"
HeaderXContentTypeOptions = "X-Content-Type-Options"
HeaderXCSRFToken = "X-CSRF-Token"
HeaderXForwardedFor = "X-Forwarded-For"
HeaderXForwardedHost = "X-Forwarded-Host"
HeaderXForwardedPort = "X-Forwarded-Port"
HeaderXForwardedProto = "X-Forwarded-Proto"
HeaderXForwardedServer = "X-Forwarded-Server"
HeaderXFrameOptions = "X-Frame-Options"
HeaderXHTTPMethodOverride = "X-HTTP-Method-Override"
HeaderXRealIP = "X-Real-Ip"
HeaderXRequestedWith = "X-Requested-With"
HeaderXRequestID = "X-Request-Id"
HeaderXXSSProtection = "X-XSS-Protection"
HeaderAccept = "Accept"
HeaderAcceptEncoding = "Accept-Encoding"
HeaderAcceptLanguage = "Accept-Language"
HeaderAcceptRanges = "Accept-Ranges"
HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"
HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers"
HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods"
HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin"
HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers"
HeaderAccessControlMaxAge = "Access-Control-Max-Age"
HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers"
HeaderAccessControlRequestMethod = "Access-Control-Request-Method"
HeaderAge = "Age"
HeaderAllow = "Allow"
HeaderAuthorization = "Authorization"
HeaderCacheControl = "Cache-Control"
HeaderConnection = "Connection"
HeaderContentDisposition = "Content-Disposition"
HeaderContentEncoding = "Content-Encoding"
HeaderContentLength = "Content-Length"
HeaderContentType = "Content-Type"
HeaderContentSecurityPolicy = "Content-Security-Policy"
HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only"
HeaderCookie = "Cookie"
HeaderDate = "Date"
HeaderETag = "ETag"
HeaderExpires = "Expires"
HeaderHost = "Host"
HeaderIfMatch = "If-Match"
HeaderIfModifiedSince = "If-Modified-Since"
HeaderIfNoneMatch = "If-None-Match"
HeaderIfRange = "If-Range"
HeaderIfUnmodifiedSince = "If-Unmodified-Since"
HeaderKeepAlive = "Keep-Alive"
HeaderLastModified = "Last-Modified"
HeaderLocation = "Location"
HeaderOrigin = "Origin"
HeaderMethod = "Method"
HeaderRange = "Range"
HeaderReferer = "Referer"
HeaderRetryAfter = "Retry-After"
HeaderServer = "Server"
HeaderSetCookie = "Set-Cookie"
HeaderStatus = "Status"
HeaderStrictTransportSecurity = "Strict-Transport-Security"
HeaderTransferEncoding = "Transfer-Encoding"
HeaderUpgrade = "Upgrade"
HeaderUserAgent = "User-Agent"
HeaderVary = "Vary"
HeaderWWWAuthenticate = "WWW-Authenticate"
HeaderXContentTypeOptions = "X-Content-Type-Options"
HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control"
HeaderXCSRFToken = "X-CSRF-Token"
HeaderXForwardedFor = "X-Forwarded-For"
HeaderXForwardedHost = "X-Forwarded-Host"
HeaderXForwardedPort = "X-Forwarded-Port"
HeaderXForwardedProto = "X-Forwarded-Proto"
HeaderXForwardedServer = "X-Forwarded-Server"
HeaderXFrameOptions = "X-Frame-Options"
HeaderXHTTPMethodOverride = "X-HTTP-Method-Override"
HeaderXRealIP = "X-Real-Ip"
HeaderXRequestedWith = "X-Requested-With"
HeaderXRequestID = "X-Request-Id"
HeaderXXSSProtection = "X-XSS-Protection"
)

type (
Expand Down
68 changes: 52 additions & 16 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ import (
"aahframework.org/essentials.v0"
)

const jsonpReqParamKey = "callback"
const (
jsonpReqParamKey = "callback"
ajaxHeaderValue = "XMLHttpRequest"
)

type (
// Request is extends `http.Request` for aah framework
Request struct {
// Schema value is protocol info it's a derived value in the order as below.
// Schema value is protocol info; it's a derived value in the order as below.
// - `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`
Expand All @@ -32,7 +35,7 @@ type (
// Method request method e.g. `GET`, `POST`, etc.
Method string

// Path the request URL Path e.g. `/booking/hotel.html`.
// Path the request URL Path e.g. `/app/login.html`.
Path string

// Header request HTTP headers
Expand Down Expand Up @@ -71,14 +74,11 @@ type (
// Locale negotiated value from HTTP Header `Accept-Language`.
Locale *Locale

// IsJSONP is true if request query string has "callback=function_name".
IsJSONP bool

// IsGzipAccepted is true if the HTTP client accepts Gzip response.
// IsGzipAccepted is true if the HTTP client accepts Gzip response,
// otherwise false.
IsGzipAccepted bool

// Raw an object that Go HTTP server provied, Direct interaction with
// Raw an object of Go HTTP server, direct interaction with
// raw object is not encouraged.
Raw *http.Request
}
Expand Down Expand Up @@ -111,7 +111,6 @@ func ParseRequest(r *http.Request, req *Request) *Request {
req.UserAgent = r.Header.Get(HeaderUserAgent)
req.ClientIP = clientIP(r)
req.Locale = NegotiateLocale(r)
req.IsJSONP = isJSONPReqeust(r)
req.IsGzipAccepted = isGzipAccepted(req, r)
req.Raw = r

Expand All @@ -132,6 +131,50 @@ func (r *Request) Cookies() []*http.Cookie {
return r.Raw.Cookies()
}

// IsJSONP method returns true if request query string has "callback=function_name".
func (r *Request) IsJSONP() bool {
return !ess.IsStrEmpty(r.QueryValue(jsonpReqParamKey))
}

// IsAJAX methods returns true if the request header `X-Requested-With` is
// `XMLHttpRequest` otherwise false.
func (r *Request) IsAJAX() bool {
return r.Header.Get(HeaderXRequestedWith) == ajaxHeaderValue
}

// PathValue method return value for given Path param key otherwise empty string.
func (r *Request) PathValue(key string) string {
return r.Params.PathValue(key)
}

// QueryValue method return value for given query (aka URL) param key
// otherwise empty string.
func (r *Request) QueryValue(key string) string {
return r.Params.QueryValue(key)
}

// QueryArrayValue method return array value for given query (aka URL)
// param key otherwise empty string.
func (r *Request) QueryArrayValue(key string) []string {
return r.Params.QueryArrayValue(key)
}

// FormValue methos returns value for given form key otherwise empty string.
func (r *Request) FormValue(key string) string {
return r.Params.FormValue(key)
}

// FormArrayValue methos returns value for given form key otherwise empty string.
func (r *Request) FormArrayValue(key string) []string {
return r.Params.FormArrayValue(key)
}

// FormFile method returns the first file for the provided form key otherwise
// returns error. It is caller responsibility to close the file.
func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) {
return r.Params.FormFile(key)
}

// Reset method resets request instance for reuse.
func (r *Request) Reset() {
r.Schema = ""
Expand All @@ -148,7 +191,6 @@ func (r *Request) Reset() {
r.UserAgent = ""
r.ClientIP = ""
r.Locale = nil
r.IsJSONP = false
r.IsGzipAccepted = false
r.Raw = nil
}
Expand Down Expand Up @@ -271,12 +313,6 @@ func getReferer(hdr http.Header) string {
return referer
}

func isJSONPReqeust(r *http.Request) bool {
query := r.URL.Query()
callback := query.Get(jsonpReqParamKey)
return !ess.IsStrEmpty(callback)
}

func isGzipAccepted(req *Request, r *http.Request) bool {
specs := ParseAcceptEncoding(r)
if specs != nil {
Expand Down
14 changes: 8 additions & 6 deletions request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,24 @@ func TestHTTPParseRequest(t *testing.T) {
assert.Equal(t, "192.168.0.1", aahReq.ClientIP)
assert.Equal(t, "http://localhost:8080/home.html", aahReq.Referer)

params := aahReq.Params
// Query Value
assert.Equal(t, "true", params.QueryValue("_ref"))
assert.Equal(t, "true", aahReq.QueryValue("_ref"))
assert.Equal(t, 1, len(aahReq.QueryArrayValue("_ref")))

// Path value
assert.Equal(t, "", params.PathValue("not_exists"))
assert.Equal(t, "", aahReq.PathValue("not_exists"))

// Form value
assert.Equal(t, "", params.FormValue("no_field"))
assert.Equal(t, "", aahReq.FormValue("no_field"))
assert.Equal(t, 0, len(aahReq.FormArrayValue("no_field")))

// Form File
f, hdr, err := params.FormFile("no_file")
f, hdr, err := aahReq.FormFile("no_file")
assert.Nil(t, f)
assert.Nil(t, hdr)
assert.Nil(t, err)
assert.False(t, aahReq.IsJSONP())
assert.False(t, aahReq.IsAJAX())

// Reset it
aahReq.Reset()
Expand All @@ -91,7 +94,6 @@ func TestHTTPParseRequest(t *testing.T) {
assert.Nil(t, aahReq.Params)
assert.Nil(t, aahReq.Locale)
assert.Nil(t, aahReq.Raw)
assert.False(t, aahReq.IsJSONP)
assert.True(t, len(aahReq.UserAgent) == 0)
assert.True(t, len(aahReq.ClientIP) == 0)
}
Expand Down

0 comments on commit 1159888

Please sign in to comment.