mirror of
https://github.com/labstack/echo.git
synced 2025-07-13 01:30:31 +02:00
15
README.md
15
README.md
@ -1,5 +1,6 @@
|
|||||||
# [Echo](http://echo.labstack.com) [](http://godoc.org/github.com/labstack/echo) [](https://travis-ci.org/labstack/echo) [](https://coveralls.io/r/labstack/echo) [](https://gitter.im/labstack/echo)
|
# [Echo](http://echo.labstack.com) [](http://godoc.org/github.com/labstack/echo) [](https://travis-ci.org/labstack/echo) [](https://coveralls.io/r/labstack/echo) [](https://gitter.im/labstack/echo)
|
||||||
Echo is a fast HTTP router (zero dynamic memory allocation) and micro web framework in Go.
|
|
||||||
|
Echo, a fast and unfancy micro web framework for Golang.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@ -75,13 +76,13 @@ BenchmarkZeus_GithubAll 2000 748827 ns/op 30068
|
|||||||
$ go get github.com/labstack/echo
|
$ go get github.com/labstack/echo
|
||||||
```
|
```
|
||||||
|
|
||||||
##[Examples](https://github.com/labstack/echo/tree/master/examples)
|
## [Recipes](https://github.com/labstack/echo/tree/master/recipes)
|
||||||
|
|
||||||
- [Hello, World!](https://github.com/labstack/echo/tree/master/examples/hello)
|
- [File Upload](http://echo.labstack.com/recipes/file-upload)
|
||||||
- [CRUD](https://github.com/labstack/echo/tree/master/examples/crud)
|
- [Streaming File Upload](http://echo.labstack.com/recipes/streaming-file-upload)
|
||||||
- [Website](https://github.com/labstack/echo/tree/master/examples/website)
|
- [Streaming Response](http://echo.labstack.com/recipes/streaming-response)
|
||||||
- [Middleware](https://github.com/labstack/echo/tree/master/examples/middleware)
|
- [WebSocket](http://echo.labstack.com/recipes/websocket)
|
||||||
- [Stream](https://github.com/labstack/echo/tree/master/examples/stream)
|
- [Graceful Shutdown](http://echo.labstack.com/recipes/graceful-shutdown)
|
||||||
|
|
||||||
##[Guide](http://echo.labstack.com/guide)
|
##[Guide](http://echo.labstack.com/guide)
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Multipart File Upload</title>
|
<title>File Upload</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Upload Files</h1>
|
<h1>Upload Files</h1>
|
||||||
<form action="/upload" method=post enctype=multipart/form-data>
|
<form action="/upload" method=post enctype="multipart/form-data">
|
||||||
Name: <input type="text" name="name"><br>
|
Name: <input type="text" name="name"><br>
|
||||||
Email: <input type="email" name="email"><br>
|
Email: <input type="email" name="email"><br>
|
||||||
Files: <input type="file" name="files" multiple><br><br>
|
Files: <input type="file" name="files" multiple><br><br>
|
||||||
|
16
recipes/streaming-file-upload/public/index.html
Normal file
16
recipes/streaming-file-upload/public/index.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!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>
|
@ -39,8 +39,6 @@ func upload(c *echo.Context) error {
|
|||||||
}
|
}
|
||||||
email := string(b)
|
email := string(b)
|
||||||
|
|
||||||
println(name, email)
|
|
||||||
|
|
||||||
// Read files
|
// Read files
|
||||||
i := 0
|
i := 0
|
||||||
for {
|
for {
|
||||||
@ -71,7 +69,7 @@ func upload(c *echo.Context) error {
|
|||||||
func main() {
|
func main() {
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
e.SetDebug(true)
|
e.SetDebug(true)
|
||||||
e.Index("../file-upload/public/index.html")
|
e.Index("public/index.html")
|
||||||
e.Post("/upload", upload)
|
e.Post("/upload", upload)
|
||||||
e.Run(":1323")
|
e.Run(":1323")
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ var (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
e.Get("/stream", func(c *echo.Context) error {
|
e.Get("/", func(c *echo.Context) error {
|
||||||
c.Response().Header().Set(echo.ContentType, echo.ApplicationJSON)
|
c.Response().Header().Set(echo.ContentType, echo.ApplicationJSON)
|
||||||
c.Response().WriteHeader(http.StatusOK)
|
c.Response().WriteHeader(http.StatusOK)
|
||||||
for _, l := range locations {
|
for _, l := range locations {
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
# Echo
|
# Echo
|
||||||
|
|
||||||
Build simple and performant systems!
|
A fast and light web framework for Golang.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
Echo is a fast HTTP router (zero dynamic memory allocation) and micro web framework in Go.
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Fast HTTP router which smartly prioritize routes.
|
- Fast HTTP router which smartly prioritize routes.
|
||||||
@ -110,7 +106,7 @@ Browse to [http://localhost:1323](http://localhost:1323) and you should see
|
|||||||
Hello, World! on the page.
|
Hello, World! on the page.
|
||||||
|
|
||||||
### Next?
|
### Next?
|
||||||
- Browse [examples](https://github.com/labstack/echo/tree/master/examples)
|
- Browse [recipes](https://github.com/labstack/echo/tree/master/recipes)
|
||||||
- Head over to [Guide](guide.md)
|
- Head over to [Guide](guide.md)
|
||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
## Multipart File Upload
|
## File Upload
|
||||||
|
|
||||||
|
- Multipart/form-data file upload
|
||||||
|
- Multiple form fields and files
|
||||||
|
|
||||||
|
Use `req.ParseMultipartForm(16 << 20)` for manually parsing multipart form. It gives
|
||||||
|
us option to specify maximum memory used while parsing the request body.
|
||||||
|
|
||||||
`server.go`
|
`server.go`
|
||||||
|
|
||||||
@ -64,11 +70,11 @@ func main() {
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Multipart File Upload</title>
|
<title>File Upload</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Upload Files</h1>
|
<h1>Upload Files</h1>
|
||||||
<form action="/upload" method=post enctype=multipart/form-data>
|
<form action="/upload" method="post" enctype="multipart/form-data">
|
||||||
Name: <input type="text" name="name"><br>
|
Name: <input type="text" name="name"><br>
|
||||||
Email: <input type="email" name="email"><br>
|
Email: <input type="email" name="email"><br>
|
||||||
Files: <input type="file" name="files" multiple><br><br>
|
Files: <input type="file" name="files" multiple><br><br>
|
||||||
@ -79,4 +85,4 @@ func main() {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## [Source Code]
|
## [Source Code](https://github.com/labstack/echo/blob/master/recipes/file-upload)
|
||||||
|
@ -50,3 +50,9 @@ func main() {
|
|||||||
gracehttp.Serve(e.Server(":1323"))
|
gracehttp.Serve(e.Server(":1323"))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Source Code
|
||||||
|
|
||||||
|
[`graceful`](https://github.com/labstack/echo/blob/master/recipes/graceful-shutdown/graceful)
|
||||||
|
|
||||||
|
[`grace`](https://github.com/labstack/echo/blob/master/recipes/graceful-shutdown/grace)
|
||||||
|
109
website/docs/recipes/streaming-file-upload.md
Normal file
109
website/docs/recipes/streaming-file-upload.md
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
## Streaming File Upload
|
||||||
|
|
||||||
|
- Streaming multipart/form-data file upload
|
||||||
|
- Multiple form fields and files
|
||||||
|
|
||||||
|
`server.go`
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/labstack/echo"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
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, "Thank You! %s <%s>, %d files uploaded successfully.",
|
||||||
|
name, email, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
e := echo.New()
|
||||||
|
e.SetDebug(true)
|
||||||
|
e.Index("../file-upload/public/index.html")
|
||||||
|
e.Post("/upload", upload)
|
||||||
|
e.Run(":1323")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`index.html`
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!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>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## [Source Code](https://github.com/labstack/echo/blob/master/recipes/streaming-file-upload)
|
||||||
|
|
@ -1,5 +1,8 @@
|
|||||||
## Streaming Response
|
## Streaming Response
|
||||||
|
|
||||||
|
- Send data as it is produced
|
||||||
|
- Streaming JSON response with chunked transfer encoding
|
||||||
|
|
||||||
`server.go`
|
`server.go`
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@ -34,7 +37,7 @@ var (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
e.Get("/stream", func(c *echo.Context) error {
|
e.Get("/", func(c *echo.Context) error {
|
||||||
c.Response().Header().Set(echo.ContentType, echo.ApplicationJSON)
|
c.Response().Header().Set(echo.ContentType, echo.ApplicationJSON)
|
||||||
c.Response().WriteHeader(http.StatusOK)
|
c.Response().WriteHeader(http.StatusOK)
|
||||||
for _, l := range locations {
|
for _, l := range locations {
|
||||||
@ -50,4 +53,15 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## [Source Code]()
|
`curl localhost:1323`
|
||||||
|
|
||||||
|
```js
|
||||||
|
{"Altitude":-97,"Latitude":37.819929,"Longitude":-122.478255}
|
||||||
|
{"Altitude":1899,"Latitude":39.096849,"Longitude":-120.032351}
|
||||||
|
{"Altitude":2619,"Latitude":37.865101,"Longitude":-119.538329}
|
||||||
|
{"Altitude":42,"Latitude":33.812092,"Longitude":-117.918974}
|
||||||
|
{"Altitude":15,"Latitude":37.77493,"Longitude":-122.419416}
|
||||||
|
```
|
||||||
|
|
||||||
|
## [Source Code](https://github.com/labstack/echo/blob/master/recipes/streaming-response)
|
||||||
|
|
||||||
|
@ -23,4 +23,5 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## [Source Code]()
|
## [Source Code](https://github.com/labstack/echo/blob/master/recipes/websocket)
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
{% if favicon %}<link rel="shortcut icon" href="{{ favicon }}">
|
{% if favicon %}<link rel="shortcut icon" href="{{ favicon }}">
|
||||||
{% else %}<link rel="shortcut icon" href="{{ base_url }}/img/favicon.ico">{% endif %}
|
{% else %}<link rel="shortcut icon" href="{{ base_url }}/img/favicon.ico">{% endif %}
|
||||||
|
|
||||||
<title>{% if page_title %}{{ page_title }} - {% endif %}{{ site_name }}</title>
|
<title>{% if page_title %}{{ page_title }} - {% endif %}{{ config.extra.site_title }}</title>
|
||||||
|
|
||||||
<link href="{{ base_url }}/css/bootstrap-custom.min.css" rel="stylesheet">
|
<link href="{{ base_url }}/css/bootstrap-custom.min.css" rel="stylesheet">
|
||||||
<link href="{{ base_url }}/css/font-awesome-4.0.3.css" rel="stylesheet">
|
<link href="{{ base_url }}/css/font-awesome-4.0.3.css" rel="stylesheet">
|
||||||
|
@ -9,6 +9,9 @@ pages:
|
|||||||
- Guide: guide.md
|
- Guide: guide.md
|
||||||
- Recipes:
|
- Recipes:
|
||||||
- File Upload: recipes/file-upload.md
|
- File Upload: recipes/file-upload.md
|
||||||
- Graceful Shutdown: recipes/graceful-shutdown.md
|
- Streaming File Upload: recipes/streaming-file-upload.md
|
||||||
- Streaming Response: recipes/streaming-response.md
|
- Streaming Response: recipes/streaming-response.md
|
||||||
- WebSocket: recipes/websocket.md
|
- WebSocket: recipes/websocket.md
|
||||||
|
- Graceful Shutdown: recipes/graceful-shutdown.md
|
||||||
|
extra:
|
||||||
|
site_title: Echo, a fast and unfancy micro web framework for Golang.
|
||||||
|
Reference in New Issue
Block a user