mirror of
https://github.com/labstack/echo.git
synced 2024-12-22 20:06:21 +02:00
parent
5cd194b6b0
commit
c8d77b2675
@ -1,75 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
mw "github.com/labstack/echo/middleware"
|
||||
)
|
||||
|
||||
type (
|
||||
user struct {
|
||||
ID int
|
||||
Name string
|
||||
}
|
||||
)
|
||||
|
||||
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(mw.Logger())
|
||||
e.Use(mw.Recover())
|
||||
|
||||
// Routes
|
||||
e.Post("/users", createUser)
|
||||
e.Get("/users/:id", getUser)
|
||||
e.Patch("/users/:id", updateUser)
|
||||
e.Delete("/users/:id", deleteUser)
|
||||
|
||||
// Start server
|
||||
e.Run(":1323")
|
||||
}
|
2
recipes/embed-resources/.gitignore
vendored
2
recipes/embed-resources/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
rice
|
||||
app.rice-box.go
|
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>go.rice Example</title>
|
||||
<script src="/static/main.js" charset="utf-8"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>go.rice Example</h1>
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
alert("main.js");
|
@ -1,26 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"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("/", func(c *echo.Context) error {
|
||||
assetHandler.ServeHTTP(c.Response().Writer(), c.Request())
|
||||
return nil
|
||||
})
|
||||
// servers other static files
|
||||
e.Get("/static/*", func(c *echo.Context) error {
|
||||
http.StripPrefix("/static/", assetHandler).
|
||||
ServeHTTP(c.Response().Writer(), c.Request())
|
||||
return nil
|
||||
})
|
||||
e.Run(":3000")
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>File Upload</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Upload Files</h1>
|
||||
|
||||
<form action="/upload" method=post enctype="multipart/form-data">
|
||||
Name: <input type="text" name="name"><br>
|
||||
Email: <input type="email" name="email"><br>
|
||||
Files: <input type="file" name="files" multiple><br><br>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -1,56 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
mw "github.com/labstack/echo/middleware"
|
||||
)
|
||||
|
||||
func upload(c *echo.Context) error {
|
||||
req := c.Request()
|
||||
req.ParseMultipartForm(16 << 20) // Max memory 16 MiB
|
||||
|
||||
// Read form fields
|
||||
name := c.Form("name")
|
||||
email := c.Form("email")
|
||||
|
||||
// Read files
|
||||
files := req.MultipartForm.File["files"]
|
||||
for _, f := range files {
|
||||
// Source file
|
||||
src, err := f.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
// Destination file
|
||||
dst, err := os.Create(f.Filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dst.Close()
|
||||
|
||||
if _, err = io.Copy(dst, src); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return c.String(http.StatusOK, fmt.Sprintf("Thank You! %s <%s>, %d files uploaded successfully.",
|
||||
name, email, len(files)))
|
||||
}
|
||||
|
||||
func main() {
|
||||
e := echo.New()
|
||||
e.Use(mw.Logger())
|
||||
e.Use(mw.Recover())
|
||||
|
||||
e.Static("/", "public")
|
||||
e.Post("/upload", upload)
|
||||
|
||||
e.Run(":1323")
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
# Dockerfile extending the generic Go image with application files for a
|
||||
# single application.
|
||||
FROM gcr.io/google_appengine/golang
|
||||
|
||||
COPY . /go/src/app
|
||||
RUN go-wrapper download
|
||||
RUN go-wrapper install -tags appenginevm
|
@ -1,18 +0,0 @@
|
||||
// +build appengine
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
application: my-application-id # defined when you create your app using google dev console
|
||||
module: default # see https://cloud.google.com/appengine/docs/go/
|
||||
version: alpha # you can run multiple versions of an app and A/B test
|
||||
runtime: go # see https://cloud.google.com/appengine/docs/go/
|
||||
api_version: go1 # used when appengine supports different go versions
|
||||
|
||||
default_expiration: "1d" # for CDN serving of static files (use url versioning if long!)
|
||||
|
||||
handlers:
|
||||
# all the static files that we normally serve ourselves are defined here and Google will handle
|
||||
# serving them for us from it's own CDN / edge locations. For all the configuration options see:
|
||||
# https://cloud.google.com/appengine/docs/go/config/appconfig#Go_app_yaml_Static_file_handlers
|
||||
- url: /
|
||||
mime_type: text/html
|
||||
static_files: public/index.html
|
||||
upload: public/index.html
|
||||
|
||||
- url: /favicon.ico
|
||||
mime_type: image/x-icon
|
||||
static_files: public/favicon.ico
|
||||
upload: public/favicon.ico
|
||||
|
||||
- url: /scripts
|
||||
mime_type: text/javascript
|
||||
static_dir: public/scripts
|
||||
|
||||
# static files normally don't touch the server that the app runs on but server-side template files
|
||||
# needs to be readable by the app. The application_readable option makes sure they are available as
|
||||
# part of the app deployment onto the instance.
|
||||
- url: /templates
|
||||
static_dir: /templates
|
||||
application_readable: true
|
||||
|
||||
# finally, we route all other requests to our application. The script name just means "the go app"
|
||||
- url: /.*
|
||||
script: _go_app
|
@ -1,29 +0,0 @@
|
||||
// +build appenginevm
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo"
|
||||
"google.golang.org/appengine"
|
||||
"net/http"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func createMux() *echo.Echo {
|
||||
// we're in a container on a Google Compute Engine instance so are not sandboxed anymore ...
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
||||
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
|
||||
http.Handle("/", e)
|
||||
appengine.Main()
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
application: my-application-id # defined when you create your app using google dev console
|
||||
module: default # see https://cloud.google.com/appengine/docs/go/
|
||||
version: alpha # you can run multiple versions of an app and A/B test
|
||||
runtime: go # see https://cloud.google.com/appengine/docs/go/
|
||||
api_version: go1 # used when appengine supports different go versions
|
||||
vm: true # for managed VMs only, remove for appengine classic
|
||||
|
||||
default_expiration: "1d" # for CDN serving of static files (use url versioning if long!)
|
||||
|
||||
handlers:
|
||||
# all the static files that we normally serve ourselves are defined here and Google will handle
|
||||
# serving them for us from it's own CDN / edge locations. For all the configuration options see:
|
||||
# https://cloud.google.com/appengine/docs/go/config/appconfig#Go_app_yaml_Static_file_handlers
|
||||
- url: /
|
||||
mime_type: text/html
|
||||
static_files: public/index.html
|
||||
upload: public/index.html
|
||||
|
||||
- url: /favicon.ico
|
||||
mime_type: image/x-icon
|
||||
static_files: public/favicon.ico
|
||||
upload: public/favicon.ico
|
||||
|
||||
- url: /scripts
|
||||
mime_type: text/javascript
|
||||
static_dir: public/scripts
|
||||
|
||||
# static files normally don't touch the server that the app runs on but server-side template files
|
||||
# needs to be readable by the app. The application_readable option makes sure they are available as
|
||||
# part of the app deployment onto the instance.
|
||||
- url: /templates
|
||||
static_dir: /templates
|
||||
application_readable: true
|
||||
|
||||
# finally, we route all other requests to our application. The script name just means "the go app"
|
||||
- url: /.*
|
||||
script: _go_app
|
@ -1,25 +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.Index("public/index.html")
|
||||
e.Static("/public", "public")
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func main() {
|
||||
e.Run(":8080")
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
package main
|
||||
|
||||
// referecnce our echo instance and create it early
|
||||
var e = createMux()
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB |
@ -1,15 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Echo</title>
|
||||
<link rel="shortcut icon" href="favicon.ico" />
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Echo!</h1>
|
||||
<script src="/scripts/main.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
console.log("Echo!");
|
@ -1 +0,0 @@
|
||||
{{define "welcome"}}Hello, {{.}}!{{end}}
|
@ -1,54 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
"github.com/rs/cors"
|
||||
)
|
||||
|
||||
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(cors.Default().Handler)
|
||||
|
||||
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.P(0)])
|
||||
}
|
@ -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.SetRenderer(t)
|
||||
e.Get("/welcome", welcome)
|
||||
}
|
||||
|
||||
func (t *Template) Render(w io.Writer, name string, data interface{}) error {
|
||||
return t.templates.ExecuteTemplate(w, name, data)
|
||||
}
|
||||
|
||||
func welcome(c *echo.Context) error {
|
||||
return c.Render(http.StatusOK, "welcome", "Joe")
|
||||
}
|
@ -1,27 +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")
|
||||
})
|
||||
|
||||
// Get the http.Server
|
||||
s := e.Server(":1323")
|
||||
|
||||
// HTTP2 is currently enabled by default in echo.New(). To override TLS handshake errors
|
||||
// you will need to override the TLSConfig for the server so it does not attempt to validate
|
||||
// the connection using TLS as required by HTTP2
|
||||
s.TLSConfig = nil
|
||||
|
||||
// Serve it like a boss
|
||||
gracehttp.Serve(s)
|
||||
}
|
@ -1,19 +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")
|
||||
})
|
||||
|
||||
graceful.ListenAndServe(e.Server(":1323"), 5*time.Second)
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
mw "github.com/labstack/echo/middleware"
|
||||
)
|
||||
|
||||
// Handler
|
||||
func hello(c *echo.Context) error {
|
||||
return c.String(http.StatusOK, "Hello, World!\n")
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Echo instance
|
||||
e := echo.New()
|
||||
|
||||
// Middleware
|
||||
e.Use(mw.Logger())
|
||||
e.Use(mw.Recover())
|
||||
|
||||
// Routes
|
||||
e.Get("/", hello)
|
||||
|
||||
// Start server
|
||||
e.Run(":1323")
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
|
||||
<title>JSONP</title>
|
||||
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var host_prefix = 'http://localhost:3999';
|
||||
$(document).ready(function() {
|
||||
// JSONP version - add 'callback=?' to the URL - fetch the JSONP response to the request
|
||||
$("#jsonp-button").click(function(e) {
|
||||
e.preventDefault();
|
||||
// The only difference on the client end is the addition of 'callback=?' to the URL
|
||||
var url = host_prefix + '/jsonp?callback=?';
|
||||
$.getJSON(url, function(jsonp) {
|
||||
console.log(jsonp);
|
||||
$("#jsonp-response").html(JSON.stringify(jsonp, null, 2));
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container" style="margin-top: 50px;">
|
||||
<input type="button" class="btn btn-primary btn-lg" id="jsonp-button" value="Get JSONP response">
|
||||
<p>
|
||||
<pre id="jsonp-response"></pre>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,31 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Setup
|
||||
e := echo.New()
|
||||
e.ServeDir("/", "public")
|
||||
|
||||
e.Get("/jsonp", func(c *echo.Context) error {
|
||||
callback := c.Query("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.Run(":3999")
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/labstack/echo"
|
||||
mw "github.com/labstack/echo/middleware"
|
||||
)
|
||||
|
||||
const (
|
||||
Bearer = "Bearer"
|
||||
SigningKey = "somethingsupersecret"
|
||||
)
|
||||
|
||||
// A JSON Web Token middleware
|
||||
func JWTAuth(key string) echo.HandlerFunc {
|
||||
return func(c *echo.Context) error {
|
||||
|
||||
// Skip WebSocket
|
||||
if (c.Request().Header.Get(echo.Upgrade)) == echo.WebSocket {
|
||||
return nil
|
||||
}
|
||||
|
||||
auth := c.Request().Header.Get("Authorization")
|
||||
l := len(Bearer)
|
||||
he := echo.NewHTTPError(http.StatusUnauthorized)
|
||||
|
||||
if len(auth) > l+1 && auth[:l] == Bearer {
|
||||
t, err := jwt.Parse(auth[l+1:], func(token *jwt.Token) (interface{}, error) {
|
||||
|
||||
// Always check the signing method
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
|
||||
// Return the key for validation
|
||||
return []byte(key), nil
|
||||
})
|
||||
if err == nil && t.Valid {
|
||||
// Store token claims in echo.Context
|
||||
c.Set("claims", t.Claims)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return he
|
||||
}
|
||||
}
|
||||
|
||||
func accessible(c *echo.Context) error {
|
||||
return c.String(http.StatusOK, "No auth required for this route.\n")
|
||||
}
|
||||
|
||||
func restricted(c *echo.Context) error {
|
||||
return c.String(http.StatusOK, "Access granted with JWT.\n")
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Echo instance
|
||||
e := echo.New()
|
||||
|
||||
// Logger
|
||||
e.Use(mw.Logger())
|
||||
|
||||
// Unauthenticated route
|
||||
e.Get("/", accessible)
|
||||
|
||||
// Restricted group
|
||||
r := e.Group("/restricted")
|
||||
r.Use(JWTAuth(SigningKey))
|
||||
r.Get("", restricted)
|
||||
|
||||
// Start server
|
||||
e.Run(":1323")
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
const SigningKey = "somethingsupersecret"
|
||||
|
||||
func main() {
|
||||
|
||||
// New web token.
|
||||
token := jwt.New(jwt.SigningMethodHS256)
|
||||
|
||||
// Set a header and a claim
|
||||
token.Header["typ"] = "JWT"
|
||||
token.Claims["exp"] = time.Now().Add(time.Hour * 96).Unix()
|
||||
|
||||
// Generate encoded token
|
||||
t, _ := token.SignedString([]byte(SigningKey))
|
||||
fmt.Println(t)
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
mw "github.com/labstack/echo/middleware"
|
||||
)
|
||||
|
||||
// Handler
|
||||
func hello(c *echo.Context) error {
|
||||
return c.String(http.StatusOK, "Hello, World!\n")
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Echo instance
|
||||
e := echo.New()
|
||||
|
||||
// Debug mode
|
||||
e.Debug()
|
||||
|
||||
//------------
|
||||
// Middleware
|
||||
//------------
|
||||
|
||||
// Logger
|
||||
e.Use(mw.Logger())
|
||||
|
||||
// Recover
|
||||
e.Use(mw.Recover())
|
||||
|
||||
// Basic auth
|
||||
e.Use(mw.BasicAuth(func(usr, pwd string) bool {
|
||||
if usr == "joe" && pwd == "secret" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}))
|
||||
|
||||
// Gzip
|
||||
e.Use(mw.Gzip())
|
||||
|
||||
// Routes
|
||||
e.Get("/", hello)
|
||||
|
||||
// Start server
|
||||
e.Run(":1323")
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>File Upload</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Upload Files</h1>
|
||||
|
||||
<form action="/upload" method=post enctype="multipart/form-data">
|
||||
Name: <input type="text" name="name"><br>
|
||||
Email: <input type="email" name="email"><br>
|
||||
Files: <input type="file" name="files" multiple><br><br>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -1,81 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
mw "github.com/labstack/echo/middleware"
|
||||
)
|
||||
|
||||
func upload(c *echo.Context) error {
|
||||
mr, err := c.Request().MultipartReader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read form field `name`
|
||||
part, err := mr.NextPart()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer part.Close()
|
||||
b, err := ioutil.ReadAll(part)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := string(b)
|
||||
|
||||
// Read form field `email`
|
||||
part, err = mr.NextPart()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer part.Close()
|
||||
b, err = ioutil.ReadAll(part)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
email := string(b)
|
||||
|
||||
// Read files
|
||||
i := 0
|
||||
for {
|
||||
part, err := mr.NextPart()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return err
|
||||
}
|
||||
defer part.Close()
|
||||
|
||||
file, err := os.Create(part.FileName())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if _, err := io.Copy(file, part); err != nil {
|
||||
return err
|
||||
}
|
||||
i++
|
||||
}
|
||||
return c.String(http.StatusOK, fmt.Sprintf("Thank You! %s <%s>, %d files uploaded successfully.",
|
||||
name, email, i))
|
||||
}
|
||||
|
||||
func main() {
|
||||
e := echo.New()
|
||||
e.Use(mw.Logger())
|
||||
e.Use(mw.Recover())
|
||||
|
||||
e.Static("/", "public")
|
||||
e.Post("/upload", upload)
|
||||
|
||||
e.Run(":1323")
|
||||
}
|
@ -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.ContentType, echo.ApplicationJSON)
|
||||
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.Run(":1323")
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
mw "github.com/labstack/echo/middleware"
|
||||
)
|
||||
|
||||
type Hosts map[string]http.Handler
|
||||
|
||||
func (h Hosts) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if handler := h[r.Host]; handler != nil {
|
||||
handler.ServeHTTP(w, r)
|
||||
} else {
|
||||
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Host map
|
||||
hosts := make(Hosts)
|
||||
|
||||
//-----
|
||||
// API
|
||||
//-----
|
||||
|
||||
api := echo.New()
|
||||
api.Use(mw.Logger())
|
||||
api.Use(mw.Recover())
|
||||
|
||||
hosts["api.localhost:1323"] = api
|
||||
|
||||
api.Get("/", func(c *echo.Context) error {
|
||||
return c.String(http.StatusOK, "API")
|
||||
})
|
||||
|
||||
//------
|
||||
// Blog
|
||||
//------
|
||||
|
||||
blog := echo.New()
|
||||
blog.Use(mw.Logger())
|
||||
blog.Use(mw.Recover())
|
||||
|
||||
hosts["blog.localhost:1323"] = blog
|
||||
|
||||
blog.Get("/", func(c *echo.Context) error {
|
||||
return c.String(http.StatusOK, "Blog")
|
||||
})
|
||||
|
||||
//---------
|
||||
// Website
|
||||
//---------
|
||||
|
||||
site := echo.New()
|
||||
site.Use(mw.Logger())
|
||||
site.Use(mw.Recover())
|
||||
|
||||
hosts["localhost:1323"] = site
|
||||
|
||||
site.Get("/", func(c *echo.Context) error {
|
||||
return c.String(http.StatusOK, "Welcome!")
|
||||
})
|
||||
|
||||
http.ListenAndServe(":1323", hosts)
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB |
@ -1 +0,0 @@
|
||||
sub directory
|
@ -1,15 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Echo</title>
|
||||
<link rel="shortcut icon" href="favicon.ico"/>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Echo!</h1>
|
||||
<script src="/scripts/main.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
console.log("Echo!")
|
@ -1 +0,0 @@
|
||||
{{define "welcome"}}Hello, {{.}}!{{end}}
|
@ -1,146 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"html/template"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
mw "github.com/labstack/echo/middleware"
|
||||
"github.com/rs/cors"
|
||||
"github.com/thoas/stats"
|
||||
)
|
||||
|
||||
type (
|
||||
// Template provides HTML template rendering
|
||||
Template struct {
|
||||
templates *template.Template
|
||||
}
|
||||
|
||||
user struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
users map[string]user
|
||||
)
|
||||
|
||||
// Render HTML
|
||||
func (t *Template) Render(w io.Writer, name string, data interface{}) error {
|
||||
return t.templates.ExecuteTemplate(w, name, data)
|
||||
}
|
||||
|
||||
//----------
|
||||
// Handlers
|
||||
//----------
|
||||
|
||||
func welcome(c *echo.Context) error {
|
||||
return c.Render(http.StatusOK, "welcome", "Joe")
|
||||
}
|
||||
|
||||
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.P(0)])
|
||||
}
|
||||
|
||||
func main() {
|
||||
e := echo.New()
|
||||
|
||||
// Middleware
|
||||
e.Use(mw.Logger())
|
||||
e.Use(mw.Recover())
|
||||
e.Use(mw.Gzip())
|
||||
|
||||
//------------------------
|
||||
// Third-party middleware
|
||||
//------------------------
|
||||
|
||||
// https://github.com/rs/cors
|
||||
e.Use(cors.Default().Handler)
|
||||
|
||||
// https://github.com/thoas/stats
|
||||
s := stats.New()
|
||||
e.Use(s.Handler)
|
||||
// Route
|
||||
e.Get("/stats", func(c *echo.Context) error {
|
||||
return c.JSON(http.StatusOK, s.Data())
|
||||
})
|
||||
|
||||
// Serve index file
|
||||
e.Index("public/index.html")
|
||||
|
||||
// Serve favicon
|
||||
e.Favicon("public/favicon.ico")
|
||||
|
||||
// Serve static files
|
||||
e.Static("/scripts", "public/scripts")
|
||||
|
||||
//--------
|
||||
// Routes
|
||||
//--------
|
||||
|
||||
e.Post("/users", createUser)
|
||||
e.Get("/users", getUsers)
|
||||
e.Get("/users/:id", getUser)
|
||||
|
||||
//-----------
|
||||
// Templates
|
||||
//-----------
|
||||
|
||||
t := &Template{
|
||||
// Cached templates
|
||||
templates: template.Must(template.ParseFiles("public/views/welcome.html")),
|
||||
}
|
||||
e.SetRenderer(t)
|
||||
e.Get("/welcome", welcome)
|
||||
|
||||
//-------
|
||||
// Group
|
||||
//-------
|
||||
|
||||
// Group with parent middleware
|
||||
a := e.Group("/admin")
|
||||
a.Use(func(c *echo.Context) error {
|
||||
// Security middleware
|
||||
return nil
|
||||
})
|
||||
a.Get("", func(c *echo.Context) error {
|
||||
return c.String(http.StatusOK, "Welcome admin!")
|
||||
})
|
||||
|
||||
// Group with no parent middleware
|
||||
g := e.Group("/files", func(c *echo.Context) error {
|
||||
// Security middleware
|
||||
return nil
|
||||
})
|
||||
g.Get("", func(c *echo.Context) error {
|
||||
return c.String(http.StatusOK, "Your files!")
|
||||
})
|
||||
|
||||
// Start server
|
||||
e.Run(":1323")
|
||||
}
|
||||
|
||||
func init() {
|
||||
users = map[string]user{
|
||||
"1": user{
|
||||
ID: "1",
|
||||
Name: "Wreck-It Ralph",
|
||||
},
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebSocket</title>
|
||||
</head>
|
||||
<body>
|
||||
<p id="output"></p>
|
||||
|
||||
<script>
|
||||
var loc = window.location;
|
||||
var uri = 'ws:';
|
||||
|
||||
if (loc.protocol === 'https:') {
|
||||
uri = 'wss:';
|
||||
}
|
||||
uri += '//' + loc.host;
|
||||
uri += loc.pathname + 'ws';
|
||||
|
||||
ws = new WebSocket(uri)
|
||||
|
||||
ws.onopen = function() {
|
||||
console.log('Connected')
|
||||
}
|
||||
|
||||
ws.onmessage = function(evt) {
|
||||
var out = document.getElementById('output');
|
||||
out.innerHTML += evt.data + '<br>';
|
||||
}
|
||||
|
||||
setInterval(function() {
|
||||
ws.send('Hello, Server!');
|
||||
}, 1000);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,34 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/labstack/echo"
|
||||
mw "github.com/labstack/echo/middleware"
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
e := echo.New()
|
||||
|
||||
e.Use(mw.Logger())
|
||||
e.Use(mw.Recover())
|
||||
|
||||
e.Static("/", "public")
|
||||
e.WebSocket("/ws", func(c *echo.Context) (err error) {
|
||||
ws := c.Socket()
|
||||
msg := ""
|
||||
|
||||
for {
|
||||
if err = websocket.Message.Send(ws, "Hello, Client!"); err != nil {
|
||||
return
|
||||
}
|
||||
if err = websocket.Message.Receive(ws, &msg); err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(msg)
|
||||
}
|
||||
})
|
||||
|
||||
e.Run(":1323")
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
FROM busybox
|
||||
FROM reg.lab.st/argo
|
||||
MAINTAINER Vishal Rana <vr@labstack.com>
|
||||
|
||||
COPY server /server
|
||||
COPY public /public
|
||||
ADD argo.json /etc
|
||||
ADD public /www
|
||||
|
||||
CMD ["/server"]
|
||||
CMD ["-c", "/etc/argo.json"]
|
||||
|
14
website/argo.json
Normal file
14
website/argo.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"www": {
|
||||
"listen": ":80",
|
||||
"hosts": {
|
||||
"*": {
|
||||
"paths": {
|
||||
"/*": {
|
||||
"dir": "/www"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -16,4 +16,4 @@ menu:
|
||||
|
||||
- [vishr](https://github.com/vishr)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/crud)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/crud)
|
||||
|
@ -17,4 +17,4 @@ menu:
|
||||
|
||||
- [caarlos0](https://github.com/caarlos0)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/rice)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/rice)
|
||||
|
@ -50,4 +50,4 @@ if _, err = io.Copy(dst, file); err != nil {
|
||||
|
||||
- [vishr](https://github.com/vishr)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/file-upload)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/file-upload)
|
||||
|
@ -132,4 +132,4 @@ but is outside the scope of this recipe.
|
||||
|
||||
- [CaptainCodeman](https://github.com/CaptainCodeman)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/google-app-engine)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/google-app-engine)
|
||||
|
@ -24,6 +24,6 @@ menu:
|
||||
|
||||
### Source Code
|
||||
|
||||
[graceful](https://github.com/labstack/echo/blob/master/recipes/graceful-shutdown/graceful)
|
||||
[graceful](https://github.com/vishr/recipes/blob/master/echo/recipes/graceful-shutdown/graceful)
|
||||
|
||||
[grace](https://github.com/labstack/echo/blob/master/recipes/graceful-shutdown/grace)
|
||||
[grace](https://github.com/vishr/recipes/blob/master/echo/recipes/graceful-shutdown/grace)
|
||||
|
@ -16,4 +16,4 @@ menu:
|
||||
|
||||
- [vishr](https://github.com/vishr)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/hello-world)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/hello-world)
|
||||
|
@ -24,4 +24,4 @@ JSONP is a method that allows cross-domain server calls. You can read more about
|
||||
|
||||
- [willf](https://github.com/willf)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/jsonp)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/jsonp)
|
||||
|
@ -55,4 +55,4 @@ $ curl localhost:1323/restricted -H "Authorization: Bearer <token>" => Access g
|
||||
|
||||
- [axdg](https://github.com/axdg)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/jwt-authentication)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/jwt-authentication)
|
||||
|
@ -17,4 +17,4 @@ menu:
|
||||
|
||||
- [vishr](https://github.com/vishr)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/middleware)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/middleware)
|
||||
|
@ -25,4 +25,4 @@ menu:
|
||||
|
||||
- [vishr](https://github.com/vishr)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/streaming-file-upload)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/streaming-file-upload)
|
||||
|
@ -35,4 +35,4 @@ $ curl localhost:1323
|
||||
|
||||
- [vishr](https://github.com/vishr)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/streaming-response)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/streaming-response)
|
||||
|
@ -15,4 +15,4 @@ menu:
|
||||
- [axdg](https://github.com/axdg)
|
||||
- [vishr](https://github.com/axdg)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/subdomains)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/subdomains)
|
||||
|
@ -22,4 +22,4 @@ menu:
|
||||
|
||||
- [vishr](https://github.com/vishr)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/website)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/website)
|
||||
|
@ -44,4 +44,4 @@ Hello, Server!
|
||||
|
||||
- [vishr](https://github.com/vishr)
|
||||
|
||||
### [Source Code](https://github.com/labstack/echo/blob/master/recipes/websocket)
|
||||
### [Source Code](https://github.com/vishr/recipes/blob/master/echo/recipes/websocket)
|
||||
|
@ -1,2 +1,2 @@
|
||||
<pre data-src="https://raw.githubusercontent.com/labstack/echo/master/recipes/{{ .Get 0 }}">
|
||||
<pre data-src="https://raw.githubusercontent.com/vishr/recipes/master/echo/recipes/{{ .Get 0 }}">
|
||||
</pre>
|
||||
|
@ -1 +0,0 @@
|
||||
{}
|
@ -1,17 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo"
|
||||
mw "github.com/labstack/echo/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
e := echo.New()
|
||||
e.Use(mw.Logger())
|
||||
e.Use(mw.Recover())
|
||||
e.Use(mw.Gzip())
|
||||
|
||||
e.Static("/", "public")
|
||||
|
||||
e.Run(":80")
|
||||
}
|
Loading…
Reference in New Issue
Block a user