summaryrefslogtreecommitdiffstats
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/labstack/echo/bind.go18
-rw-r--r--vendor/github.com/labstack/echo/context.go47
-rw-r--r--vendor/github.com/labstack/echo/cookbook/auto-tls/server.go26
-rw-r--r--vendor/github.com/labstack/echo/cookbook/cors/server.go38
-rw-r--r--vendor/github.com/labstack/echo/cookbook/crud/server.go75
-rw-r--r--vendor/github.com/labstack/echo/cookbook/embed-resources/server.go21
-rw-r--r--vendor/github.com/labstack/echo/cookbook/file-upload/multiple/server.go65
-rw-r--r--vendor/github.com/labstack/echo/cookbook/file-upload/single/server.go59
-rw-r--r--vendor/github.com/labstack/echo/cookbook/google-app-engine/app-engine.go17
-rw-r--r--vendor/github.com/labstack/echo/cookbook/google-app-engine/app-managed.go25
-rw-r--r--vendor/github.com/labstack/echo/cookbook/google-app-engine/app-standalone.go24
-rw-r--r--vendor/github.com/labstack/echo/cookbook/google-app-engine/app.go4
-rw-r--r--vendor/github.com/labstack/echo/cookbook/google-app-engine/users.go54
-rw-r--r--vendor/github.com/labstack/echo/cookbook/google-app-engine/welcome.go31
-rw-r--r--vendor/github.com/labstack/echo/cookbook/graceful-shutdown/grace/server.go20
-rw-r--r--vendor/github.com/labstack/echo/cookbook/graceful-shutdown/graceful/server.go21
-rw-r--r--vendor/github.com/labstack/echo/cookbook/hello-world/server.go25
-rw-r--r--vendor/github.com/labstack/echo/cookbook/http2/server.go42
-rw-r--r--vendor/github.com/labstack/echo/cookbook/jsonp/server.go35
-rw-r--r--vendor/github.com/labstack/echo/cookbook/jwt/custom-claims/server.go86
-rw-r--r--vendor/github.com/labstack/echo/cookbook/jwt/map-claims/server.go69
-rw-r--r--vendor/github.com/labstack/echo/cookbook/middleware/server.go82
-rw-r--r--vendor/github.com/labstack/echo/cookbook/streaming-response/server.go45
-rw-r--r--vendor/github.com/labstack/echo/cookbook/subdomains/server.go78
-rw-r--r--vendor/github.com/labstack/echo/cookbook/twitter/handler/handler.go14
-rw-r--r--vendor/github.com/labstack/echo/cookbook/twitter/handler/post.go73
-rw-r--r--vendor/github.com/labstack/echo/cookbook/twitter/handler/user.go97
-rw-r--r--vendor/github.com/labstack/echo/cookbook/twitter/model/post.go12
-rw-r--r--vendor/github.com/labstack/echo/cookbook/twitter/model/user.go13
-rw-r--r--vendor/github.com/labstack/echo/cookbook/twitter/server.go52
-rw-r--r--vendor/github.com/labstack/echo/cookbook/websocket/gorilla/server.go47
-rw-r--r--vendor/github.com/labstack/echo/cookbook/websocket/net/server.go41
-rw-r--r--vendor/github.com/labstack/echo/echo.go124
-rw-r--r--vendor/github.com/labstack/echo/echo_go1.8.go25
-rw-r--r--vendor/github.com/labstack/echo/group.go11
-rw-r--r--vendor/github.com/labstack/echo/middleware/basic_auth.go28
-rw-r--r--vendor/github.com/labstack/echo/middleware/compress.go4
-rw-r--r--vendor/github.com/labstack/echo/middleware/jwt.go2
-rw-r--r--vendor/github.com/labstack/echo/middleware/key_auth.go7
-rw-r--r--vendor/github.com/labstack/echo/middleware/logger.go15
-rw-r--r--vendor/github.com/labstack/echo/middleware/middleware.go2
-rw-r--r--vendor/github.com/labstack/echo/middleware/proxy.go160
-rw-r--r--vendor/github.com/labstack/echo/middleware/request_id.go64
-rw-r--r--vendor/github.com/labstack/echo/middleware/static.go39
-rw-r--r--vendor/github.com/labstack/echo/router.go49
-rw-r--r--vendor/github.com/labstack/gommon/random/random.go40
-rw-r--r--vendor/github.com/valyala/fasttemplate/unsafe.go2
-rw-r--r--vendor/github.com/valyala/fasttemplate/unsafe_gae.go11
48 files changed, 526 insertions, 1413 deletions
diff --git a/vendor/github.com/labstack/echo/bind.go b/vendor/github.com/labstack/echo/bind.go
index f2393ea6..186bd83d 100644
--- a/vendor/github.com/labstack/echo/bind.go
+++ b/vendor/github.com/labstack/echo/bind.go
@@ -30,16 +30,16 @@ type (
// Bind implements the `Binder#Bind` function.
func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
req := c.Request()
- if req.Method == GET {
- if err = b.bindData(i, c.QueryParams(), "query"); err != nil {
- return NewHTTPError(http.StatusBadRequest, err.Error())
- }
- return
- }
- ctype := req.Header.Get(HeaderContentType)
if req.ContentLength == 0 {
+ if req.Method == GET || req.Method == DELETE {
+ if err = b.bindData(i, c.QueryParams(), "query"); err != nil {
+ return NewHTTPError(http.StatusBadRequest, err.Error())
+ }
+ return
+ }
return NewHTTPError(http.StatusBadRequest, "Request body can't be empty")
}
+ ctype := req.Header.Get(HeaderContentType)
switch {
case strings.HasPrefix(ctype, MIMEApplicationJSON):
if err = json.NewDecoder(req.Body).Decode(i); err != nil {
@@ -51,7 +51,7 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
return NewHTTPError(http.StatusBadRequest, err.Error())
}
}
- case strings.HasPrefix(ctype, MIMEApplicationXML):
+ case strings.HasPrefix(ctype, MIMEApplicationXML), strings.HasPrefix(ctype, MIMETextXML):
if err = xml.NewDecoder(req.Body).Decode(i); err != nil {
if ute, ok := err.(*xml.UnsupportedTypeError); ok {
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unsupported type error: type=%v, error=%v", ute.Type, ute.Error()))
@@ -142,6 +142,8 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V
}
switch valueKind {
+ case reflect.Ptr:
+ return setWithProperType(structField.Elem().Kind(), val, structField.Elem())
case reflect.Int:
return setIntField(val, 0, structField)
case reflect.Int8:
diff --git a/vendor/github.com/labstack/echo/context.go b/vendor/github.com/labstack/echo/context.go
index 1a6ebf47..242eec26 100644
--- a/vendor/github.com/labstack/echo/context.go
+++ b/vendor/github.com/labstack/echo/context.go
@@ -31,6 +31,9 @@ type (
// IsTLS returns true if HTTP connection is TLS otherwise false.
IsTLS() bool
+ // IsWebSocket returns true if HTTP connection is WebSocket otherwise false.
+ IsWebSocket() bool
+
// Scheme returns the HTTP protocol scheme, `http` or `https`.
Scheme() string
@@ -219,19 +222,36 @@ func (c *context) IsTLS() bool {
return c.request.TLS != nil
}
+func (c *context) IsWebSocket() bool {
+ upgrade := c.request.Header.Get(HeaderUpgrade)
+ return upgrade == "websocket" || upgrade == "Websocket"
+}
+
func (c *context) Scheme() string {
// Can't use `r.Request.URL.Scheme`
// See: https://groups.google.com/forum/#!topic/golang-nuts/pMUkBlQBDF0
if c.IsTLS() {
return "https"
}
+ if scheme := c.request.Header.Get(HeaderXForwardedProto); scheme != "" {
+ return scheme
+ }
+ if scheme := c.request.Header.Get(HeaderXForwardedProtocol); scheme != "" {
+ return scheme
+ }
+ if ssl := c.request.Header.Get(HeaderXForwardedSsl); ssl == "on" {
+ return "https"
+ }
+ if scheme := c.request.Header.Get(HeaderXUrlScheme); scheme != "" {
+ return scheme
+ }
return "http"
}
func (c *context) RealIP() string {
ra := c.request.RemoteAddr
if ip := c.request.Header.Get(HeaderXForwardedFor); ip != "" {
- ra = ip
+ ra = strings.Split(ip, ", ")[0]
} else if ip := c.request.Header.Get(HeaderXRealIP); ip != "" {
ra = ip
} else {
@@ -275,7 +295,7 @@ func (c *context) SetParamNames(names ...string) {
}
func (c *context) ParamValues() []string {
- return c.pvalues
+ return c.pvalues[:len(c.pnames)]
}
func (c *context) SetParamValues(values ...string) {
@@ -385,7 +405,8 @@ func (c *context) String(code int, s string) (err error) {
}
func (c *context) JSON(code int, i interface{}) (err error) {
- if c.echo.Debug {
+ _, pretty := c.QueryParams()["pretty"]
+ if c.echo.Debug || pretty {
return c.JSONPretty(code, i, " ")
}
b, err := json.Marshal(i)
@@ -429,7 +450,8 @@ func (c *context) JSONPBlob(code int, callback string, b []byte) (err error) {
}
func (c *context) XML(code int, i interface{}) (err error) {
- if c.echo.Debug {
+ _, pretty := c.QueryParams()["pretty"]
+ if c.echo.Debug || pretty {
return c.XMLPretty(code, i, " ")
}
b, err := xml.Marshal(i)
@@ -471,7 +493,12 @@ func (c *context) Stream(code int, contentType string, r io.Reader) (err error)
return
}
-func (c *context) File(file string) error {
+func (c *context) File(file string) (err error) {
+ file, err = url.QueryUnescape(file) // Issue #839
+ if err != nil {
+ return
+ }
+
f, err := os.Open(file)
if err != nil {
return ErrNotFound
@@ -487,11 +514,11 @@ func (c *context) File(file string) error {
}
defer f.Close()
if fi, err = f.Stat(); err != nil {
- return err
+ return
}
}
http.ServeContent(c.Response(), c.Request(), fi.Name(), fi.ModTime(), f)
- return nil
+ return
}
func (c *context) Attachment(file, name string) (err error) {
@@ -514,7 +541,7 @@ func (c *context) NoContent(code int) error {
}
func (c *context) Redirect(code int, url string) error {
- if code < http.StatusMultipleChoices || code > http.StatusTemporaryRedirect {
+ if code < 300 || code > 308 {
return ErrInvalidRedirectCode
}
c.response.Header().Set(HeaderLocation, url)
@@ -548,4 +575,8 @@ func (c *context) Reset(r *http.Request, w http.ResponseWriter) {
c.query = nil
c.handler = NotFoundHandler
c.store = nil
+ c.path = ""
+ c.pnames = nil
+ // NOTE: Don't reset because it has to have length c.echo.maxParam at all times
+ // c.pvalues = nil
}
diff --git a/vendor/github.com/labstack/echo/cookbook/auto-tls/server.go b/vendor/github.com/labstack/echo/cookbook/auto-tls/server.go
deleted file mode 100644
index 4a8bbdfd..00000000
--- a/vendor/github.com/labstack/echo/cookbook/auto-tls/server.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package main
-
-import (
- "net/http"
-
- "golang.org/x/crypto/acme/autocert"
-
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
-)
-
-func main() {
- e := echo.New()
- // e.AutoTLSManager.HostPolicy = autocert.HostWhitelist("<DOMAIN>")
- // Cache certificates
- e.AutoTLSManager.Cache = autocert.DirCache("/var/www/.cache")
- e.Use(middleware.Recover())
- e.Use(middleware.Logger())
- e.GET("/", func(c echo.Context) error {
- return c.HTML(http.StatusOK, `
- <h1>Welcome to Echo!</h1>
- <h3>TLS certificates automatically installed from Let's Encrypt :)</h3>
- `)
- })
- e.Logger.Fatal(e.StartAutoTLS(":443"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/cors/server.go b/vendor/github.com/labstack/echo/cookbook/cors/server.go
deleted file mode 100644
index 0cc5c345..00000000
--- a/vendor/github.com/labstack/echo/cookbook/cors/server.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package main
-
-import (
- "net/http"
-
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
-)
-
-var (
- users = []string{"Joe", "Veer", "Zion"}
-)
-
-func getUsers(c echo.Context) error {
- return c.JSON(http.StatusOK, users)
-}
-
-func main() {
- e := echo.New()
- e.Use(middleware.Logger())
- e.Use(middleware.Recover())
-
- // CORS default
- // Allows requests from any origin wth GET, HEAD, PUT, POST or DELETE method.
- // e.Use(middleware.CORS())
-
- // CORS restricted
- // Allows requests from any `https://labstack.com` or `https://labstack.net` origin
- // wth GET, PUT, POST or DELETE method.
- e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
- AllowOrigins: []string{"https://labstack.com", "https://labstack.net"},
- AllowMethods: []string{echo.GET, echo.PUT, echo.POST, echo.DELETE},
- }))
-
- e.GET("/api/users", getUsers)
-
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/crud/server.go b/vendor/github.com/labstack/echo/cookbook/crud/server.go
deleted file mode 100644
index fbb5c754..00000000
--- a/vendor/github.com/labstack/echo/cookbook/crud/server.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package main
-
-import (
- "net/http"
- "strconv"
-
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
-)
-
-type (
- user struct {
- ID int `json:"id"`
- Name string `json:"name"`
- }
-)
-
-var (
- users = map[int]*user{}
- seq = 1
-)
-
-//----------
-// Handlers
-//----------
-
-func createUser(c echo.Context) error {
- u := &user{
- ID: seq,
- }
- if err := c.Bind(u); err != nil {
- return err
- }
- users[u.ID] = u
- seq++
- return c.JSON(http.StatusCreated, u)
-}
-
-func getUser(c echo.Context) error {
- id, _ := strconv.Atoi(c.Param("id"))
- return c.JSON(http.StatusOK, users[id])
-}
-
-func updateUser(c echo.Context) error {
- u := new(user)
- if err := c.Bind(u); err != nil {
- return err
- }
- id, _ := strconv.Atoi(c.Param("id"))
- users[id].Name = u.Name
- return c.JSON(http.StatusOK, users[id])
-}
-
-func deleteUser(c echo.Context) error {
- id, _ := strconv.Atoi(c.Param("id"))
- delete(users, id)
- return c.NoContent(http.StatusNoContent)
-}
-
-func main() {
- e := echo.New()
-
- // Middleware
- e.Use(middleware.Logger())
- e.Use(middleware.Recover())
-
- // Routes
- e.POST("/users", createUser)
- e.GET("/users/:id", getUser)
- e.PUT("/users/:id", updateUser)
- e.DELETE("/users/:id", deleteUser)
-
- // Start server
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/embed-resources/server.go b/vendor/github.com/labstack/echo/cookbook/embed-resources/server.go
deleted file mode 100644
index e5b0c3db..00000000
--- a/vendor/github.com/labstack/echo/cookbook/embed-resources/server.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package main
-
-import (
- "net/http"
-
- rice "github.com/GeertJohan/go.rice"
- "github.com/labstack/echo"
-)
-
-func main() {
- e := echo.New()
- // the file server for rice. "app" is the folder where the files come from.
- assetHandler := http.FileServer(rice.MustFindBox("app").HTTPBox())
- // serves the index.html from rice
- e.GET("/", echo.WrapHandler(assetHandler))
-
- // servers other static files
- e.GET("/static/*", echo.WrapHandler(http.StripPrefix("/static/", assetHandler)))
-
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/file-upload/multiple/server.go b/vendor/github.com/labstack/echo/cookbook/file-upload/multiple/server.go
deleted file mode 100644
index cd0f54d3..00000000
--- a/vendor/github.com/labstack/echo/cookbook/file-upload/multiple/server.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package main
-
-import (
- "fmt"
- "io"
- "os"
-
- "net/http"
-
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
-)
-
-func upload(c echo.Context) error {
- // Read form fields
- name := c.FormValue("name")
- email := c.FormValue("email")
-
- //------------
- // Read files
- //------------
-
- // Multipart form
- form, err := c.MultipartForm()
- if err != nil {
- return err
- }
- files := form.File["files"]
-
- for _, file := range files {
- // Source
- src, err := file.Open()
- if err != nil {
- return err
- }
- defer src.Close()
-
- // Destination
- dst, err := os.Create(file.Filename)
- if err != nil {
- return err
- }
- defer dst.Close()
-
- // Copy
- if _, err = io.Copy(dst, src); err != nil {
- return err
- }
-
- }
-
- return c.HTML(http.StatusOK, fmt.Sprintf("<p>Uploaded successfully %d files with fields name=%s and email=%s.</p>", len(files), name, email))
-}
-
-func main() {
- e := echo.New()
-
- e.Use(middleware.Logger())
- e.Use(middleware.Recover())
-
- e.Static("/", "public")
- e.POST("/upload", upload)
-
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/file-upload/single/server.go b/vendor/github.com/labstack/echo/cookbook/file-upload/single/server.go
deleted file mode 100644
index 1b84f220..00000000
--- a/vendor/github.com/labstack/echo/cookbook/file-upload/single/server.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package main
-
-import (
- "fmt"
- "io"
- "os"
-
- "net/http"
-
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
-)
-
-func upload(c echo.Context) error {
- // Read form fields
- name := c.FormValue("name")
- email := c.FormValue("email")
-
- //-----------
- // Read file
- //-----------
-
- // Source
- file, err := c.FormFile("file")
- if err != nil {
- return err
- }
- src, err := file.Open()
- if err != nil {
- return err
- }
- defer src.Close()
-
- // Destination
- dst, err := os.Create(file.Filename)
- if err != nil {
- return err
- }
- defer dst.Close()
-
- // Copy
- if _, err = io.Copy(dst, src); err != nil {
- return err
- }
-
- return c.HTML(http.StatusOK, fmt.Sprintf("<p>File %s uploaded successfully with fields name=%s and email=%s.</p>", file.Filename, name, email))
-}
-
-func main() {
- e := echo.New()
-
- e.Use(middleware.Logger())
- e.Use(middleware.Recover())
-
- e.Static("/", "public")
- e.POST("/upload", upload)
-
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/google-app-engine/app-engine.go b/vendor/github.com/labstack/echo/cookbook/google-app-engine/app-engine.go
deleted file mode 100644
index 0c1db087..00000000
--- a/vendor/github.com/labstack/echo/cookbook/google-app-engine/app-engine.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// +build appengine
-
-package main
-
-import (
- "net/http"
-
- "github.com/labstack/echo"
-)
-
-func createMux() *echo.Echo {
- e := echo.New()
- // note: we don't need to provide the middleware or static handlers, that's taken care of by the platform
- // app engine has it's own "main" wrapper - we just need to hook echo into the default handler
- http.Handle("/", e)
- return e
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/google-app-engine/app-managed.go b/vendor/github.com/labstack/echo/cookbook/google-app-engine/app-managed.go
deleted file mode 100644
index 7b8eacf8..00000000
--- a/vendor/github.com/labstack/echo/cookbook/google-app-engine/app-managed.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// +build appenginevm
-
-package main
-
-import (
- "net/http"
-
- "github.com/labstack/echo"
- "google.golang.org/appengine"
-)
-
-func createMux() *echo.Echo {
- e := echo.New()
- // note: we don't need to provide the middleware or static handlers
- // for the appengine vm version - that's taken care of by the platform
- return e
-}
-
-func main() {
- // the appengine package provides a convenient method to handle the health-check requests
- // and also run the app on the correct port. We just need to add Echo to the default handler
- e := echo.New(":8080")
- http.Handle("/", e)
- appengine.Main()
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/google-app-engine/app-standalone.go b/vendor/github.com/labstack/echo/cookbook/google-app-engine/app-standalone.go
deleted file mode 100644
index c3b44dc0..00000000
--- a/vendor/github.com/labstack/echo/cookbook/google-app-engine/app-standalone.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// +build !appengine,!appenginevm
-
-package main
-
-import (
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
-)
-
-func createMux() *echo.Echo {
- e := echo.New()
-
- e.Use(middleware.Recover())
- e.Use(middleware.Logger())
- e.Use(middleware.Gzip())
-
- e.Static("/", "public")
-
- return e
-}
-
-func main() {
- e.Logger.Fatal(e.Start(":8080"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/google-app-engine/app.go b/vendor/github.com/labstack/echo/cookbook/google-app-engine/app.go
deleted file mode 100644
index 8d4d97a2..00000000
--- a/vendor/github.com/labstack/echo/cookbook/google-app-engine/app.go
+++ /dev/null
@@ -1,4 +0,0 @@
-package main
-
-// reference our echo instance and create it early
-var e = createMux()
diff --git a/vendor/github.com/labstack/echo/cookbook/google-app-engine/users.go b/vendor/github.com/labstack/echo/cookbook/google-app-engine/users.go
deleted file mode 100644
index 19533e51..00000000
--- a/vendor/github.com/labstack/echo/cookbook/google-app-engine/users.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package main
-
-import (
- "net/http"
-
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
-)
-
-type (
- user struct {
- ID string `json:"id"`
- Name string `json:"name"`
- }
-)
-
-var (
- users map[string]user
-)
-
-func init() {
- users = map[string]user{
- "1": user{
- ID: "1",
- Name: "Wreck-It Ralph",
- },
- }
-
- // hook into the echo instance to create an endpoint group
- // and add specific middleware to it plus handlers
- g := e.Group("/users")
- g.Use(middleware.CORS())
-
- g.POST("", createUser)
- g.GET("", getUsers)
- g.GET("/:id", getUser)
-}
-
-func createUser(c echo.Context) error {
- u := new(user)
- if err := c.Bind(u); err != nil {
- return err
- }
- users[u.ID] = *u
- return c.JSON(http.StatusCreated, u)
-}
-
-func getUsers(c echo.Context) error {
- return c.JSON(http.StatusOK, users)
-}
-
-func getUser(c echo.Context) error {
- return c.JSON(http.StatusOK, users[c.Param("id")])
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/google-app-engine/welcome.go b/vendor/github.com/labstack/echo/cookbook/google-app-engine/welcome.go
deleted file mode 100644
index 2639b209..00000000
--- a/vendor/github.com/labstack/echo/cookbook/google-app-engine/welcome.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package main
-
-import (
- "html/template"
- "io"
- "net/http"
-
- "github.com/labstack/echo"
-)
-
-type (
- Template struct {
- templates *template.Template
- }
-)
-
-func init() {
- t := &Template{
- templates: template.Must(template.ParseFiles("templates/welcome.html")),
- }
- e.Renderer = t
- e.GET("/welcome", welcome)
-}
-
-func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
- return t.templates.ExecuteTemplate(w, name, data)
-}
-
-func welcome(c echo.Context) error {
- return c.Render(http.StatusOK, "welcome", "Joe")
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/graceful-shutdown/grace/server.go b/vendor/github.com/labstack/echo/cookbook/graceful-shutdown/grace/server.go
deleted file mode 100644
index 1f9937b0..00000000
--- a/vendor/github.com/labstack/echo/cookbook/graceful-shutdown/grace/server.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package main
-
-import (
- "net/http"
-
- "github.com/facebookgo/grace/gracehttp"
- "github.com/labstack/echo"
-)
-
-func main() {
- // Setup
- e := echo.New()
- e.GET("/", func(c echo.Context) error {
- return c.String(http.StatusOK, "Six sick bricks tick")
- })
- e.Server.Addr = ":1323"
-
- // Serve it like a boss
- e.Logger.Fatal(gracehttp.Serve(e.Server))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/graceful-shutdown/graceful/server.go b/vendor/github.com/labstack/echo/cookbook/graceful-shutdown/graceful/server.go
deleted file mode 100644
index 39e7b634..00000000
--- a/vendor/github.com/labstack/echo/cookbook/graceful-shutdown/graceful/server.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package main
-
-import (
- "net/http"
- "time"
-
- "github.com/labstack/echo"
- "github.com/tylerb/graceful"
-)
-
-func main() {
- // Setup
- e := echo.New()
- e.GET("/", func(c echo.Context) error {
- return c.String(http.StatusOK, "Sue sews rose on slow joe crows nose")
- })
- e.Server.Addr = ":1323"
-
- // Serve it like a boss
- graceful.ListenAndServe(e.Server, 5*time.Second)
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/hello-world/server.go b/vendor/github.com/labstack/echo/cookbook/hello-world/server.go
deleted file mode 100644
index 06e0718b..00000000
--- a/vendor/github.com/labstack/echo/cookbook/hello-world/server.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package main
-
-import (
- "net/http"
-
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
-)
-
-func main() {
- // Echo instance
- e := echo.New()
-
- // Middleware
- e.Use(middleware.Logger())
- e.Use(middleware.Recover())
-
- // Route => handler
- e.GET("/", func(c echo.Context) error {
- return c.String(http.StatusOK, "Hello, World!\n")
- })
-
- // Start server
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/http2/server.go b/vendor/github.com/labstack/echo/cookbook/http2/server.go
deleted file mode 100644
index 8db989c4..00000000
--- a/vendor/github.com/labstack/echo/cookbook/http2/server.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package main
-
-import (
- "fmt"
- "net/http"
- "time"
-
- "github.com/labstack/echo"
-)
-
-func request(c echo.Context) error {
- req := c.Request()
- format := "<pre><strong>Request Information</strong>\n\n<code>Protocol: %s\nHost: %s\nRemote Address: %s\nMethod: %s\nPath: %s\n</code></pre>"
- return c.HTML(http.StatusOK, fmt.Sprintf(format, req.Proto, req.Host, req.RemoteAddr, req.Method, req.URL.Path))
-}
-
-func stream(c echo.Context) error {
- res := c.Response()
- gone := res.CloseNotify()
- res.Header().Set(echo.HeaderContentType, echo.MIMETextHTMLCharsetUTF8)
- res.WriteHeader(http.StatusOK)
- ticker := time.NewTicker(1 * time.Second)
- defer ticker.Stop()
-
- fmt.Fprint(res, "<pre><strong>Clock Stream</strong>\n\n<code>")
- for {
- fmt.Fprintf(res, "%v\n", time.Now())
- res.Flush()
- select {
- case <-ticker.C:
- case <-gone:
- break
- }
- }
-}
-
-func main() {
- e := echo.New()
- e.GET("/request", request)
- e.GET("/stream", stream)
- e.Logger.Fatal(e.StartTLS(":1323", "cert.pem", "key.pem"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/jsonp/server.go b/vendor/github.com/labstack/echo/cookbook/jsonp/server.go
deleted file mode 100644
index ba46bab0..00000000
--- a/vendor/github.com/labstack/echo/cookbook/jsonp/server.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package main
-
-import (
- "math/rand"
- "net/http"
- "time"
-
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
-)
-
-func main() {
- e := echo.New()
- e.Use(middleware.Logger())
- e.Use(middleware.Recover())
-
- e.Static("/", "public")
-
- // JSONP
- e.GET("/jsonp", func(c echo.Context) error {
- callback := c.QueryParam("callback")
- var content struct {
- Response string `json:"response"`
- Timestamp time.Time `json:"timestamp"`
- Random int `json:"random"`
- }
- content.Response = "Sent via JSONP"
- content.Timestamp = time.Now().UTC()
- content.Random = rand.Intn(1000)
- return c.JSONP(http.StatusOK, callback, &content)
- })
-
- // Start server
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/jwt/custom-claims/server.go b/vendor/github.com/labstack/echo/cookbook/jwt/custom-claims/server.go
deleted file mode 100644
index b3a13205..00000000
--- a/vendor/github.com/labstack/echo/cookbook/jwt/custom-claims/server.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package main
-
-import (
- "net/http"
- "time"
-
- jwt "github.com/dgrijalva/jwt-go"
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
-)
-
-// jwtCustomClaims are custom claims extending default ones.
-type jwtCustomClaims struct {
- Name string `json:"name"`
- Admin bool `json:"admin"`
- jwt.StandardClaims
-}
-
-func login(c echo.Context) error {
- username := c.FormValue("username")
- password := c.FormValue("password")
-
- if username == "jon" && password == "shhh!" {
-
- // Set custom claims
- claims := &jwtCustomClaims{
- "Jon Snow",
- true,
- jwt.StandardClaims{
- ExpiresAt: time.Now().Add(time.Hour * 72).Unix(),
- },
- }
-
- // Create token with claims
- token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
-
- // Generate encoded token and send it as response.
- t, err := token.SignedString([]byte("secret"))
- if err != nil {
- return err
- }
- return c.JSON(http.StatusOK, echo.Map{
- "token": t,
- })
- }
-
- return echo.ErrUnauthorized
-}
-
-func accessible(c echo.Context) error {
- return c.String(http.StatusOK, "Accessible")
-}
-
-func restricted(c echo.Context) error {
- user := c.Get("user").(*jwt.Token)
- claims := user.Claims.(*jwtCustomClaims)
- name := claims.Name
- return c.String(http.StatusOK, "Welcome "+name+"!")
-}
-
-func main() {
- e := echo.New()
-
- // Middleware
- e.Use(middleware.Logger())
- e.Use(middleware.Recover())
-
- // Login route
- e.POST("/login", login)
-
- // Unauthenticated route
- e.GET("/", accessible)
-
- // Restricted group
- r := e.Group("/restricted")
-
- // Configure middleware with the custom claims type
- config := middleware.JWTConfig{
- Claims: &jwtCustomClaims{},
- SigningKey: []byte("secret"),
- }
- r.Use(middleware.JWTWithConfig(config))
- r.GET("", restricted)
-
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/jwt/map-claims/server.go b/vendor/github.com/labstack/echo/cookbook/jwt/map-claims/server.go
deleted file mode 100644
index 678be490..00000000
--- a/vendor/github.com/labstack/echo/cookbook/jwt/map-claims/server.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package main
-
-import (
- "net/http"
- "time"
-
- jwt "github.com/dgrijalva/jwt-go"
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
-)
-
-func login(c echo.Context) error {
- username := c.FormValue("username")
- password := c.FormValue("password")
-
- if username == "jon" && password == "shhh!" {
- // Create token
- token := jwt.New(jwt.SigningMethodHS256)
-
- // Set claims
- claims := token.Claims.(jwt.MapClaims)
- claims["name"] = "Jon Snow"
- claims["admin"] = true
- claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
-
- // Generate encoded token and send it as response.
- t, err := token.SignedString([]byte("secret"))
- if err != nil {
- return err
- }
- return c.JSON(http.StatusOK, map[string]string{
- "token": t,
- })
- }
-
- return echo.ErrUnauthorized
-}
-
-func accessible(c echo.Context) error {
- return c.String(http.StatusOK, "Accessible")
-}
-
-func restricted(c echo.Context) error {
- user := c.Get("user").(*jwt.Token)
- claims := user.Claims.(jwt.MapClaims)
- name := claims["name"].(string)
- return c.String(http.StatusOK, "Welcome "+name+"!")
-}
-
-func main() {
- e := echo.New()
-
- // Middleware
- e.Use(middleware.Logger())
- e.Use(middleware.Recover())
-
- // Login route
- e.POST("/login", login)
-
- // Unauthenticated route
- e.GET("/", accessible)
-
- // Restricted group
- r := e.Group("/restricted")
- r.Use(middleware.JWT([]byte("secret")))
- r.GET("", restricted)
-
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/middleware/server.go b/vendor/github.com/labstack/echo/cookbook/middleware/server.go
deleted file mode 100644
index 2f21df50..00000000
--- a/vendor/github.com/labstack/echo/cookbook/middleware/server.go
+++ /dev/null
@@ -1,82 +0,0 @@
-package main
-
-import (
- "net/http"
- "strconv"
- "sync"
- "time"
-
- "github.com/labstack/echo"
-)
-
-type (
- Stats struct {
- Uptime time.Time `json:"uptime"`
- RequestCount uint64 `json:"requestCount"`
- Statuses map[string]int `json:"statuses"`
- mutex sync.RWMutex
- }
-)
-
-func NewStats() *Stats {
- return &Stats{
- Uptime: time.Now(),
- Statuses: make(map[string]int),
- }
-}
-
-// Process is the middleware function.
-func (s *Stats) Process(next echo.HandlerFunc) echo.HandlerFunc {
- return func(c echo.Context) error {
- if err := next(c); err != nil {
- c.Error(err)
- }
- s.mutex.Lock()
- defer s.mutex.Unlock()
- s.RequestCount++
- status := strconv.Itoa(c.Response().Status)
- s.Statuses[status]++
- return nil
- }
-}
-
-// Handle is the endpoint to get stats.
-func (s *Stats) Handle(c echo.Context) error {
- s.mutex.RLock()
- defer s.mutex.RUnlock()
- return c.JSON(http.StatusOK, s)
-}
-
-// ServerHeader middleware adds a `Server` header to the response.
-func ServerHeader(next echo.HandlerFunc) echo.HandlerFunc {
- return func(c echo.Context) error {
- c.Response().Header().Set(echo.HeaderServer, "Echo/3.0")
- return next(c)
- }
-}
-
-func main() {
- e := echo.New()
-
- // Debug mode
- e.Debug = true
-
- //-------------------
- // Custom middleware
- //-------------------
- // Stats
- s := NewStats()
- e.Use(s.Process)
- e.GET("/stats", s.Handle) // Endpoint to get stats
-
- // Server header
- e.Use(ServerHeader)
-
- // Handler
- e.GET("/", func(c echo.Context) error {
- return c.String(http.StatusOK, "Hello, World!")
- })
-
- // Start server
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/streaming-response/server.go b/vendor/github.com/labstack/echo/cookbook/streaming-response/server.go
deleted file mode 100644
index a3a679ef..00000000
--- a/vendor/github.com/labstack/echo/cookbook/streaming-response/server.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package main
-
-import (
- "net/http"
- "time"
-
- "encoding/json"
-
- "github.com/labstack/echo"
-)
-
-type (
- Geolocation struct {
- Altitude float64
- Latitude float64
- Longitude float64
- }
-)
-
-var (
- locations = []Geolocation{
- {-97, 37.819929, -122.478255},
- {1899, 39.096849, -120.032351},
- {2619, 37.865101, -119.538329},
- {42, 33.812092, -117.918974},
- {15, 37.77493, -122.419416},
- }
-)
-
-func main() {
- e := echo.New()
- e.GET("/", func(c echo.Context) error {
- c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
- c.Response().WriteHeader(http.StatusOK)
- for _, l := range locations {
- if err := json.NewEncoder(c.Response()).Encode(l); err != nil {
- return err
- }
- c.Response().Flush()
- time.Sleep(1 * time.Second)
- }
- return nil
- })
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/subdomains/server.go b/vendor/github.com/labstack/echo/cookbook/subdomains/server.go
deleted file mode 100644
index ef4f65f9..00000000
--- a/vendor/github.com/labstack/echo/cookbook/subdomains/server.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package main
-
-import (
- "net/http"
-
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
-)
-
-type (
- Host struct {
- Echo *echo.Echo
- }
-)
-
-func main() {
- // Hosts
- hosts := make(map[string]*Host)
-
- //-----
- // API
- //-----
-
- api := echo.New()
- api.Use(middleware.Logger())
- api.Use(middleware.Recover())
-
- hosts["api.localhost:1323"] = &Host{api}
-
- api.GET("/", func(c echo.Context) error {
- return c.String(http.StatusOK, "API")
- })
-
- //------
- // Blog
- //------
-
- blog := echo.New()
- blog.Use(middleware.Logger())
- blog.Use(middleware.Recover())
-
- hosts["blog.localhost:1323"] = &Host{blog}
-
- blog.GET("/", func(c echo.Context) error {
- return c.String(http.StatusOK, "Blog")
- })
-
- //---------
- // Website
- //---------
-
- site := echo.New()
- site.Use(middleware.Logger())
- site.Use(middleware.Recover())
-
- hosts["localhost:1323"] = &Host{site}
-
- site.GET("/", func(c echo.Context) error {
- return c.String(http.StatusOK, "Website")
- })
-
- // Server
- e := echo.New()
- e.Any("/*", func(c echo.Context) (err error) {
- req := c.Request()
- res := c.Response()
- host := hosts[req.Host]
-
- if host == nil {
- err = echo.ErrNotFound
- } else {
- host.Echo.ServeHTTP(res, req)
- }
-
- return
- })
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/twitter/handler/handler.go b/vendor/github.com/labstack/echo/cookbook/twitter/handler/handler.go
deleted file mode 100644
index 263c5e21..00000000
--- a/vendor/github.com/labstack/echo/cookbook/twitter/handler/handler.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package handler
-
-import mgo "gopkg.in/mgo.v2"
-
-type (
- Handler struct {
- DB *mgo.Session
- }
-)
-
-const (
- // Key (Should come from somewhere else).
- Key = "secret"
-)
diff --git a/vendor/github.com/labstack/echo/cookbook/twitter/handler/post.go b/vendor/github.com/labstack/echo/cookbook/twitter/handler/post.go
deleted file mode 100644
index b1428a30..00000000
--- a/vendor/github.com/labstack/echo/cookbook/twitter/handler/post.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package handler
-
-import (
- "net/http"
- "strconv"
-
- "github.com/labstack/echo"
- "github.com/labstack/echo/cookbook/twitter/model"
- mgo "gopkg.in/mgo.v2"
- "gopkg.in/mgo.v2/bson"
-)
-
-func (h *Handler) CreatePost(c echo.Context) (err error) {
- u := &model.User{
- ID: bson.ObjectIdHex(userIDFromToken(c)),
- }
- p := &model.Post{
- ID: bson.NewObjectId(),
- From: u.ID.Hex(),
- }
- if err = c.Bind(p); err != nil {
- return
- }
-
- // Validation
- if p.To == "" || p.Message == "" {
- return &echo.HTTPError{Code: http.StatusBadRequest, Message: "invalid to or message fields"}
- }
-
- // Find user from database
- db := h.DB.Clone()
- defer db.Close()
- if err = db.DB("twitter").C("users").FindId(u.ID).One(u); err != nil {
- if err == mgo.ErrNotFound {
- return echo.ErrNotFound
- }
- return
- }
-
- // Save post in database
- if err = db.DB("twitter").C("posts").Insert(p); err != nil {
- return
- }
- return c.JSON(http.StatusCreated, p)
-}
-
-func (h *Handler) FetchPost(c echo.Context) (err error) {
- userID := userIDFromToken(c)
- page, _ := strconv.Atoi(c.QueryParam("page"))
- limit, _ := strconv.Atoi(c.QueryParam("limit"))
-
- // Defaults
- if page == 0 {
- page = 1
- }
- if limit == 0 {
- limit = 100
- }
-
- // Retrieve posts from database
- posts := []*model.Post{}
- db := h.DB.Clone()
- if err = db.DB("twitter").C("posts").
- Find(bson.M{"to": userID}).
- Skip((page - 1) * limit).
- Limit(limit).
- All(&posts); err != nil {
- return
- }
- defer db.Close()
-
- return c.JSON(http.StatusOK, posts)
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/twitter/handler/user.go b/vendor/github.com/labstack/echo/cookbook/twitter/handler/user.go
deleted file mode 100644
index a34d2f4e..00000000
--- a/vendor/github.com/labstack/echo/cookbook/twitter/handler/user.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package handler
-
-import (
- "net/http"
- "time"
-
- jwt "github.com/dgrijalva/jwt-go"
- "github.com/labstack/echo"
- "github.com/labstack/echo/cookbook/twitter/model"
- mgo "gopkg.in/mgo.v2"
- "gopkg.in/mgo.v2/bson"
-)
-
-func (h *Handler) Signup(c echo.Context) (err error) {
- // Bind
- u := &model.User{ID: bson.NewObjectId()}
- if err = c.Bind(u); err != nil {
- return
- }
-
- // Validate
- if u.Email == "" || u.Password == "" {
- return &echo.HTTPError{Code: http.StatusBadRequest, Message: "invalid email or password"}
- }
-
- // Save user
- db := h.DB.Clone()
- defer db.Close()
- if err = db.DB("twitter").C("users").Insert(u); err != nil {
- return
- }
-
- return c.JSON(http.StatusCreated, u)
-}
-
-func (h *Handler) Login(c echo.Context) (err error) {
- // Bind
- u := new(model.User)
- if err = c.Bind(u); err != nil {
- return
- }
-
- // Find user
- db := h.DB.Clone()
- defer db.Close()
- if err = db.DB("twitter").C("users").
- Find(bson.M{"email": u.Email, "password": u.Password}).One(u); err != nil {
- if err == mgo.ErrNotFound {
- return &echo.HTTPError{Code: http.StatusUnauthorized, Message: "invalid email or password"}
- }
- return
- }
-
- //-----
- // JWT
- //-----
-
- // Create token
- token := jwt.New(jwt.SigningMethodHS256)
-
- // Set claims
- claims := token.Claims.(jwt.MapClaims)
- claims["id"] = u.ID
- claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
-
- // Generate encoded token and send it as response
- u.Token, err = token.SignedString([]byte(Key))
- if err != nil {
- return err
- }
-
- u.Password = "" // Don't send password
- return c.JSON(http.StatusOK, u)
-}
-
-func (h *Handler) Follow(c echo.Context) (err error) {
- userID := userIDFromToken(c)
- id := c.Param("id")
-
- // Add a follower to user
- db := h.DB.Clone()
- defer db.Close()
- if err = db.DB("twitter").C("users").
- UpdateId(bson.ObjectIdHex(id), bson.M{"$addToSet": bson.M{"followers": userID}}); err != nil {
- if err == mgo.ErrNotFound {
- return echo.ErrNotFound
- }
- }
-
- return
-}
-
-func userIDFromToken(c echo.Context) string {
- user := c.Get("user").(*jwt.Token)
- claims := user.Claims.(jwt.MapClaims)
- return claims["id"].(string)
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/twitter/model/post.go b/vendor/github.com/labstack/echo/cookbook/twitter/model/post.go
deleted file mode 100644
index 7344296e..00000000
--- a/vendor/github.com/labstack/echo/cookbook/twitter/model/post.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package model
-
-import "gopkg.in/mgo.v2/bson"
-
-type (
- Post struct {
- ID bson.ObjectId `json:"id" bson:"_id,omitempty"`
- To string `json:"to" bson:"to"`
- From string `json:"from" bson:"from"`
- Message string `json:"message" bson:"message"`
- }
-)
diff --git a/vendor/github.com/labstack/echo/cookbook/twitter/model/user.go b/vendor/github.com/labstack/echo/cookbook/twitter/model/user.go
deleted file mode 100644
index e063c89b..00000000
--- a/vendor/github.com/labstack/echo/cookbook/twitter/model/user.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package model
-
-import "gopkg.in/mgo.v2/bson"
-
-type (
- User struct {
- ID bson.ObjectId `json:"id" bson:"_id,omitempty"`
- Email string `json:"email" bson:"email"`
- Password string `json:"password,omitempty" bson:"password"`
- Token string `json:"token,omitempty" bson:"-"`
- Followers []string `json:"followers,omitempty" bson:"followers,omitempty"`
- }
-)
diff --git a/vendor/github.com/labstack/echo/cookbook/twitter/server.go b/vendor/github.com/labstack/echo/cookbook/twitter/server.go
deleted file mode 100644
index 22db7aa0..00000000
--- a/vendor/github.com/labstack/echo/cookbook/twitter/server.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package main
-
-import (
- "github.com/labstack/echo"
- "github.com/labstack/echo/cookbook/twitter/handler"
- "github.com/labstack/echo/middleware"
- "github.com/labstack/gommon/log"
- mgo "gopkg.in/mgo.v2"
-)
-
-func main() {
- e := echo.New()
- e.Logger.SetLevel(log.ERROR)
- e.Use(middleware.Logger())
- e.Use(middleware.JWTWithConfig(middleware.JWTConfig{
- SigningKey: []byte(handler.Key),
- Skipper: func(c echo.Context) bool {
- // Skip authentication for and signup login requests
- if c.Path() == "/login" || c.Path() == "/signup" {
- return true
- }
- return false
- },
- }))
-
- // Database connection
- db, err := mgo.Dial("localhost")
- if err != nil {
- e.Logger.Fatal(err)
- }
-
- // Create indices
- if err = db.Copy().DB("twitter").C("users").EnsureIndex(mgo.Index{
- Key: []string{"email"},
- Unique: true,
- }); err != nil {
- log.Fatal(err)
- }
-
- // Initialize handler
- h := &handler.Handler{DB: db}
-
- // Routes
- e.POST("/signup", h.Signup)
- e.POST("/login", h.Login)
- e.POST("/follow/:id", h.Follow)
- e.POST("/posts", h.CreatePost)
- e.GET("/feed", h.FetchPost)
-
- // Start server
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/websocket/gorilla/server.go b/vendor/github.com/labstack/echo/cookbook/websocket/gorilla/server.go
deleted file mode 100644
index e9d52dbb..00000000
--- a/vendor/github.com/labstack/echo/cookbook/websocket/gorilla/server.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package main
-
-import (
- "fmt"
- "log"
-
- "github.com/labstack/echo"
-
- "github.com/gorilla/websocket"
- "github.com/labstack/echo/middleware"
-)
-
-var (
- upgrader = websocket.Upgrader{}
-)
-
-func hello(c echo.Context) error {
- ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil)
- if err != nil {
- return err
- }
- defer ws.Close()
-
- for {
- // Write
- err := ws.WriteMessage(websocket.TextMessage, []byte("Hello, Client!"))
- if err != nil {
- log.Fatal(err)
- }
-
- // Read
- _, msg, err := ws.ReadMessage()
- if err != nil {
- log.Fatal(err)
- }
- fmt.Printf("%s\n", msg)
- }
-}
-
-func main() {
- e := echo.New()
- e.Use(middleware.Logger())
- e.Use(middleware.Recover())
- e.Static("/", "../public")
- e.GET("/ws", hello)
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/cookbook/websocket/net/server.go b/vendor/github.com/labstack/echo/cookbook/websocket/net/server.go
deleted file mode 100644
index aa746030..00000000
--- a/vendor/github.com/labstack/echo/cookbook/websocket/net/server.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package main
-
-import (
- "fmt"
- "log"
-
- "github.com/labstack/echo"
- "github.com/labstack/echo/middleware"
- "golang.org/x/net/websocket"
-)
-
-func hello(c echo.Context) error {
- websocket.Handler(func(ws *websocket.Conn) {
- defer ws.Close()
- for {
- // Write
- err := websocket.Message.Send(ws, "Hello, Client!")
- if err != nil {
- log.Fatal(err)
- }
-
- // Read
- msg := ""
- err = websocket.Message.Receive(ws, &msg)
- if err != nil {
- log.Fatal(err)
- }
- fmt.Printf("%s\n", msg)
- }
- }).ServeHTTP(c.Response(), c.Request())
- return nil
-}
-
-func main() {
- e := echo.New()
- e.Use(middleware.Logger())
- e.Use(middleware.Recover())
- e.Static("/", "../public")
- e.GET("/ws", hello)
- e.Logger.Fatal(e.Start(":1323"))
-}
diff --git a/vendor/github.com/labstack/echo/echo.go b/vendor/github.com/labstack/echo/echo.go
index f0c1b72e..baa92fde 100644
--- a/vendor/github.com/labstack/echo/echo.go
+++ b/vendor/github.com/labstack/echo/echo.go
@@ -42,10 +42,11 @@ import (
"errors"
"fmt"
"io"
- slog "log"
+ stdLog "log"
"net"
"net/http"
"path"
+ "path/filepath"
"reflect"
"runtime"
"sync"
@@ -59,7 +60,7 @@ import (
type (
// Echo is the top-level framework instance.
Echo struct {
- stdLogger *slog.Logger
+ stdLogger *stdLog.Logger
colorer *color.Color
premiddleware []MiddlewareFunc
middleware []MiddlewareFunc
@@ -73,20 +74,21 @@ type (
TLSListener net.Listener
DisableHTTP2 bool
Debug bool
+ HideBanner bool
HTTPErrorHandler HTTPErrorHandler
Binder Binder
Validator Validator
Renderer Renderer
AutoTLSManager autocert.Manager
- Mutex sync.RWMutex
- Logger Logger
+ // Mutex sync.RWMutex
+ Logger Logger
}
// Route contains a handler and information for matching against requests.
Route struct {
- Method string
- Path string
- Handler string
+ Method string `json:"method"`
+ Path string `json:"path"`
+ Handler string `json:"handler"`
}
// HTTPError represents an error that occurred while handling a request.
@@ -144,6 +146,8 @@ const (
MIMEApplicationJavaScriptCharsetUTF8 = MIMEApplicationJavaScript + "; " + charsetUTF8
MIMEApplicationXML = "application/xml"
MIMEApplicationXMLCharsetUTF8 = MIMEApplicationXML + "; " + charsetUTF8
+ MIMETextXML = "text/xml"
+ MIMETextXMLCharsetUTF8 = MIMETextXML + "; " + charsetUTF8
MIMEApplicationForm = "application/x-www-form-urlencoded"
MIMEApplicationProtobuf = "application/protobuf"
MIMEApplicationMsgpack = "application/msgpack"
@@ -161,27 +165,34 @@ const (
// Headers
const (
- HeaderAcceptEncoding = "Accept-Encoding"
- HeaderAllow = "Allow"
- HeaderAuthorization = "Authorization"
- HeaderContentDisposition = "Content-Disposition"
- HeaderContentEncoding = "Content-Encoding"
- HeaderContentLength = "Content-Length"
- HeaderContentType = "Content-Type"
- HeaderCookie = "Cookie"
- HeaderSetCookie = "Set-Cookie"
- HeaderIfModifiedSince = "If-Modified-Since"
- HeaderLastModified = "Last-Modified"
- HeaderLocation = "Location"
- HeaderUpgrade = "Upgrade"
- HeaderVary = "Vary"
- HeaderWWWAuthenticate = "WWW-Authenticate"
- HeaderXForwardedProto = "X-Forwarded-Proto"
- HeaderXHTTPMethodOverride = "X-HTTP-Method-Override"
- HeaderXForwardedFor = "X-Forwarded-For"
- HeaderXRealIP = "X-Real-IP"
- HeaderServer = "Server"
- HeaderOrigin = "Origin"
+ HeaderAccept = "Accept"
+ HeaderAcceptEncoding = "Accept-Encoding"
+ HeaderAllow = "Allow"
+ HeaderAuthorization = "Authorization"
+ HeaderContentDisposition = "Content-Disposition"
+ HeaderContentEncoding = "Content-Encoding"
+ HeaderContentLength = "Content-Length"
+ HeaderContentType = "Content-Type"
+ HeaderCookie = "Cookie"
+ HeaderSetCookie = "Set-Cookie"
+ HeaderIfModifiedSince = "If-Modified-Since"
+ HeaderLastModified = "Last-Modified"
+ HeaderLocation = "Location"
+ HeaderUpgrade = "Upgrade"
+ HeaderVary = "Vary"
+ HeaderWWWAuthenticate = "WWW-Authenticate"
+ HeaderXForwardedFor = "X-Forwarded-For"
+ HeaderXForwardedProto = "X-Forwarded-Proto"
+ HeaderXForwardedProtocol = "X-Forwarded-Protocol"
+ HeaderXForwardedSsl = "X-Forwarded-Ssl"
+ HeaderXUrlScheme = "X-Url-Scheme"
+ HeaderXHTTPMethodOverride = "X-HTTP-Method-Override"
+ HeaderXRealIP = "X-Real-IP"
+ HeaderXRequestID = "X-Request-ID"
+ HeaderServer = "Server"
+ HeaderOrigin = "Origin"
+
+ // Access control
HeaderAccessControlRequestMethod = "Access-Control-Request-Method"
HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers"
HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin"
@@ -200,6 +211,22 @@ const (
HeaderXCSRFToken = "X-CSRF-Token"
)
+const (
+ version = "3.1.0"
+ website = "https://echo.labstack.com"
+ // http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
+ banner = `
+ ____ __
+ / __/___/ / ___
+ / _// __/ _ \/ _ \
+/___/\__/_//_/\___/ %s
+High performance, minimalist Go web framework
+%s
+____________________________________O/_______
+ O\
+`
+)
+
var (
methods = [...]string{
CONNECT,
@@ -219,6 +246,7 @@ var (
ErrUnsupportedMediaType = NewHTTPError(http.StatusUnsupportedMediaType)
ErrNotFound = NewHTTPError(http.StatusNotFound)
ErrUnauthorized = NewHTTPError(http.StatusUnauthorized)
+ ErrForbidden = NewHTTPError(http.StatusForbidden)
ErrMethodNotAllowed = NewHTTPError(http.StatusMethodNotAllowed)
ErrStatusRequestEntityTooLarge = NewHTTPError(http.StatusRequestEntityTooLarge)
ErrValidatorNotRegistered = errors.New("Validator not registered")
@@ -255,7 +283,7 @@ func New() (e *Echo) {
e.HTTPErrorHandler = e.DefaultHTTPErrorHandler
e.Binder = &DefaultBinder{}
e.Logger.SetLevel(log.OFF)
- e.stdLogger = slog.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0)
+ e.stdLogger = stdLog.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0)
e.pool.New = func() interface{} {
return e.NewContext(nil, nil)
}
@@ -398,12 +426,16 @@ func (e *Echo) Match(methods []string, path string, handler HandlerFunc, middlew
// Static registers a new route with path prefix to serve static files from the
// provided root directory.
func (e *Echo) Static(prefix, root string) {
+ if root == "" {
+ root = "." // For security we want to restrict to CWD.
+ }
static(e, prefix, root)
}
func static(i i, prefix, root string) {
h := func(c Context) error {
- return c.File(path.Join(root, c.Param("*")))
+ name := filepath.Join(root, path.Clean("/"+c.Param("*"))) // "/"+ for security
+ return c.File(name)
}
i.GET(prefix, h)
if prefix == "/" {
@@ -430,7 +462,7 @@ func (e *Echo) add(method, path string, handler HandlerFunc, middleware ...Middl
}
return h(c)
})
- r := Route{
+ r := &Route{
Method: method,
Path: path,
Handler: name,
@@ -476,8 +508,8 @@ func (e *Echo) URL(h HandlerFunc, params ...interface{}) string {
}
// Routes returns the registered routes.
-func (e *Echo) Routes() []Route {
- routes := []Route{}
+func (e *Echo) Routes() []*Route {
+ routes := []*Route{}
for _, v := range e.router.routes {
routes = append(routes, v)
}
@@ -499,8 +531,8 @@ func (e *Echo) ReleaseContext(c Context) {
// ServeHTTP implements `http.Handler` interface, which serves HTTP requests.
func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Acquire lock
- e.Mutex.RLock()
- defer e.Mutex.RUnlock()
+ // e.Mutex.RLock()
+ // defer e.Mutex.RUnlock()
// Acquire context
c := e.pool.Get().(*context)
@@ -510,7 +542,10 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Middleware
h := func(c Context) error {
method := r.Method
- path := r.URL.EscapedPath()
+ path := r.URL.RawPath
+ if path == "" {
+ path = r.URL.Path
+ }
e.router.Find(method, path, c)
h := c.Handler()
for i := len(e.middleware) - 1; i >= 0; i-- {
@@ -572,8 +607,15 @@ func (e *Echo) startTLS(address string) error {
func (e *Echo) StartServer(s *http.Server) (err error) {
// Setup
e.colorer.SetOutput(e.Logger.Output())
- s.Handler = e
s.ErrorLog = e.stdLogger
+ s.Handler = e
+ if e.Debug {
+ e.Logger.SetLevel(log.DEBUG)
+ }
+
+ if !e.HideBanner {
+ e.colorer.Printf(banner, e.colorer.Red("v"+version), e.colorer.Blue(website))
+ }
if s.TLSConfig == nil {
if e.Listener == nil {
@@ -582,7 +624,9 @@ func (e *Echo) StartServer(s *http.Server) (err error) {
return err
}
}
- e.colorer.Printf("⇛ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
+ if !e.HideBanner {
+ e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
+ }
return s.Serve(e.Listener)
}
if e.TLSListener == nil {
@@ -592,7 +636,9 @@ func (e *Echo) StartServer(s *http.Server) (err error) {
}
e.TLSListener = tls.NewListener(l, s.TLSConfig)
}
- e.colorer.Printf("⇛ https server started on %s\n", e.colorer.Green(e.TLSListener.Addr()))
+ if !e.HideBanner {
+ e.colorer.Printf("⇨ https server started on %s\n", e.colorer.Green(e.TLSListener.Addr()))
+ }
return s.Serve(e.TLSListener)
}
diff --git a/vendor/github.com/labstack/echo/echo_go1.8.go b/vendor/github.com/labstack/echo/echo_go1.8.go
new file mode 100644
index 00000000..340bed70
--- /dev/null
+++ b/vendor/github.com/labstack/echo/echo_go1.8.go
@@ -0,0 +1,25 @@
+// +build go1.8
+
+package echo
+
+import (
+ stdContext "context"
+)
+
+// Close immediately stops the server.
+// It internally calls `http.Server#Close()`.
+func (e *Echo) Close() error {
+ if err := e.TLSServer.Close(); err != nil {
+ return err
+ }
+ return e.Server.Close()
+}
+
+// Shutdown stops server the gracefully.
+// It internally calls `http.Server#Shutdown()`.
+func (e *Echo) Shutdown(ctx stdContext.Context) error {
+ if err := e.TLSServer.Shutdown(ctx); err != nil {
+ return err
+ }
+ return e.Server.Shutdown(ctx)
+}
diff --git a/vendor/github.com/labstack/echo/group.go b/vendor/github.com/labstack/echo/group.go
index 9767bb19..799a8f90 100644
--- a/vendor/github.com/labstack/echo/group.go
+++ b/vendor/github.com/labstack/echo/group.go
@@ -1,8 +1,12 @@
package echo
+import (
+ "path"
+)
+
type (
// Group is a set of sub-routes for a specified route. It can be used for inner
- // routes that share a common middlware or functionality that should be separate
+ // routes that share a common middleware or functionality that should be separate
// from the parent echo instance while still inheriting from it.
Group struct {
prefix string
@@ -14,6 +18,11 @@ type (
// Use implements `Echo#Use()` for sub-routes within the Group.
func (g *Group) Use(middleware ...MiddlewareFunc) {
g.middleware = append(g.middleware, middleware...)
+ // Allow all requests to reach the group as they might get dropped if router
+ // doesn't find a match, making none of the group middleware process.
+ g.echo.Any(path.Clean(g.prefix+"/*"), func(c Context) error {
+ return ErrNotFound
+ }, g.middleware...)
}
// CONNECT implements `Echo#CONNECT()` for sub-routes within the Group.
diff --git a/vendor/github.com/labstack/echo/middleware/basic_auth.go b/vendor/github.com/labstack/echo/middleware/basic_auth.go
index e98a87e3..c1f34c8f 100644
--- a/vendor/github.com/labstack/echo/middleware/basic_auth.go
+++ b/vendor/github.com/labstack/echo/middleware/basic_auth.go
@@ -2,6 +2,7 @@ package middleware
import (
"encoding/base64"
+ "strconv"
"github.com/labstack/echo"
)
@@ -15,20 +16,26 @@ type (
// Validator is a function to validate BasicAuth credentials.
// Required.
Validator BasicAuthValidator
+
+ // Realm is a string to define realm attribute of BasicAuth.
+ // Default value "Restricted".
+ Realm string
}
// BasicAuthValidator defines a function to validate BasicAuth credentials.
- BasicAuthValidator func(string, string, echo.Context) bool
+ BasicAuthValidator func(string, string, echo.Context) (bool, error)
)
const (
- basic = "Basic"
+ basic = "Basic"
+ defaultRealm = "Restricted"
)
var (
// DefaultBasicAuthConfig is the default BasicAuth middleware config.
DefaultBasicAuthConfig = BasicAuthConfig{
Skipper: DefaultSkipper,
+ Realm: defaultRealm,
}
)
@@ -52,6 +59,9 @@ func BasicAuthWithConfig(config BasicAuthConfig) echo.MiddlewareFunc {
if config.Skipper == nil {
config.Skipper = DefaultBasicAuthConfig.Skipper
}
+ if config.Realm == "" {
+ config.Realm = defaultRealm
+ }
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
@@ -71,15 +81,25 @@ func BasicAuthWithConfig(config BasicAuthConfig) echo.MiddlewareFunc {
for i := 0; i < len(cred); i++ {
if cred[i] == ':' {
// Verify credentials
- if config.Validator(cred[:i], cred[i+1:], c) {
+ valid, err := config.Validator(cred[:i], cred[i+1:], c)
+ if err != nil {
+ return err
+ } else if valid {
return next(c)
}
}
}
}
+ realm := ""
+ if config.Realm == defaultRealm {
+ realm = defaultRealm
+ } else {
+ realm = strconv.Quote(config.Realm)
+ }
+
// Need to return `401` for browsers to pop-up login box.
- c.Response().Header().Set(echo.HeaderWWWAuthenticate, basic+" realm=Restricted")
+ c.Response().Header().Set(echo.HeaderWWWAuthenticate, basic+" realm="+realm)
return echo.ErrUnauthorized
}
}
diff --git a/vendor/github.com/labstack/echo/middleware/compress.go b/vendor/github.com/labstack/echo/middleware/compress.go
index eee67b37..cffadbd1 100644
--- a/vendor/github.com/labstack/echo/middleware/compress.go
+++ b/vendor/github.com/labstack/echo/middleware/compress.go
@@ -108,8 +108,8 @@ func (w *gzipResponseWriter) Write(b []byte) (int, error) {
return w.Writer.Write(b)
}
-func (w *gzipResponseWriter) Flush() error {
- return w.Writer.(*gzip.Writer).Flush()
+func (w *gzipResponseWriter) Flush() {
+ w.Writer.(*gzip.Writer).Flush()
}
func (w *gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
diff --git a/vendor/github.com/labstack/echo/middleware/jwt.go b/vendor/github.com/labstack/echo/middleware/jwt.go
index b2658739..5d2072e7 100644
--- a/vendor/github.com/labstack/echo/middleware/jwt.go
+++ b/vendor/github.com/labstack/echo/middleware/jwt.go
@@ -91,7 +91,7 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
config.Skipper = DefaultJWTConfig.Skipper
}
if config.SigningKey == nil {
- panic("jwt middleware requires signing key")
+ panic("echo: jwt middleware requires signing key")
}
if config.SigningMethod == "" {
config.SigningMethod = DefaultJWTConfig.SigningMethod
diff --git a/vendor/github.com/labstack/echo/middleware/key_auth.go b/vendor/github.com/labstack/echo/middleware/key_auth.go
index 4d4cb940..5ef87e3d 100644
--- a/vendor/github.com/labstack/echo/middleware/key_auth.go
+++ b/vendor/github.com/labstack/echo/middleware/key_auth.go
@@ -32,7 +32,7 @@ type (
}
// KeyAuthValidator defines a function to validate KeyAuth credentials.
- KeyAuthValidator func(string, echo.Context) bool
+ KeyAuthValidator func(string, echo.Context) (bool, error)
keyExtractor func(echo.Context) (string, error)
)
@@ -94,7 +94,10 @@ func KeyAuthWithConfig(config KeyAuthConfig) echo.MiddlewareFunc {
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
}
- if config.Validator(key, c) {
+ valid, err := config.Validator(key, c)
+ if err != nil {
+ return err
+ } else if valid {
return next(c)
}
diff --git a/vendor/github.com/labstack/echo/middleware/logger.go b/vendor/github.com/labstack/echo/middleware/logger.go
index e26b5496..b9c54468 100644
--- a/vendor/github.com/labstack/echo/middleware/logger.go
+++ b/vendor/github.com/labstack/echo/middleware/logger.go
@@ -26,7 +26,7 @@ type (
// - time_unix_nano
// - time_rfc3339
// - time_rfc3339_nano
- // - id (Request ID - Not implemented)
+ // - id (Request ID)
// - remote_ip
// - uri
// - host
@@ -62,7 +62,7 @@ var (
// DefaultLoggerConfig is the default Logger middleware config.
DefaultLoggerConfig = LoggerConfig{
Skipper: DefaultSkipper,
- Format: `{"time":"${time_rfc3339_nano}","remote_ip":"${remote_ip}","host":"${host}",` +
+ Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}","host":"${host}",` +
`"method":"${method}","uri":"${uri}","status":${status}, "latency":${latency},` +
`"latency_human":"${latency_human}","bytes_in":${bytes_in},` +
`"bytes_out":${bytes_out}}` + "\n",
@@ -126,6 +126,12 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc {
return buf.WriteString(time.Now().Format(time.RFC3339))
case "time_rfc3339_nano":
return buf.WriteString(time.Now().Format(time.RFC3339Nano))
+ case "id":
+ id := req.Header.Get(echo.HeaderXRequestID)
+ if id == "" {
+ id = res.Header().Get(echo.HeaderXRequestID)
+ }
+ return buf.WriteString(id)
case "remote_ip":
return buf.WriteString(c.RealIP())
case "host":
@@ -177,6 +183,11 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc {
return buf.Write([]byte(c.QueryParam(tag[6:])))
case strings.HasPrefix(tag, "form:"):
return buf.Write([]byte(c.FormValue(tag[5:])))
+ case strings.HasPrefix(tag, "cookie:"):
+ cookie, err := c.Cookie(tag[7:])
+ if err == nil {
+ return buf.Write([]byte(cookie.Value))
+ }
}
}
return 0, nil
diff --git a/vendor/github.com/labstack/echo/middleware/middleware.go b/vendor/github.com/labstack/echo/middleware/middleware.go
index 7edccc1d..efcbab91 100644
--- a/vendor/github.com/labstack/echo/middleware/middleware.go
+++ b/vendor/github.com/labstack/echo/middleware/middleware.go
@@ -9,6 +9,6 @@ type (
)
// DefaultSkipper returns false which processes the middleware.
-func DefaultSkipper(c echo.Context) bool {
+func DefaultSkipper(echo.Context) bool {
return false
}
diff --git a/vendor/github.com/labstack/echo/middleware/proxy.go b/vendor/github.com/labstack/echo/middleware/proxy.go
new file mode 100644
index 00000000..7eb24abf
--- /dev/null
+++ b/vendor/github.com/labstack/echo/middleware/proxy.go
@@ -0,0 +1,160 @@
+package middleware
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "math/rand"
+ "net"
+ "net/http"
+ "net/http/httputil"
+ "net/url"
+ "sync/atomic"
+ "time"
+
+ "github.com/labstack/echo"
+)
+
+// TODO: Handle TLS proxy
+
+type (
+ // ProxyConfig defines the config for Proxy middleware.
+ ProxyConfig struct {
+ // Skipper defines a function to skip middleware.
+ Skipper Skipper
+
+ // Balancer defines a load balancing technique.
+ // Required.
+ // Possible values:
+ // - RandomBalancer
+ // - RoundRobinBalancer
+ Balancer ProxyBalancer
+ }
+
+ // ProxyTarget defines the upstream target.
+ ProxyTarget struct {
+ URL *url.URL
+ }
+
+ // RandomBalancer implements a random load balancing technique.
+ RandomBalancer struct {
+ Targets []*ProxyTarget
+ random *rand.Rand
+ }
+
+ // RoundRobinBalancer implements a round-robin load balancing technique.
+ RoundRobinBalancer struct {
+ Targets []*ProxyTarget
+ i uint32
+ }
+
+ // ProxyBalancer defines an interface to implement a load balancing technique.
+ ProxyBalancer interface {
+ Next() *ProxyTarget
+ }
+)
+
+func proxyHTTP(t *ProxyTarget) http.Handler {
+ return httputil.NewSingleHostReverseProxy(t.URL)
+}
+
+func proxyRaw(t *ProxyTarget, c echo.Context) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ h, ok := w.(http.Hijacker)
+ if !ok {
+ c.Error(errors.New("proxy raw, not a hijacker"))
+ return
+ }
+ in, _, err := h.Hijack()
+ if err != nil {
+ c.Error(fmt.Errorf("proxy raw, hijack error=%v, url=%s", r.URL, err))
+ return
+ }
+ defer in.Close()
+
+ out, err := net.Dial("tcp", t.URL.Host)
+ if err != nil {
+ he := echo.NewHTTPError(http.StatusBadGateway, fmt.Sprintf("proxy raw, dial error=%v, url=%s", r.URL, err))
+ c.Error(he)
+ return
+ }
+ defer out.Close()
+
+ err = r.Write(out)
+ if err != nil {
+ he := echo.NewHTTPError(http.StatusBadGateway, fmt.Sprintf("proxy raw, request copy error=%v, url=%s", r.URL, err))
+ c.Error(he)
+ return
+ }
+
+ errc := make(chan error, 2)
+ cp := func(dst io.Writer, src io.Reader) {
+ _, err := io.Copy(dst, src)
+ errc <- err
+ }
+
+ go cp(out, in)
+ go cp(in, out)
+ err = <-errc
+ if err != nil && err != io.EOF {
+ c.Logger().Errorf("proxy raw, error=%v, url=%s", r.URL, err)
+ }
+ })
+}
+
+// Next randomly returns an upstream target.
+func (r *RandomBalancer) Next() *ProxyTarget {
+ if r.random == nil {
+ r.random = rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
+ }
+ return r.Targets[r.random.Intn(len(r.Targets))]
+}
+
+// Next returns an upstream target using round-robin technique.
+func (r *RoundRobinBalancer) Next() *ProxyTarget {
+ r.i = r.i % uint32(len(r.Targets))
+ t := r.Targets[r.i]
+ atomic.AddUint32(&r.i, 1)
+ return t
+}
+
+// Proxy returns an HTTP/WebSocket reverse proxy middleware.
+func Proxy(config ProxyConfig) echo.MiddlewareFunc {
+ // Defaults
+ if config.Skipper == nil {
+ config.Skipper = DefaultLoggerConfig.Skipper
+ }
+ if config.Balancer == nil {
+ panic("echo: proxy middleware requires balancer")
+ }
+
+ return func(next echo.HandlerFunc) echo.HandlerFunc {
+ return func(c echo.Context) (err error) {
+ req := c.Request()
+ res := c.Response()
+ tgt := config.Balancer.Next()
+
+ // Fix header
+ if req.Header.Get(echo.HeaderXRealIP) == "" {
+ req.Header.Set(echo.HeaderXRealIP, c.RealIP())
+ }
+ if req.Header.Get(echo.HeaderXForwardedProto) == "" {
+ req.Header.Set(echo.HeaderXForwardedProto, c.Scheme())
+ }
+ if c.IsWebSocket() && req.Header.Get(echo.HeaderXForwardedFor) == "" { // For HTTP, it is automatically set by Go HTTP reverse proxy.
+ req.Header.Set(echo.HeaderXForwardedFor, c.RealIP())
+ }
+
+ // Proxy
+ switch {
+ case c.IsWebSocket():
+ proxyRaw(tgt, c).ServeHTTP(res, req)
+ case req.Header.Get(echo.HeaderAccept) == "text/event-stream":
+ default:
+ proxyHTTP(tgt).ServeHTTP(res, req)
+ }
+
+ return
+ }
+ }
+}
diff --git a/vendor/github.com/labstack/echo/middleware/request_id.go b/vendor/github.com/labstack/echo/middleware/request_id.go
new file mode 100644
index 00000000..f376c296
--- /dev/null
+++ b/vendor/github.com/labstack/echo/middleware/request_id.go
@@ -0,0 +1,64 @@
+package middleware
+
+import (
+ "github.com/labstack/echo"
+ "github.com/labstack/gommon/random"
+)
+
+type (
+ // RequestIDConfig defines the config for RequestID middleware.
+ RequestIDConfig struct {
+ // Skipper defines a function to skip middleware.
+ Skipper Skipper
+
+ // Generator defines a function to generate an ID.
+ // Optional. Default value random.String(32).
+ Generator func() string
+ }
+)
+
+var (
+ // DefaultRequestIDConfig is the default RequestID middleware config.
+ DefaultRequestIDConfig = RequestIDConfig{
+ Skipper: DefaultSkipper,
+ Generator: generator,
+ }
+)
+
+// RequestID returns a X-Request-ID middleware.
+func RequestID() echo.MiddlewareFunc {
+ return RequestIDWithConfig(DefaultRequestIDConfig)
+}
+
+// RequestIDWithConfig returns a X-Request-ID middleware with config.
+func RequestIDWithConfig(config RequestIDConfig) echo.MiddlewareFunc {
+ // Defaults
+ if config.Skipper == nil {
+ config.Skipper = DefaultRequestIDConfig.Skipper
+ }
+ if config.Generator == nil {
+ config.Generator = generator
+ }
+
+ return func(next echo.HandlerFunc) echo.HandlerFunc {
+ return func(c echo.Context) error {
+ if config.Skipper(c) {
+ return next(c)
+ }
+
+ req := c.Request()
+ res := c.Response()
+ rid := req.Header.Get(echo.HeaderXRequestID)
+ if rid == "" {
+ rid = config.Generator()
+ }
+ res.Header().Set(echo.HeaderXRequestID, rid)
+
+ return next(c)
+ }
+ }
+}
+
+func generator() string {
+ return random.String(32)
+}
diff --git a/vendor/github.com/labstack/echo/middleware/static.go b/vendor/github.com/labstack/echo/middleware/static.go
index 793c1445..e715c1c4 100644
--- a/vendor/github.com/labstack/echo/middleware/static.go
+++ b/vendor/github.com/labstack/echo/middleware/static.go
@@ -3,7 +3,9 @@ package middleware
import (
"fmt"
"os"
+ "path"
"path/filepath"
+ "strings"
"github.com/labstack/echo"
)
@@ -53,6 +55,9 @@ func Static(root string) echo.MiddlewareFunc {
// See `Static()`.
func StaticWithConfig(config StaticConfig) echo.MiddlewareFunc {
// Defaults
+ if config.Root == "" {
+ config.Root = "." // For security we want to restrict to CWD.
+ }
if config.Skipper == nil {
config.Skipper = DefaultStaticConfig.Skipper
}
@@ -62,26 +67,44 @@ func StaticWithConfig(config StaticConfig) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
- p := c.Param("*")
- name := filepath.Join(config.Root, p)
- fi, err := os.Stat(name)
+ if config.Skipper(c) {
+ return next(c)
+ }
+ p := c.Request().URL.Path
+ if strings.HasSuffix(c.Path(), "*") { // When serving from a group, e.g. `/static*`.
+ p = c.Param("*")
+ }
+ name := filepath.Join(config.Root, path.Clean("/"+p)) // "/"+ for security
+
+ fi, err := os.Stat(name)
if err != nil {
if os.IsNotExist(err) {
- if config.HTML5 {
+ if config.HTML5 && path.Ext(p) == "" {
return c.File(filepath.Join(config.Root, config.Index))
}
- return echo.ErrNotFound
+ return next(c)
}
return err
}
if fi.IsDir() {
- if config.Browse {
- return listDir(name, c.Response())
+ index := filepath.Join(name, config.Index)
+ fi, err = os.Stat(index)
+
+ if err != nil {
+ if config.Browse {
+ return listDir(name, c.Response())
+ }
+ if os.IsNotExist(err) {
+ return next(c)
+ }
+ return err
}
- return c.File(filepath.Join(name, config.Index))
+
+ return c.File(index)
}
+
return c.File(name)
}
}
diff --git a/vendor/github.com/labstack/echo/router.go b/vendor/github.com/labstack/echo/router.go
index 5cb47116..2ef904e0 100644
--- a/vendor/github.com/labstack/echo/router.go
+++ b/vendor/github.com/labstack/echo/router.go
@@ -7,7 +7,7 @@ type (
// request matching and URL path parameter parsing.
Router struct {
tree *node
- routes map[string]Route
+ routes map[string]*Route
echo *Echo
}
node struct {
@@ -47,7 +47,7 @@ func NewRouter(e *Echo) *Router {
tree: &node{
methodHandler: new(methodHandler),
},
- routes: make(map[string]Route),
+ routes: map[string]*Route{},
echo: e,
}
}
@@ -101,7 +101,7 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
cn := r.tree // Current node as root
if cn == nil {
- panic("echo ⇛ invalid method")
+ panic("echo: invalid method")
}
search := path
@@ -296,18 +296,19 @@ func (n *node) checkMethodNotAllowed() HandlerFunc {
// - Get context from `Echo#AcquireContext()`
// - Reset it `Context#Reset()`
// - Return it `Echo#ReleaseContext()`.
-func (r *Router) Find(method, path string, context Context) {
- context.SetPath(path)
+func (r *Router) Find(method, path string, c Context) {
+ ctx := c.(*context)
+ ctx.path = path
cn := r.tree // Current node as root
var (
search = path
- c *node // Child node
- n int // Param counter
- nk kind // Next kind
- nn *node // Next node
- ns string // Next search
- pvalues = context.ParamValues()
+ child *node // Child node
+ n int // Param counter
+ nk kind // Next kind
+ nn *node // Next node
+ ns string // Next search
+ pvalues = ctx.pvalues // Use the internal slice so the interface can keep the illusion of a dynamic slice
)
// Search order static > param > any
@@ -352,20 +353,20 @@ func (r *Router) Find(method, path string, context Context) {
}
// Static node
- if c = cn.findChild(search[0], skind); c != nil {
+ if child = cn.findChild(search[0], skind); child != nil {
// Save next
if cn.prefix[len(cn.prefix)-1] == '/' { // Issue #623
nk = pkind
nn = cn
ns = search
}
- cn = c
+ cn = child
continue
}
// Param node
Param:
- if c = cn.findChildByKind(pkind); c != nil {
+ if child = cn.findChildByKind(pkind); child != nil {
// Issue #378
if len(pvalues) == n {
continue
@@ -378,7 +379,7 @@ func (r *Router) Find(method, path string, context Context) {
ns = search
}
- cn = c
+ cn = child
i, l := 0, len(search)
for ; i < l && search[i] != '/'; i++ {
}
@@ -409,13 +410,13 @@ func (r *Router) Find(method, path string, context Context) {
}
End:
- context.SetHandler(cn.findHandler(method))
- context.SetPath(cn.ppath)
- context.SetParamNames(cn.pnames...)
+ ctx.handler = cn.findHandler(method)
+ ctx.path = cn.ppath
+ ctx.pnames = cn.pnames
// NOTE: Slow zone...
- if context.Handler() == nil {
- context.SetHandler(cn.checkMethodNotAllowed())
+ if ctx.handler == nil {
+ ctx.handler = cn.checkMethodNotAllowed()
// Dig further for any, might have an empty value for *, e.g.
// serving a directory. Issue #207.
@@ -423,12 +424,12 @@ End:
return
}
if h := cn.findHandler(method); h != nil {
- context.SetHandler(h)
+ ctx.handler = h
} else {
- context.SetHandler(cn.checkMethodNotAllowed())
+ ctx.handler = cn.checkMethodNotAllowed()
}
- context.SetPath(cn.ppath)
- context.SetParamNames(cn.pnames...)
+ ctx.path = cn.ppath
+ ctx.pnames = cn.pnames
pvalues[len(cn.pnames)-1] = ""
}
diff --git a/vendor/github.com/labstack/gommon/random/random.go b/vendor/github.com/labstack/gommon/random/random.go
index b76bd9b3..b1ae864a 100644
--- a/vendor/github.com/labstack/gommon/random/random.go
+++ b/vendor/github.com/labstack/gommon/random/random.go
@@ -2,22 +2,24 @@ package random
import (
"math/rand"
+ "strings"
"time"
)
type (
Random struct {
- charset Charset
}
-
- Charset string
)
+// Charsets
const (
- Alphanumeric Charset = Alphabetic + Numeric
- Alphabetic Charset = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- Numeric Charset = "0123456789"
- Hex Charset = Numeric + "abcdef"
+ Uppercase string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ Lowercase = "abcdefghijklmnopqrstuvwxyz"
+ Alphabetic = Uppercase + Lowercase
+ Numeric = "0123456789"
+ Alphanumeric = Alphabetic + Numeric
+ Symbols = "`" + `~!@#$%^&*()-_+={}[]|\;:"<>,./?`
+ Hex = Numeric + "abcdef"
)
var (
@@ -26,27 +28,21 @@ var (
func New() *Random {
rand.Seed(time.Now().UnixNano())
- return &Random{
- charset: Alphanumeric,
- }
-}
-
-func (r *Random) SetCharset(c Charset) {
- r.charset = c
+ return new(Random)
}
-func (r *Random) String(length uint8) string {
+func (r *Random) String(length uint8, charsets ...string) string {
+ charset := strings.Join(charsets, "")
+ if charset == "" {
+ charset = Alphanumeric
+ }
b := make([]byte, length)
for i := range b {
- b[i] = r.charset[rand.Int63()%int64(len(r.charset))]
+ b[i] = charset[rand.Int63()%int64(len(charset))]
}
return string(b)
}
-func SetCharset(c Charset) {
- global.SetCharset(c)
-}
-
-func String(length uint8) string {
- return global.String(length)
+func String(length uint8, charsets ...string) string {
+ return global.String(length, charsets...)
}
diff --git a/vendor/github.com/valyala/fasttemplate/unsafe.go b/vendor/github.com/valyala/fasttemplate/unsafe.go
index 5e25b0ff..0498248f 100644
--- a/vendor/github.com/valyala/fasttemplate/unsafe.go
+++ b/vendor/github.com/valyala/fasttemplate/unsafe.go
@@ -1,3 +1,5 @@
+// +build !appengine
+
package fasttemplate
import (
diff --git a/vendor/github.com/valyala/fasttemplate/unsafe_gae.go b/vendor/github.com/valyala/fasttemplate/unsafe_gae.go
new file mode 100644
index 00000000..cc4ce151
--- /dev/null
+++ b/vendor/github.com/valyala/fasttemplate/unsafe_gae.go
@@ -0,0 +1,11 @@
+// +build appengine
+
+package fasttemplate
+
+func unsafeBytes2String(b []byte) string {
+ return string(b)
+}
+
+func unsafeString2Bytes(s string) []byte {
+ return []byte(s)
+}