Skip to content
Merged

V5 #382

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 32 additions & 13 deletions cookbook/auto-tls/server.go
Original file line number Diff line number Diff line change
@@ -1,37 +1,56 @@
package main

import (
"context"
"crypto/tls"
"golang.org/x/crypto/acme"
"errors"
"log/slog"
"net/http"
"os"

"golang.org/x/crypto/acme"

"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/echo/v5"
"github.com/labstack/echo/v5/middleware"
"golang.org/x/crypto/acme/autocert"
)

func main() {
e := echo.New()
// e.AutoTLSManager.HostPolicy = autocert.HostWhitelist("<DOMAIN>")
// Cache certificates to avoid issues with rate limits (https://letsencrypt.org/docs/rate-limits)
e.AutoTLSManager.Cache = autocert.DirCache("/var/www/.cache")
e.Logger = slog.New(slog.NewJSONHandler(os.Stdout, nil))

e.Use(middleware.Recover())
e.Use(middleware.Logger())
e.GET("/", func(c echo.Context) error {
e.Use(middleware.RequestLogger())

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"))
m := &autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("example.com", "www.example.com"),
// Cache certificates to avoid issues with rate limits (https://letsencrypt.org/docs/rate-limits)
Cache: autocert.DirCache("/var/www/.cache"),
// Email: "[email protected]", // optional but recommended
}

sc := echo.StartConfig{
Address: ":443",
TLSConfig: m.TLSConfig(),
}
if err := sc.Start(context.Background(), e); err != nil {
e.Logger.Error("failed to start server", "error", err)
}
}

func customHTTPServer() {
e := echo.New()
e.Use(middleware.Recover())
e.Use(middleware.Logger())
e.GET("/", func(c echo.Context) error {
e.Use(middleware.RequestLogger())
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>
Expand All @@ -54,7 +73,7 @@ func customHTTPServer() {
},
//ReadTimeout: 30 * time.Second, // use custom timeouts
}
if err := s.ListenAndServeTLS("", ""); err != http.ErrServerClosed {
e.Logger.Fatal(err)
if err := s.ListenAndServeTLS("", ""); err != nil && !errors.Is(err, http.ErrServerClosed) {
e.Logger.Error("failed to start server", "error", err)
}
}
39 changes: 26 additions & 13 deletions cookbook/cors/origin-func/server.go
Original file line number Diff line number Diff line change
@@ -1,43 +1,56 @@
package main

import (
"context"
"net/http"
"regexp"
"strings"

"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/echo/v5"
"github.com/labstack/echo/v5/middleware"
)

var (
users = []string{"Joe", "Veer", "Zion"}
)

func getUsers(c echo.Context) error {
func getUsers(c *echo.Context) error {
return c.JSON(http.StatusOK, users)
}

// allowOrigin takes the origin as an argument and returns true if the origin
// is allowed or false otherwise.
func allowOrigin(origin string) (bool, error) {
// In this example we use a regular expression but we can imagine various
// allowOrigin takes the origin as an argument and returns:
// - origin to add to the response Access-Control-Allow-Origin header
// - whether the request is allowed or not
// - an optional error. this will stop handler chain execution and return an error response.
//
// return origin, true, err // blocks request with error
// return origin, true, nil // allows CSRF request through
// return origin, false, nil // falls back to legacy token logic
func allowOrigin(c *echo.Context, origin string) (string, bool, error) {
// In this example we use a naive suffix check but we can imagine various
// kind of custom logic. For example, an external datasource could be used
// to maintain the list of allowed origins.
return regexp.MatchString(`^https:\/\/labstack\.(net|com)$`, origin)
if strings.HasSuffix(origin, ".example.com") {
return origin, true, nil
}
return "", false, nil
}

func main() {
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.RequestLogger())
e.Use(middleware.Recover())

// CORS restricted with a custom function to allow origins
// and with the GET, PUT, POST or DELETE methods allowed.
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOriginFunc: allowOrigin,
AllowMethods: []string{http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete},
UnsafeAllowOriginFunc: allowOrigin,
AllowMethods: []string{http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete},
}))

e.GET("/api/users", getUsers)

e.Logger.Fatal(e.Start(":1323"))
sc := echo.StartConfig{Address: ":1323"}
if err := sc.Start(context.Background(), e); err != nil {
e.Logger.Error("failed to start server", "error", err)
}
}
22 changes: 11 additions & 11 deletions cookbook/cors/origin-list/server.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
package main

import (
"context"
"net/http"

"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/echo/v5"
"github.com/labstack/echo/v5/middleware"
)

var (
users = []string{"Joe", "Veer", "Zion"}
)

func getUsers(c echo.Context) error {
func getUsers(c *echo.Context) error {
return c.JSON(http.StatusOK, users)
}

func main() {
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.RequestLogger())
e.Use(middleware.Recover())

// CORS default
// Allows requests from any origin wth GET, HEAD, PUT, POST or DELETE method.
// e.Use(middleware.CORS())
// 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{http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete},
}))
e.Use(middleware.CORS("https://labstack.com", "https://labstack.net"))

