diff options
Diffstat (limited to 'vendor/github.com/labstack/echo/cookbook')
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")) +} |