1
0
mirror of https://github.com/labstack/echo.git synced 2025-01-12 01:22:21 +02:00

New name for repo

Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
Vishal Rana 2015-03-27 14:21:30 -07:00
parent 827177a814
commit 064a69d1dc
13 changed files with 51 additions and 352 deletions

View File

@ -1,22 +1,22 @@
# Bolt [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/labstack/bolt) [![Build Status](http://img.shields.io/travis/fatih/structs.svg?style=flat-square)](https://travis-ci.org/labstack/bolt) [![Coverage Status](http://img.shields.io/coveralls/labstack/bolt.svg?style=flat-square)](https://coveralls.io/r/labstack/bolt)
Bolt is a fast HTTP router (zero memory allocation) + micro web framework in Go.
# Echo [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/labstack/echo) [![Build Status](http://img.shields.io/travis/fatih/structs.svg?style=flat-square)](https://travis-ci.org/labstack/echo) [![Coverage Status](http://img.shields.io/coveralls/labstack/echo.svg?style=flat-square)](https://coveralls.io/r/labstack/echo)
Echo is a fast HTTP router (zero memory allocation) + micro web framework in Go.
### Features
- Zippy router.
- Extensible middleware / handler, supports:
- Middleware
- `func(bolt.HandlerFunc) bolt.HandlerFunc`
- `func(echo.HandlerFunc) echo.HandlerFunc`
- `http.HandlerFunc`
- `http.Handler`
- `func(http.Handler) http.Handler`
- Handler
- `func(*bolt.Context)`
- `func(*echo.Context)`
- `http.HandlerFunc`
- `http.Handler`
- Serve static files, including index.
### Example
https://github.com/labstack/bolt/tree/master/example
https://github.com/labstack/echo/tree/master/example
```go
package main
@ -24,8 +24,8 @@ package main
import (
"net/http"
"github.com/labstack/bolt"
mw "github.com/labstack/bolt/middleware"
"github.com/labstack/echo"
mw "github.com/labstack/echo/middleware"
"github.com/rs/cors"
"github.com/thoas/stats"
)
@ -46,7 +46,7 @@ func init() {
}
}
func createUser(c *bolt.Context) {
func createUser(c *echo.Context) {
u := new(user)
if c.Bind(u) {
users[u.ID] = *u
@ -54,16 +54,16 @@ func createUser(c *bolt.Context) {
}
}
func getUsers(c *bolt.Context) {
func getUsers(c *echo.Context) {
c.JSON(http.StatusOK, users)
}
func getUser(c *bolt.Context) {
func getUser(c *echo.Context) {
c.JSON(http.StatusOK, users[c.P(0)])
}
func main() {
b := bolt.New()
b := echo.New()
//*************************//
// Built-in middleware //
@ -80,7 +80,7 @@ func main() {
s := stats.New()
b.Use(s.Handler)
// Route
b.Get("/stats", func(c *bolt.Context) {
b.Get("/stats", func(c *echo.Context) {
c.JSON(200, s.Data())
})
@ -109,7 +109,7 @@ Based on [julienschmidt/go-http-routing-benchmark] (https://github.com/vishr/go-
BenchmarkAce_GithubAll 20000 70743 ns/op 13792 B/op 167 allocs/op
BenchmarkBear_GithubAll 10000 251638 ns/op 79952 B/op 943 allocs/op
BenchmarkBeego_GithubAll 3000 485840 ns/op 146272 B/op 2092 allocs/op
BenchmarkBolt_GithubAll 30000 49183 ns/op 0 B/op 0 allocs/op
BenchmarkEcho_GithubAll 30000 49183 ns/op 0 B/op 0 allocs/op
BenchmarkBone_GithubAll 1000 2167949 ns/op 648016 B/op 8119 allocs/op
BenchmarkDenco_GithubAll 20000 82404 ns/op 20224 B/op 167 allocs/op
BenchmarkGin_GithubAll 20000 72831 ns/op 13792 B/op 167 allocs/op

228
bolt.go
View File

@ -1,228 +0,0 @@
package bolt
import (
"log"
"net/http"
"sync"
)
type (
Bolt struct {
Router *router
middleware []MiddlewareFunc
maxParam byte
notFoundHandler HandlerFunc
methodNotAllowedHandler HandlerFunc
internalServerErrorHandler HandlerFunc
pool sync.Pool
}
Handler interface{}
HandlerFunc func(*Context)
Middleware interface{}
MiddlewareFunc func(HandlerFunc) HandlerFunc
)
const (
MIMEJSON = "application/json"
HeaderAccept = "Accept"
HeaderContentDisposition = "Content-Disposition"
HeaderContentLength = "Content-Length"
HeaderContentType = "Content-Type"
)
// New creates a bolt instance.
func New() (b *Bolt) {
b = &Bolt{
maxParam: 5,
notFoundHandler: func(c *Context) {
http.Error(c.Response, http.StatusText(http.StatusNotFound), http.StatusNotFound)
// c.Halt()
},
methodNotAllowedHandler: func(c *Context) {
http.Error(c.Response, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
// c.Halt()
},
internalServerErrorHandler: func(c *Context) {
http.Error(c.Response, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
// c.Halt()
},
}
b.Router = NewRouter(b)
b.pool.New = func() interface{} {
return &Context{
Response: &response{},
params: make(Params, b.maxParam),
store: make(store),
// i: -1,
bolt: b,
}
}
return
}
// NOP
func (h HandlerFunc) ServeHTTP(r http.ResponseWriter, w *http.Request) {
}
// func (b *Bolt) Sub(prefix string, m ...MiddlewareFunc) *Bolt {
// return &Bolt{
// prefix: b.prefix + prefix,
// middleware: append(b.handlers, handlers...),
// }
// }
// MaxParam sets the max path params allowed. Default is 5, good enough for
// many users.
func (b *Bolt) MaxParam(n uint8) {
b.maxParam = n
}
// NotFoundHandler sets a custom NotFound handler.
func (b *Bolt) NotFoundHandler(h Handler) {
b.notFoundHandler = wrapH(h)
}
// MethodNotAllowedHandler sets a custom MethodNotAllowed handler.
func (b *Bolt) MethodNotAllowedHandler(h Handler) {
b.methodNotAllowedHandler = wrapH(h)
}
// InternalServerErrorHandler sets a custom InternalServerError handler.
func (b *Bolt) InternalServerErrorHandler(h Handler) {
b.internalServerErrorHandler = wrapH(h)
}
// Use adds handler to the middleware chain.
func (b *Bolt) Use(m ...Middleware) {
for _, h := range m {
b.middleware = append(b.middleware, wrapM(h))
}
}
// Connect adds a CONNECT route > handler to the router.
func (b *Bolt) Connect(path string, h Handler) {
b.Router.Add("CONNECT", path, wrapH(h))
}
// Delete adds a DELETE route > handler to the router.
func (b *Bolt) Delete(path string, h Handler) {
b.Router.Add("DELETE", path, wrapH(h))
}
// Get adds a GET route > handler to the router.
func (b *Bolt) Get(path string, h Handler) {
b.Router.Add("GET", path, wrapH(h))
}
// Head adds a HEAD route > handler to the router.
func (b *Bolt) Head(path string, h Handler) {
b.Router.Add("HEAD", path, wrapH(h))
}
// Options adds an OPTIONS route > handler to the router.
func (b *Bolt) Options(path string, h Handler) {
b.Router.Add("OPTIONS", path, wrapH(h))
}
// Patch adds a PATCH route > handler to the router.
func (b *Bolt) Patch(path string, h Handler) {
b.Router.Add("PATCH", path, wrapH(h))
}
// Post adds a POST route > handler to the router.
func (b *Bolt) Post(path string, h Handler) {
b.Router.Add("POST", path, wrapH(h))
}
// Put adds a PUT route > handler to the router.
func (b *Bolt) Put(path string, h Handler) {
b.Router.Add("PUT", path, wrapH(h))
}
// Trace adds a TRACE route > handler to the router.
func (b *Bolt) Trace(path string, h Handler) {
b.Router.Add("TRACE", path, wrapH(h))
}
// Static serves static files.
func (b *Bolt) Static(path, root string) {
fs := http.StripPrefix(path, http.FileServer(http.Dir(root)))
b.Get(path+"/*", func(c *Context) {
fs.ServeHTTP(c.Response, c.Request)
})
}
// ServeFile serves a file.
func (b *Bolt) ServeFile(path, file string) {
b.Get(path, func(c *Context) {
http.ServeFile(c.Response, c.Request, file)
})
}
// Index serves index file.
func (b *Bolt) Index(file string) {
b.ServeFile("/", file)
}
func (b *Bolt) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
h, c, s := b.Router.Find(r.Method, r.URL.Path)
c.reset(rw, r)
if h != nil {
// Middleware
for i := len(b.middleware) - 1; i >= 0; i-- {
h = b.middleware[i](h)
}
// Handler
h(c)
} else {
if s == NotFound {
b.notFoundHandler(c)
} else if s == NotAllowed {
b.methodNotAllowedHandler(c)
}
}
b.pool.Put(c)
}
func (b *Bolt) Run(addr string) {
log.Fatal(http.ListenAndServe(addr, b))
}
// wraps Middleware
func wrapM(m Middleware) MiddlewareFunc {
switch m := m.(type) {
case func(HandlerFunc) HandlerFunc:
return MiddlewareFunc(m)
case http.HandlerFunc, func(http.ResponseWriter, *http.Request), http.Handler:
return func(h HandlerFunc) HandlerFunc {
return func(c *Context) {
m.(http.Handler).ServeHTTP(c.Response, c.Request)
h(c)
}
}
case func(http.Handler) http.Handler:
return func(h HandlerFunc) HandlerFunc {
return func(c *Context) {
m(h).ServeHTTP(c.Response, c.Request)
h(c)
}
}
default:
panic("bolt: unknown middleware")
}
}
// wraps Handler
func wrapH(h Handler) HandlerFunc {
switch h := h.(type) {
case func(*Context):
return HandlerFunc(h)
case http.HandlerFunc, func(http.ResponseWriter, *http.Request), http.Handler:
return func(c *Context) {
h.(http.Handler).ServeHTTP(c.Response, c.Request)
}
default:
panic("bolt: unknown handler")
}
}

View File

@ -1,73 +0,0 @@
package bolt
import (
"encoding/binary"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"testing"
)
type (
user struct {
ID string
Name string
}
)
var u = user{
ID: "1",
Name: "Joe",
}
func TestBoltMaxParam(t *testing.T) {
b := New()
b.MaxParam(8)
if b.maxParam != 8 {
t.Errorf("max param should be 8, found %d", b.maxParam)
}
}
func TestBoltIndex(t *testing.T) {
b := New()
b.Index("example/public/index.html")
r, _ := http.NewRequest("GET", "/", nil)
w := httptest.NewRecorder()
b.ServeHTTP(w, r)
if w.Code != 200 {
t.Errorf("status code should be 200, found %d", w.Code)
}
}
func TestBoltStatic(t *testing.T) {
b := New()
b.Static("/js", "example/public/js")
r, _ := http.NewRequest("GET", "/js/main.js", nil)
w := httptest.NewRecorder()
b.ServeHTTP(w, r)
if w.Code != 200 {
t.Errorf("status code should be 200, found %d", w.Code)
}
}
func verifyUser(rd io.Reader, t *testing.T) {
var l int64
err := binary.Read(rd, binary.BigEndian, &l) // Body length
if err != nil {
t.Fatal(err)
}
bd := io.LimitReader(rd, l) // Body
u2 := new(user)
dec := json.NewDecoder(bd)
err = dec.Decode(u2)
if err != nil {
t.Fatal(err)
}
if u2.ID != u.ID {
t.Errorf("user id should be %s, found %s", u.ID, u2.ID)
}
if u2.Name != u.Name {
t.Errorf("user name should be %s, found %s", u.Name, u2.Name)
}
}

View File

@ -1,4 +1,4 @@
package bolt
package echo
import (
"encoding/json"
@ -15,7 +15,7 @@ type (
Response *response
params Params
store map[string]interface{}
bolt *Bolt
echo *Echo
}
store map[string]interface{}
)
@ -41,7 +41,7 @@ func (c *Context) Bind(i interface{}) bool {
// TODO:
}
if err != nil {
c.bolt.internalServerErrorHandler(c)
c.echo.internalServerErrorHandler(c)
return false
}
return true
@ -53,7 +53,7 @@ func (c *Context) JSON(n int, i interface{}) {
c.Response.Header().Set(HeaderContentType, MIMEJSON+"; charset=utf-8")
c.Response.WriteHeader(n)
if err := enc.Encode(i); err != nil {
c.bolt.internalServerErrorHandler(c)
c.echo.internalServerErrorHandler(c)
}
}

View File

@ -1,4 +1,4 @@
package bolt
package echo
import "testing"

View File

@ -3,8 +3,8 @@ package main
import (
"net/http"
"github.com/labstack/bolt"
mw "github.com/labstack/bolt/middleware"
"github.com/labstack/echo"
mw "github.com/labstack/echo/middleware"
"github.com/rs/cors"
"github.com/thoas/stats"
)
@ -25,7 +25,7 @@ func init() {
}
}
func createUser(c *bolt.Context) {
func createUser(c *echo.Context) {
u := new(user)
if c.Bind(u) {
users[u.ID] = *u
@ -33,16 +33,16 @@ func createUser(c *bolt.Context) {
}
}
func getUsers(c *bolt.Context) {
func getUsers(c *echo.Context) {
c.JSON(http.StatusOK, users)
}
func getUser(c *bolt.Context) {
func getUser(c *echo.Context) {
c.JSON(http.StatusOK, users[c.P(0)])
}
func main() {
b := bolt.New()
b := echo.New()
//*************************//
// Built-in middleware //
@ -59,7 +59,7 @@ func main() {
s := stats.New()
b.Use(s.Handler)
// Route
b.Get("/stats", func(c *bolt.Context) {
b.Get("/stats", func(c *echo.Context) {
c.JSON(200, s.Data())
})

View File

@ -2,10 +2,10 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bolt</title>
<title>Echo</title>
</head>
<body>
Hello, Bolt!
Hello, Echo!
<script src="/js/main.js"></script>
</body>
</html>

View File

@ -1 +1 @@
console.log("Hello, Bolt!")
console.log("Hello, Echo!")

View File

@ -6,24 +6,24 @@ import (
"strings"
"github.com/dgrijalva/jwt-go"
"github.com/labstack/bolt"
"github.com/labstack/echo"
)
type (
BasicAuthFunc func(string, string) bool
AuthorizedHandler bolt.HandlerFunc
UnauthorizedHandler func(*bolt.Context, error)
AuthorizedHandler echo.HandlerFunc
UnauthorizedHandler func(*echo.Context, error)
JwtKeyFunc func(string) ([]byte, error)
Claims map[string]interface{}
)
var (
ErrBasicAuth = errors.New("bolt: basic auth error")
ErrJwtAuth = errors.New("bolt: jwt auth error")
ErrBasicAuth = errors.New("echo: basic auth error")
ErrJwtAuth = errors.New("echo: jwt auth error")
)
func BasicAuth(ah AuthorizedHandler, uah UnauthorizedHandler, fn BasicAuthFunc) bolt.HandlerFunc {
return func(c *bolt.Context) {
func BasicAuth(ah AuthorizedHandler, uah UnauthorizedHandler, fn BasicAuthFunc) echo.HandlerFunc {
return func(c *echo.Context) {
auth := strings.Fields(c.Request.Header.Get("Authorization"))
if len(auth) == 2 {
scheme := auth[0]
@ -44,8 +44,8 @@ func BasicAuth(ah AuthorizedHandler, uah UnauthorizedHandler, fn BasicAuthFunc)
}
}
func JwtAuth(ah AuthorizedHandler, uah UnauthorizedHandler, fn JwtKeyFunc) bolt.HandlerFunc {
return func(c *bolt.Context) {
func JwtAuth(ah AuthorizedHandler, uah UnauthorizedHandler, fn JwtKeyFunc) echo.HandlerFunc {
return func(c *echo.Context) {
auth := strings.Fields(c.Request.Header.Get("Authorization"))
if len(auth) == 2 {
t, err := jwt.Parse(auth[1], func(token *jwt.Token) (interface{}, error) {

View File

@ -4,12 +4,12 @@ import (
"log"
"time"
"github.com/labstack/bolt"
"github.com/labstack/echo"
"github.com/labstack/gommon/color"
)
func Logger(h bolt.HandlerFunc) bolt.HandlerFunc {
return bolt.HandlerFunc(func(c *bolt.Context) {
func Logger(h echo.HandlerFunc) echo.HandlerFunc {
return echo.HandlerFunc(func(c *echo.Context) {
start := time.Now()
h(c)
end := time.Now()

View File

@ -1,4 +1,4 @@
package bolt
package echo
import (
"bufio"
@ -22,7 +22,7 @@ func (r *response) WriteHeader(n int) {
// TODO: fix when halted.
if r.committed {
// TODO: Warning
log.Println("bolt: response already committed")
log.Println("echo: response already committed")
return
}
r.status = n

View File

@ -1,4 +1,4 @@
package bolt
package echo
import (
"fmt"
@ -8,7 +8,7 @@ import (
type (
router struct {
root *node
bolt *Bolt
echo *Echo
}
node struct {
label byte
@ -52,14 +52,14 @@ var methods = map[string]uint8{
"TRACE": 8,
}
func NewRouter(b *Bolt) (r *router) {
func NewRouter(b *Echo) (r *router) {
r = &router{
root: &node{
prefix: "",
handlers: make([]HandlerFunc, len(methods)),
edges: edges{},
},
bolt: b,
echo: b,
}
return
}
@ -173,7 +173,7 @@ func newNode(pfx string, has ntype, h []HandlerFunc, e edges) (n *node) {
}
func (r *router) Find(method, path string) (handler HandlerFunc, c *Context, s Status) {
c = r.bolt.pool.Get().(*Context)
c = r.echo.pool.Get().(*Context)
cn := r.root // Current node
search := path
n := 0 // Param count
@ -257,12 +257,12 @@ func (r *router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
h(c)
} else {
if rep == NotFound {
r.bolt.notFoundHandler(c)
r.echo.notFoundHandler(c)
} else if rep == NotAllowed {
r.bolt.methodNotAllowedHandler(c)
r.echo.methodNotAllowedHandler(c)
}
}
r.bolt.pool.Put(c)
r.echo.pool.Put(c)
}
// Get returns path parameter by name.

View File

@ -1,4 +1,4 @@
package bolt
package echo
import "testing"