summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/labstack/echo/cookbook
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/labstack/echo/cookbook')
-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
30 files changed, 1291 insertions, 0 deletions
diff --git a/vendor/github.com/labstack/echo/cookbook/auto-tls/server.go b/vendor/github.com/labstack/echo/cookbook/auto-tls/server.go
new file mode 100644
index 00000000..4a8bbdfd
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/auto-tls/server.go
@@ -0,0 +1,26 @@
+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
new file mode 100644
index 00000000..0cc5c345
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/cors/server.go
@@ -0,0 +1,38 @@
+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
new file mode 100644
index 00000000..fbb5c754
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/crud/server.go
@@ -0,0 +1,75 @@
+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
new file mode 100644
index 00000000..e5b0c3db
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/embed-resources/server.go
@@ -0,0 +1,21 @@
+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
new file mode 100644
index 00000000..cd0f54d3
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/file-upload/multiple/server.go
@@ -0,0 +1,65 @@
+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
new file mode 100644
index 00000000..1b84f220
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/file-upload/single/server.go
@@ -0,0 +1,59 @@
+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
new file mode 100644
index 00000000..0c1db087
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/google-app-engine/app-engine.go
@@ -0,0 +1,17 @@
+// +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
new file mode 100644
index 00000000..7b8eacf8
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/google-app-engine/app-managed.go
@@ -0,0 +1,25 @@
+// +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
new file mode 100644
index 00000000..c3b44dc0
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/google-app-engine/app-standalone.go
@@ -0,0 +1,24 @@
+// +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
new file mode 100644
index 00000000..8d4d97a2
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/google-app-engine/app.go
@@ -0,0 +1,4 @@
+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
new file mode 100644
index 00000000..19533e51
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/google-app-engine/users.go
@@ -0,0 +1,54 @@
+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
new file mode 100644
index 00000000..2639b209
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/google-app-engine/welcome.go
@@ -0,0 +1,31 @@
+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
new file mode 100644
index 00000000..1f9937b0
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/graceful-shutdown/grace/server.go
@@ -0,0 +1,20 @@
+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
new file mode 100644
index 00000000..39e7b634
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/graceful-shutdown/graceful/server.go
@@ -0,0 +1,21 @@
+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
new file mode 100644
index 00000000..06e0718b
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/hello-world/server.go
@@ -0,0 +1,25 @@
+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
new file mode 100644
index 00000000..8db989c4
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/http2/server.go
@@ -0,0 +1,42 @@
+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
new file mode 100644
index 00000000..ba46bab0
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/jsonp/server.go
@@ -0,0 +1,35 @@
+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
new file mode 100644
index 00000000..b3a13205
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/jwt/custom-claims/server.go
@@ -0,0 +1,86 @@
+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
new file mode 100644
index 00000000..678be490
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/jwt/map-claims/server.go
@@ -0,0 +1,69 @@
+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
new file mode 100644
index 00000000..2f21df50
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/middleware/server.go
@@ -0,0 +1,82 @@
+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
new file mode 100644
index 00000000..a3a679ef
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/streaming-response/server.go
@@ -0,0 +1,45 @@
+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
new file mode 100644
index 00000000..ef4f65f9
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/subdomains/server.go
@@ -0,0 +1,78 @@
+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
new file mode 100644
index 00000000..263c5e21
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/twitter/handler/handler.go
@@ -0,0 +1,14 @@
+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
new file mode 100644
index 00000000..b1428a30
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/twitter/handler/post.go
@@ -0,0 +1,73 @@
+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
new file mode 100644
index 00000000..a34d2f4e
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/twitter/handler/user.go
@@ -0,0 +1,97 @@
+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
new file mode 100644
index 00000000..7344296e
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/twitter/model/post.go
@@ -0,0 +1,12 @@
+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
new file mode 100644
index 00000000..e063c89b
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/twitter/model/user.go
@@ -0,0 +1,13 @@
+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
new file mode 100644
index 00000000..22db7aa0
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/twitter/server.go
@@ -0,0 +1,52 @@
+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
new file mode 100644
index 00000000..e9d52dbb
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/websocket/gorilla/server.go
@@ -0,0 +1,47 @@
+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
new file mode 100644
index 00000000..aa746030
--- /dev/null
+++ b/vendor/github.com/labstack/echo/cookbook/websocket/net/server.go
@@ -0,0 +1,41 @@
+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"))
+}