Skip to content

Commit

Permalink
Added headers capabilities and CORS default headers
Browse files Browse the repository at this point in the history
  • Loading branch information
eko committed Jan 8, 2017
1 parent 8d66923 commit 20ffdc2
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 22 deletions.
33 changes: 28 additions & 5 deletions README.md
@@ -1,10 +1,10 @@
Gofast - A simple Go micro-framework
====================================
Gofast - A light, fast and simple Go micro-framework
====================================================

[![GoDoc](https://godoc.org/github.com/eko/gofast?status.png)](https://godoc.org/github.com/eko/gofast)
[![Build Status](https://secure.travis-ci.org/eko/gofast.png?branch=master)](http://travis-ci.org/eko/gofast)

This is a micro-framework I wrote in order to train to Golang language.
This is a light and fast micro-framework I wrote in order to train to Go language.

This project uses "pongo2" library for rendering templates (compatible with Django Jinja templates)

Expand Down Expand Up @@ -55,12 +55,12 @@ func main() {
})

// You can add a simple GET route
app.Get("homepage", "/", func(context gofast.Context) {
app.Get("homepage", "/$", func(context gofast.Context) {
app.Render(context, "index.html")
})

// ... or add a more complex POST route with a URL parameter
app.Post("add", "/add/([a-zA-Z]+)", func(context gofast.Context) {
app.Post("add", "/add/([a-zA-Z]+)$", func(context gofast.Context) {
request := context.GetRequest()

pattern := request.GetRoute().GetPattern()
Expand Down Expand Up @@ -114,3 +114,26 @@ Using the example given below, here is the request results:
<h2>Retrieve a "data" POST form value</h2>
<p>my post data</p>
```

Default CORS headers
--------------------

Following CORS headers are enabled by default when the request has an "Origin" header:

```
Access-Control-Allow-Headers: Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: domainname.tld
```

You can override any header (including CORS ones) by the following way into each action:

```go
app.Get("retrieve-data", "/retrieve$", func(context gofast.Context) {
response := context.GetResponse()
response.Header().Set("Access-Control-Allow-Methods", "GET")
response.Header().Set("Content-Type", "application/json")

fmt.Fprint(response, "{result: 200}")
})
```
18 changes: 16 additions & 2 deletions context.go
Expand Up @@ -31,13 +31,27 @@ func (c *Context) GetRequest() *Request {

// Sets a HTTP response instance
func (c *Context) SetResponse(res http.ResponseWriter) {
res.Header().Set("Content-Type", "text/html; charset: utf-8")

response := NewResponse(res)
c.response = &response

c.AddDefaultHeaders()
}

// Returns a HTTP response component instance
func (c *Context) GetResponse() *Response {
return c.response
}

// Adds some defaults headers to send with the response
func (c *Context) AddDefaultHeaders() {
request := c.GetRequest()
response := c.GetResponse()

response.Header().Set("Content-Type", "text/html; charset: utf-8")

if origin := request.GetHeader("Origin"); origin != "" {
response.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
response.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
response.Header().Set("Access-Control-Allow-Origin", origin)
}
}
37 changes: 22 additions & 15 deletions gofast.go
Expand Up @@ -55,26 +55,33 @@ func (g *Gofast) Listen() {

// Serves HTTP request by matching the correct route
func (g *Gofast) ServeHTTP(res http.ResponseWriter, req *http.Request) {
fallbackRoute := g.GetFallback()
matchedRoute := g.GetFallback()

for _, route := range g.GetRoutes() {
if req.Method == route.method && route.pattern.MatchString(req.URL.Path) {
context := NewContext()
context.SetRequest(req, route)
context.SetResponse(res)
if "fallback" == route.name {
continue
}

if (route.method == req.Method || "*" == route.method) && route.pattern.MatchString(req.URL.Path) {
matchedRoute = route
break
}
}

startTime := time.Now()
g.HandleRoute(res, req, matchedRoute)
}

if fallbackRoute.name == "fallback" && req.URL.Path != "/" && route.pattern.String() == "/" {
route = fallbackRoute
}
// Handles a route with the initialized context
func (g *Gofast) HandleRoute(res http.ResponseWriter, req *http.Request, route Route) {
startTime := time.Now()

route.handler(context)
context := NewContext()
context.SetRequest(req, route)
context.SetResponse(res)

stopTime := time.Now()
route.handler(context)

log.Printf("[%s] %v | route: '%s' | url: %q (time: %v)\n", req.Method, context.GetResponse().GetStatusCode(), route.name, req.URL.String(), stopTime.Sub(startTime))
break
}
}
stopTime := time.Now()

log.Printf("[%s] %v | route: '%s' | url: %q (time: %v)\n", req.Method, context.GetResponse().GetStatusCode(), route.name, req.URL.String(), stopTime.Sub(startTime))
}
5 changes: 5 additions & 0 deletions request.go
Expand Up @@ -58,3 +58,8 @@ func (r *Request) GetParameter(name string) interface{} {
func (r *Request) GetFormValue(name string) interface{} {
return r.httpRequest.FormValue(name)
}

// Returns a request header from its name
func (r *Request) GetHeader(name string) string {
return r.GetHttpRequest().Header.Get(name)
}
14 changes: 14 additions & 0 deletions request_test.go
Expand Up @@ -40,3 +40,17 @@ func TestParameters(t *testing.T) {
t.Fail()
}
}

// Tests retrieving a header
func TestGetHeader(t *testing.T) {
httpRequest, _ := http.NewRequest("GET", "/", nil)
httpRequest.Header.Set("X-Test-Header", "yes")

route := Route{"GET", "test", regexp.MustCompile("/test"), func(c Context) {}}

request := NewRequest(httpRequest, route)

if request.GetHeader("X-Test-Header") != "yes" {
t.Fail()
}
}

0 comments on commit 20ffdc2

Please sign in to comment.