e.GET("/api/users", getUsers)

e.Logger.Fatal(e.Start(":1323"))
sc := echo.StartConfig{Address: ":1323"}
if err := sc.Start(context.Background(), e); err != nil {
e.Logger.Error("failed to start server", "error", err)
}
}
22 changes: 13 additions & 9 deletions cookbook/crud/server.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package main

import (
"context"
"net/http"
"strconv"
"sync"

"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/echo/v5"
"github.com/labstack/echo/v5/middleware"
)

type (
Expand All @@ -26,7 +27,7 @@ var (
// Handlers
//----------

func createUser(c echo.Context) error {
func createUser(c *echo.Context) error {
lock.Lock()
defer lock.Unlock()
u := &user{
Expand All @@ -40,14 +41,14 @@ func createUser(c echo.Context) error {
return c.JSON(http.StatusCreated, u)
}

func getUser(c echo.Context) error {
func getUser(c *echo.Context) error {
lock.Lock()
defer lock.Unlock()
id, _ := strconv.Atoi(c.Param("id"))
return c.JSON(http.StatusOK, users[id])
}

func updateUser(c echo.Context) error {
func updateUser(c *echo.Context) error {
lock.Lock()
defer lock.Unlock()
u := new(user)
Expand All @@ -59,15 +60,15 @@ func updateUser(c echo.Context) error {
return c.JSON(http.StatusOK, users[id])
}

func deleteUser(c echo.Context) error {
func deleteUser(c *echo.Context) error {
lock.Lock()
defer lock.Unlock()
id, _ := strconv.Atoi(c.Param("id"))
delete(users, id)
return c.NoContent(http.StatusNoContent)
}

func getAllUsers(c echo.Context) error {
func getAllUsers(c *echo.Context) error {
lock.Lock()
defer lock.Unlock()
return c.JSON(http.StatusOK, users)
Expand All @@ -77,7 +78,7 @@ func main() {
e := echo.New()

// Middleware
e.Use(middleware.Logger())
e.Use(middleware.RequestLogger())
e.Use(middleware.Recover())

// Routes
Expand All @@ -88,5 +89,8 @@ func main() {
e.DELETE("/users/:id", deleteUser)

// Start server
e.Logger.Fatal(e.Start(":1323"))
sc := echo.StartConfig{Address: ":1323"}
if err := sc.Start(context.Background(), e); err != nil {
e.Logger.Error("failed to start server", "error", err)
}
}
2 changes: 0 additions & 2 deletions cookbook/embed-resources/.gitignore

This file was deleted.

11 changes: 0 additions & 11 deletions cookbook/embed-resources/app/index.html

This file was deleted.

1 change: 0 additions & 1 deletion cookbook/embed-resources/app/main.js

This file was deleted.

21 changes: 0 additions & 21 deletions cookbook/embed-resources/server.go

This file was deleted.

9 changes: 7 additions & 2 deletions cookbook/embed/server.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package main

import (
"context"
"embed"
"io/fs"
"log"
"net/http"
"os"

"github.com/labstack/echo/v4"
"github.com/labstack/echo/v5"
)

//go:embed app
Expand All @@ -34,5 +35,9 @@ func main() {
assetHandler := http.FileServer(getFileSystem(useOS))
e.GET("/", echo.WrapHandler(assetHandler))
e.GET("/static/*", echo.WrapHandler(http.StripPrefix("/static/", assetHandler)))
e.Logger.Fatal(e.Start(":1323"))

sc := echo.StartConfig{Address: ":1323"}
if err := sc.Start(context.Background(), e); err != nil {
e.Logger.Error("failed to start server", "error", err)
}
}
17 changes: 11 additions & 6 deletions cookbook/file-download/attachment/server.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
package main

import (
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"context"

"github.com/labstack/echo/v5"
"github.com/labstack/echo/v5/middleware"
)

func main() {
e := echo.New()

e.Use(middleware.Logger())
e.Use(middleware.RequestLogger())
e.Use(middleware.Recover())

e.GET("/", func(c echo.Context) error {
e.GET("/", func(c *echo.Context) error {
return c.File("index.html")
})
e.GET("/attachment", func(c echo.Context) error {
e.GET("/attachment", func(c *echo.Context) error {
return c.Attachment("attachment.txt", "attachment.txt")
})

e.Logger.Fatal(e.Start(":1323"))
sc := echo.StartConfig{Address: ":1323"}
if err := sc.Start(context.Background(), e); err != nil {
e.Logger.Error("failed to start server", "error", err)
}
}
Loading
Loading