mirror of
https://github.com/labstack/echo.git
synced 2025-01-07 23:01:56 +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>
|
MAINTAINER Vishal Rana <vr@labstack.com>
|
||||||
|
|
||||||
COPY server /server
|
ADD argo.json /etc
|
||||||
COPY public /public
|
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)
|
- [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)
|
- [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)
|
- [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)
|
- [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
|
### 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)
|
- [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)
|
- [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)
|
- [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)
|
- [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)
|
- [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)
|
- [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)
|
- [axdg](https://github.com/axdg)
|
||||||
- [vishr](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)
|
- [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)
|
- [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>
|
</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