Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
manucorporat committed May 22, 2015
2 parents bd2c864 + 66fa43f commit 9163ee5
Show file tree
Hide file tree
Showing 68 changed files with 6,010 additions and 1,679 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Godeps/*
!Godeps/Godeps.json
coverage.out
count.out
16 changes: 15 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
language: go
sudo: false
go:
- 1.3
- 1.4
- 1.4.2
- tip

script:
- go get golang.org/x/tools/cmd/cover
- go get github.com/mattn/goveralls
- go test -v -covermode=count -coverprofile=coverage.out
- goveralls -coverprofile=coverage.out -service=travis-ci -repotoken yFj7FrCeddvBzUaaCyG33jCLfWXeb93eA

notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/acc2c57482e94b44f557
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: false # default: false
3 changes: 1 addition & 2 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ List of all the awesome people working to make Gin the best Web Framework in Go.

##gin 0.x series authors

**Original Developer:** Manu Martinez-Almeida (@manucorporat)
**Long-term Maintainer:** Javier Provecho (@javierprovecho)
**Maintainer:** Manu Martinez-Almeida (@manucorporat), Javier Provecho (@javierprovecho)

People and companies, who have contributed, in alphabetical order.

Expand Down
52 changes: 48 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,55 @@
#Changelog

###Gin 1.0rc1 (May 22, 2015)

- [PERFORMANCE] Zero allocation router
- [PERFORMANCE] Faster JSON, XML and text rendering
- [PERFORMANCE] Custom hand optimized HttpRouter for Gin
- [PERFORMANCE] Misc code optimizations. Inlining, tail call optimizations
- [NEW] Built-in support for golang.org/x/net/context
- [NEW] Any(path, handler). Create a route that matches any path
- [NEW] Refactored rendering pipeline (faster and static typeded)
- [NEW] Refactored errors API
- [NEW] IndentedJSON() prints pretty JSON
- [NEW] Added gin.DefaultWriter
- [NEW] UNIX socket support
- [NEW] RouterGroup.BasePath is exposed
- [NEW] JSON validation using go-validate-yourself (very powerful options)
- [NEW] Completed suite of unit tests
- [NEW] HTTP streaming with c.Stream()
- [NEW] StaticFile() creates a router for serving just one file.
- [NEW] StaticFS() has an option to disable directory listing.
- [NEW] StaticFS() for serving static files through virtual filesystems
- [NEW] Server-Sent Events native support
- [NEW] WrapF() and WrapH() helpers for wrapping http.HandlerFunc and http.Handler
- [NEW] Added LoggerWithWriter() middleware
- [NEW] Added RecoveryWithWriter() middleware
- [NEW] Added DefaultPostFormValue()
- [NEW] Added DefaultFormValue()
- [NEW] Added DefaultParamValue()
- [FIX] BasicAuth() when using custom realm
- [FIX] Bug when serving static files in nested routing group
- [FIX] Redirect using built-in http.Redirect()
- [FIX] Logger when printing the requested path
- [FIX] Documentation typos
- [FIX] Context.Engine renamed to Context.engine
- [FIX] Better debugging messages
- [FIX] ErrorLogger
- [FIX] Debug HTTP render
- [FIX] Refactored binding and render modules
- [FIX] Refactored Context initialization
- [FIX] Refactored BasicAuth()
- [FIX] NoMethod/NoRoute handlers
- [FIX] Hijacking http
- [FIX] Better support for Google App Engine (using log instead of fmt)


###Gin 0.6 (Mar 9, 2015)

- [ADD] Support multipart/form-data
- [ADD] NoMethod handler
- [ADD] Validate sub structures
- [ADD] Support for HTTP Realm Auth
- [NEW] Support multipart/form-data
- [NEW] NoMethod handler
- [NEW] Validate sub structures
- [NEW] Support for HTTP Realm Auth
- [FIX] Unsigned integers in binding
- [FIX] Improve color logger

Expand Down
23 changes: 20 additions & 3 deletions Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 3 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Gin Web Framework [![GoDoc](https://godoc.org/github.com/gin-gonic/gin?status.svg)](https://godoc.org/github.com/gin-gonic/gin) [![Build Status](https://travis-ci.org/gin-gonic/gin.svg)](https://travis-ci.org/gin-gonic/gin)
#Gin Web Framework [![Build Status](https://travis-ci.org/gin-gonic/gin.svg)](https://travis-ci.org/gin-gonic/gin) [![Coverage Status](https://coveralls.io/repos/gin-gonic/gin/badge.svg?branch=develop)](https://coveralls.io/r/gin-gonic/gin?branch=develop)

[![Join the chat at https://gitter.im/gin-gonic/gin](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gin-gonic/gin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![GoDoc](https://godoc.org/github.com/gin-gonic/gin?status.svg)](https://godoc.org/github.com/gin-gonic/gin) [![Join the chat at https://gitter.im/gin-gonic/gin](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gin-gonic/gin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

Gin is a web framework written in Golang. It features a martini-like API with much better performance, up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin.

Expand Down Expand Up @@ -29,7 +29,7 @@ func main() {
c.String(http.StatusUnauthorized, "not authorized")
})
router.PUT("/error", func(c *gin.Context) {
c.String(http.StatusInternalServerError, "and error happened :(")
c.String(http.StatusInternalServerError, "an error happened :(")
})
router.Run(":8080")
}
Expand Down Expand Up @@ -72,18 +72,6 @@ Then import it in your Go code:
import "github.com/gin-gonic/gin"
```


##Community
If you'd like to help out with the project, there's a mailing list and IRC channel where Gin discussions normally happen.

* IRC
* [irc.freenode.net #getgin](irc://irc.freenode.net:6667/getgin)
* [Webchat](http://webchat.freenode.net?randomnick=1&channels=%23getgin)
* Mailing List
* Subscribe: [[email protected]](mailto:[email protected])
* [Archives](http://librelist.com/browser/getgin/)


##API Examples

#### Create most basic PING/PONG HTTP endpoint
Expand Down
69 changes: 31 additions & 38 deletions auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ package gin
import (
"crypto/subtle"
"encoding/base64"
"errors"
"fmt"
"sort"
"strconv"
)

const (
Expand All @@ -25,31 +23,37 @@ type (
authPairs []authPair
)

func (a authPairs) Len() int { return len(a) }
func (a authPairs) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a authPairs) Less(i, j int) bool { return a[i].Value < a[j].Value }
func (a authPairs) searchCredential(authValue string) (string, bool) {
if len(authValue) == 0 {
return "", false
}
for _, pair := range a {
if pair.Value == authValue {
return pair.User, true
}
}
return "", false
}

// Implements a basic Basic HTTP Authorization. It takes as arguments a map[string]string where
// the key is the user name and the value is the password, as well as the name of the Realm
// (see http://tools.ietf.org/html/rfc2617#section-1.2)
func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc {
pairs, err := processAccounts(accounts)
if err != nil {
panic(err)
if realm == "" {
realm = "Authorization Required"
}
realm = "Basic realm=" + strconv.Quote(realm)
pairs := processAccounts(accounts)
return func(c *Context) {
// Search user in the slice of allowed credentials
user, ok := searchCredential(pairs, c.Request.Header.Get("Authorization"))
if !ok {
// Credentials doesn't match, we return 401 Unauthorized and abort request.
if realm == "" {
realm = "Authorization Required"
}
c.Writer.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=\"%s\"", realm))
c.Fail(401, errors.New("Unauthorized"))
user, found := pairs.searchCredential(c.Request.Header.Get("Authorization"))
if !found {
// Credentials doesn't match, we return 401 and abort handlers chain.
c.Header("WWW-Authenticate", realm)
c.AbortWithStatus(401)
} else {
// user is allowed, set UserId to key "user" in this context, the userId can be read later using
// c.Get(gin.AuthUserKey)
// The user credentials was found, set user's id to key AuthUserKey in this context, the userId can be read later using
// c.MustGet(gin.AuthUserKey)
c.Set(AuthUserKey, user)
}
}
Expand All @@ -61,38 +65,27 @@ func BasicAuth(accounts Accounts) HandlerFunc {
return BasicAuthForRealm(accounts, "")
}

func processAccounts(accounts Accounts) (authPairs, error) {
func processAccounts(accounts Accounts) authPairs {
if len(accounts) == 0 {
return nil, errors.New("Empty list of authorized credentials")
panic("Empty list of authorized credentials")
}
pairs := make(authPairs, 0, len(accounts))
for user, password := range accounts {
if len(user) == 0 {
return nil, errors.New("User can not be empty")
panic("User can not be empty")
}
base := user + ":" + password
value := "Basic " + base64.StdEncoding.EncodeToString([]byte(base))
value := authorizationHeader(user, password)
pairs = append(pairs, authPair{
Value: value,
User: user,
})
}
// We have to sort the credentials in order to use bsearch later.
sort.Sort(pairs)
return pairs, nil
return pairs
}

func searchCredential(pairs authPairs, auth string) (string, bool) {
if len(auth) == 0 {
return "", false
}
// Search user in the slice of allowed credentials
r := sort.Search(len(pairs), func(i int) bool { return pairs[i].Value >= auth })
if r < len(pairs) && secureCompare(pairs[r].Value, auth) {
return pairs[r].User, true
} else {
return "", false
}
func authorizationHeader(user, password string) string {
base := user + ":" + password
return "Basic " + base64.StdEncoding.EncodeToString([]byte(base))
}

func secureCompare(given, actual string) bool {
Expand Down
Loading

0 comments on commit 9163ee5

Please sign in to comment.