mirror of
https://github.com/labstack/echo.git
synced 2024-11-24 08:22:21 +02:00
more godoc
Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
parent
d01e856db6
commit
c4caeb8ffb
107
context.go
107
context.go
@ -22,40 +22,108 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// Context represents context for the current request. It holds request and
|
// Context represents the context of the current HTTP request. It holds request and
|
||||||
// response objects, path parameters, data and registered handler.
|
// response objects, path, path parameters, data and registered handler.
|
||||||
Context interface {
|
Context interface {
|
||||||
netContext.Context
|
netContext.Context
|
||||||
|
|
||||||
|
// NetContext returns `http://blog.golang.org/context.Context` interface.
|
||||||
NetContext() netContext.Context
|
NetContext() netContext.Context
|
||||||
|
|
||||||
|
// SetNetContext sets `http://blog.golang.org/context.Context` interface.
|
||||||
SetNetContext(netContext.Context)
|
SetNetContext(netContext.Context)
|
||||||
|
|
||||||
|
// Request returns `engine.Request` interface.
|
||||||
Request() engine.Request
|
Request() engine.Request
|
||||||
|
|
||||||
|
// Request returns `engine.Response` interface.
|
||||||
Response() engine.Response
|
Response() engine.Response
|
||||||
|
|
||||||
|
// Path returns the registered path for the handler.
|
||||||
Path() string
|
Path() string
|
||||||
|
|
||||||
|
// P returns path parameter by index.
|
||||||
P(int) string
|
P(int) string
|
||||||
|
|
||||||
|
// Param returns path parameter by name.
|
||||||
Param(string) string
|
Param(string) string
|
||||||
|
|
||||||
|
// ParamNames returns path parameter names.
|
||||||
ParamNames() []string
|
ParamNames() []string
|
||||||
|
|
||||||
|
// Query returns query parameter by name.
|
||||||
Query(string) string
|
Query(string) string
|
||||||
|
|
||||||
|
// Form returns form parameter by name.
|
||||||
Form(string) string
|
Form(string) string
|
||||||
|
|
||||||
|
// Get retrieves data from the context.
|
||||||
Get(string) interface{}
|
Get(string) interface{}
|
||||||
|
|
||||||
|
// Set saves data in the context.
|
||||||
Set(string, interface{})
|
Set(string, interface{})
|
||||||
|
|
||||||
|
// Bind binds the request body into provided type `i`. The default binder does
|
||||||
|
// it based on Content-Type header.
|
||||||
Bind(interface{}) error
|
Bind(interface{}) error
|
||||||
|
|
||||||
|
// Render renders a template with data and sends a text/html response with status
|
||||||
|
// code. Templates can be registered using `Echo.SetRenderer()`.
|
||||||
Render(int, string, interface{}) error
|
Render(int, string, interface{}) error
|
||||||
|
|
||||||
|
// HTML sends an HTTP response with status code.
|
||||||
HTML(int, string) error
|
HTML(int, string) error
|
||||||
|
|
||||||
|
// String sends a string response with status code.
|
||||||
String(int, string) error
|
String(int, string) error
|
||||||
|
|
||||||
|
// JSON sends a JSON response with status code.
|
||||||
JSON(int, interface{}) error
|
JSON(int, interface{}) error
|
||||||
|
|
||||||
|
// JSONBlob sends a JSON blob response with status code.
|
||||||
JSONBlob(int, []byte) error
|
JSONBlob(int, []byte) error
|
||||||
|
|
||||||
|
// JSONP sends a JSONP response with status code. It uses `callback` to construct
|
||||||
|
// the JSONP payload.
|
||||||
JSONP(int, string, interface{}) error
|
JSONP(int, string, interface{}) error
|
||||||
|
|
||||||
|
// XML sends an XML response with status code.
|
||||||
XML(int, interface{}) error
|
XML(int, interface{}) error
|
||||||
|
|
||||||
|
// XMLBlob sends a XML blob response with status code.
|
||||||
XMLBlob(int, []byte) error
|
XMLBlob(int, []byte) error
|
||||||
|
|
||||||
|
// File sends a response with the content of the file.
|
||||||
File(string) error
|
File(string) error
|
||||||
|
|
||||||
|
// Attachment sends a response from `io.Reader` as attachment, prompting client
|
||||||
|
// to save the file.
|
||||||
Attachment(io.Reader, string) error
|
Attachment(io.Reader, string) error
|
||||||
|
|
||||||
|
// NoContent sends a response with no body and a status code.
|
||||||
NoContent(int) error
|
NoContent(int) error
|
||||||
|
|
||||||
|
// Redirect redirects the request with status code.
|
||||||
Redirect(int, string) error
|
Redirect(int, string) error
|
||||||
|
|
||||||
|
// Error invokes the registered HTTP error handler. Generally used by middleware.
|
||||||
Error(err error)
|
Error(err error)
|
||||||
|
|
||||||
|
// Handler implements `Handler` interface.
|
||||||
Handle(Context) error
|
Handle(Context) error
|
||||||
|
|
||||||
|
// Logger returns the `Logger` instance.
|
||||||
Logger() *log.Logger
|
Logger() *log.Logger
|
||||||
|
|
||||||
|
// Echo returns the `Echo` instance.
|
||||||
Echo() *Echo
|
Echo() *Echo
|
||||||
|
|
||||||
|
// Object returns the `context` instance.
|
||||||
Object() *context
|
Object() *context
|
||||||
|
|
||||||
|
// Reset resets the context after request completes. It must be called along
|
||||||
|
// with `Echo#GetContext()` and `Echo#PutContext()`. See `Echo#ServeHTTP()`
|
||||||
|
Reset(engine.Request, engine.Response)
|
||||||
}
|
}
|
||||||
|
|
||||||
context struct {
|
context struct {
|
||||||
@ -118,22 +186,18 @@ func (c *context) Handle(ctx Context) error {
|
|||||||
return c.handler.Handle(ctx)
|
return c.handler.Handle(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request returns *http.Request.
|
|
||||||
func (c *context) Request() engine.Request {
|
func (c *context) Request() engine.Request {
|
||||||
return c.request
|
return c.request
|
||||||
}
|
}
|
||||||
|
|
||||||
// Response returns `engine.Response`.
|
|
||||||
func (c *context) Response() engine.Response {
|
func (c *context) Response() engine.Response {
|
||||||
return c.response
|
return c.response
|
||||||
}
|
}
|
||||||
|
|
||||||
// Path returns the registered path for the handler.
|
|
||||||
func (c *context) Path() string {
|
func (c *context) Path() string {
|
||||||
return c.path
|
return c.path
|
||||||
}
|
}
|
||||||
|
|
||||||
// P returns path parameter by index.
|
|
||||||
func (c *context) P(i int) (value string) {
|
func (c *context) P(i int) (value string) {
|
||||||
l := len(c.pnames)
|
l := len(c.pnames)
|
||||||
if i < l {
|
if i < l {
|
||||||
@ -142,7 +206,6 @@ func (c *context) P(i int) (value string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Param returns path parameter by name.
|
|
||||||
func (c *context) Param(name string) (value string) {
|
func (c *context) Param(name string) (value string) {
|
||||||
l := len(c.pnames)
|
l := len(c.pnames)
|
||||||
for i, n := range c.pnames {
|
for i, n := range c.pnames {
|
||||||
@ -154,22 +217,18 @@ func (c *context) Param(name string) (value string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParamNames returns path parameter names.
|
|
||||||
func (c *context) ParamNames() []string {
|
func (c *context) ParamNames() []string {
|
||||||
return c.pnames
|
return c.pnames
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query returns query parameter by name.
|
|
||||||
func (c *context) Query(name string) string {
|
func (c *context) Query(name string) string {
|
||||||
return c.request.URL().QueryValue(name)
|
return c.request.URL().QueryValue(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Form returns form parameter by name.
|
|
||||||
func (c *context) Form(name string) string {
|
func (c *context) Form(name string) string {
|
||||||
return c.request.FormValue(name)
|
return c.request.FormValue(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set saves data in the context.
|
|
||||||
func (c *context) Set(key string, val interface{}) {
|
func (c *context) Set(key string, val interface{}) {
|
||||||
if c.store == nil {
|
if c.store == nil {
|
||||||
c.store = make(store)
|
c.store = make(store)
|
||||||
@ -177,19 +236,14 @@ func (c *context) Set(key string, val interface{}) {
|
|||||||
c.store[key] = val
|
c.store[key] = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get retrieves data from the context.
|
|
||||||
func (c *context) Get(key string) interface{} {
|
func (c *context) Get(key string) interface{} {
|
||||||
return c.store[key]
|
return c.store[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind binds the request body into provided type `i`. The default binder does
|
|
||||||
// it based on Content-Type header.
|
|
||||||
func (c *context) Bind(i interface{}) error {
|
func (c *context) Bind(i interface{}) error {
|
||||||
return c.echo.binder.Bind(i, c)
|
return c.echo.binder.Bind(i, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render renders a template with data and sends a text/html response with status
|
|
||||||
// code. Templates can be registered using `Echo.SetRenderer()`.
|
|
||||||
func (c *context) Render(code int, name string, data interface{}) (err error) {
|
func (c *context) Render(code int, name string, data interface{}) (err error) {
|
||||||
if c.echo.renderer == nil {
|
if c.echo.renderer == nil {
|
||||||
return ErrRendererNotRegistered
|
return ErrRendererNotRegistered
|
||||||
@ -204,7 +258,6 @@ func (c *context) Render(code int, name string, data interface{}) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTML sends an HTTP response with status code.
|
|
||||||
func (c *context) HTML(code int, html string) (err error) {
|
func (c *context) HTML(code int, html string) (err error) {
|
||||||
c.response.Header().Set(ContentType, TextHTMLCharsetUTF8)
|
c.response.Header().Set(ContentType, TextHTMLCharsetUTF8)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
@ -212,7 +265,6 @@ func (c *context) HTML(code int, html string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// String sends a string response with status code.
|
|
||||||
func (c *context) String(code int, s string) (err error) {
|
func (c *context) String(code int, s string) (err error) {
|
||||||
c.response.Header().Set(ContentType, TextPlainCharsetUTF8)
|
c.response.Header().Set(ContentType, TextPlainCharsetUTF8)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
@ -220,7 +272,6 @@ func (c *context) String(code int, s string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON sends a JSON response with status code.
|
|
||||||
func (c *context) JSON(code int, i interface{}) (err error) {
|
func (c *context) JSON(code int, i interface{}) (err error) {
|
||||||
b, err := json.Marshal(i)
|
b, err := json.Marshal(i)
|
||||||
if c.echo.Debug() {
|
if c.echo.Debug() {
|
||||||
@ -232,7 +283,6 @@ func (c *context) JSON(code int, i interface{}) (err error) {
|
|||||||
return c.JSONBlob(code, b)
|
return c.JSONBlob(code, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONBlob sends a JSON blob response with status code.
|
|
||||||
func (c *context) JSONBlob(code int, b []byte) (err error) {
|
func (c *context) JSONBlob(code int, b []byte) (err error) {
|
||||||
c.response.Header().Set(ContentType, ApplicationJSONCharsetUTF8)
|
c.response.Header().Set(ContentType, ApplicationJSONCharsetUTF8)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
@ -240,8 +290,6 @@ func (c *context) JSONBlob(code int, b []byte) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONP sends a JSONP response with status code. It uses `callback` to construct
|
|
||||||
// the JSONP payload.
|
|
||||||
func (c *context) JSONP(code int, callback string, i interface{}) (err error) {
|
func (c *context) JSONP(code int, callback string, i interface{}) (err error) {
|
||||||
b, err := json.Marshal(i)
|
b, err := json.Marshal(i)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -259,7 +307,6 @@ func (c *context) JSONP(code int, callback string, i interface{}) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// XML sends an XML response with status code.
|
|
||||||
func (c *context) XML(code int, i interface{}) (err error) {
|
func (c *context) XML(code int, i interface{}) (err error) {
|
||||||
b, err := xml.Marshal(i)
|
b, err := xml.Marshal(i)
|
||||||
if c.echo.Debug() {
|
if c.echo.Debug() {
|
||||||
@ -271,7 +318,6 @@ func (c *context) XML(code int, i interface{}) (err error) {
|
|||||||
return c.XMLBlob(code, b)
|
return c.XMLBlob(code, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// XMLBlob sends a XML blob response with status code.
|
|
||||||
func (c *context) XMLBlob(code int, b []byte) (err error) {
|
func (c *context) XMLBlob(code int, b []byte) (err error) {
|
||||||
c.response.Header().Set(ContentType, ApplicationXMLCharsetUTF8)
|
c.response.Header().Set(ContentType, ApplicationXMLCharsetUTF8)
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
@ -282,7 +328,6 @@ func (c *context) XMLBlob(code int, b []byte) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// File sends a response with the content of the file.
|
|
||||||
func (c *context) File(file string) error {
|
func (c *context) File(file string) error {
|
||||||
root, file := filepath.Split(file)
|
root, file := filepath.Split(file)
|
||||||
fs := http.Dir(root)
|
fs := http.Dir(root)
|
||||||
@ -305,8 +350,6 @@ func (c *context) File(file string) error {
|
|||||||
return ServeContent(c.Request(), c.Response(), f, fi)
|
return ServeContent(c.Request(), c.Response(), f, fi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attachment sends a response from `io.Reader` as attachment, prompting client
|
|
||||||
// to save the file.
|
|
||||||
func (c *context) Attachment(r io.Reader, name string) (err error) {
|
func (c *context) Attachment(r io.Reader, name string) (err error) {
|
||||||
c.response.Header().Set(ContentType, detectContentType(name))
|
c.response.Header().Set(ContentType, detectContentType(name))
|
||||||
c.response.Header().Set(ContentDisposition, "attachment; filename="+name)
|
c.response.Header().Set(ContentDisposition, "attachment; filename="+name)
|
||||||
@ -315,13 +358,11 @@ func (c *context) Attachment(r io.Reader, name string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoContent sends a response with no body and a status code.
|
|
||||||
func (c *context) NoContent(code int) error {
|
func (c *context) NoContent(code int) error {
|
||||||
c.response.WriteHeader(code)
|
c.response.WriteHeader(code)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect redirects the request with status code.
|
|
||||||
func (c *context) Redirect(code int, url string) error {
|
func (c *context) Redirect(code int, url string) error {
|
||||||
if code < http.StatusMultipleChoices || code > http.StatusTemporaryRedirect {
|
if code < http.StatusMultipleChoices || code > http.StatusTemporaryRedirect {
|
||||||
return ErrInvalidRedirectCode
|
return ErrInvalidRedirectCode
|
||||||
@ -331,26 +372,24 @@ func (c *context) Redirect(code int, url string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error invokes the registered HTTP error handler. Generally used by middleware.
|
|
||||||
func (c *context) Error(err error) {
|
func (c *context) Error(err error) {
|
||||||
c.echo.httpErrorHandler(err, c)
|
c.echo.httpErrorHandler(err, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Echo returns the `Echo` instance.
|
|
||||||
func (c *context) Echo() *Echo {
|
func (c *context) Echo() *Echo {
|
||||||
return c.echo
|
return c.echo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logger returns the `Logger` instance.
|
|
||||||
func (c *context) Logger() *log.Logger {
|
func (c *context) Logger() *log.Logger {
|
||||||
return c.echo.logger
|
return c.echo.logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object returns the `context` object.
|
|
||||||
func (c *context) Object() *context {
|
func (c *context) Object() *context {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServeContent sends a response from `io.Reader`. It automatically sets the `Content-Type`
|
||||||
|
// and `Last-Modified` headers.
|
||||||
func ServeContent(req engine.Request, res engine.Response, f http.File, fi os.FileInfo) error {
|
func ServeContent(req engine.Request, res engine.Response, f http.File, fi os.FileInfo) error {
|
||||||
res.Header().Set(ContentType, detectContentType(fi.Name()))
|
res.Header().Set(ContentType, detectContentType(fi.Name()))
|
||||||
res.Header().Set(LastModified, fi.ModTime().UTC().Format(http.TimeFormat))
|
res.Header().Set(LastModified, fi.ModTime().UTC().Format(http.TimeFormat))
|
||||||
@ -366,7 +405,7 @@ func detectContentType(name string) (t string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) reset(req engine.Request, res engine.Response) {
|
func (c *context) Reset(req engine.Request, res engine.Response) {
|
||||||
c.netContext = nil
|
c.netContext = nil
|
||||||
c.request = req
|
c.request = req
|
||||||
c.response = res
|
c.response = res
|
||||||
|
@ -191,8 +191,8 @@ func TestContext(t *testing.T) {
|
|||||||
c.Error(errors.New("error"))
|
c.Error(errors.New("error"))
|
||||||
assert.Equal(t, http.StatusInternalServerError, rec.Status())
|
assert.Equal(t, http.StatusInternalServerError, rec.Status())
|
||||||
|
|
||||||
// reset
|
// Reset
|
||||||
c.Object().reset(req, test.NewResponseRecorder())
|
c.Object().Reset(req, test.NewResponseRecorder())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContextPath(t *testing.T) {
|
func TestContextPath(t *testing.T) {
|
||||||
|
179
echo.go
179
echo.go
@ -1,3 +1,42 @@
|
|||||||
|
/*
|
||||||
|
Package echo implements a fast and unfancy micro web framework for Go.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/labstack/echo"
|
||||||
|
"github.com/labstack/echo/engine/standard"
|
||||||
|
"github.com/labstack/echo/middleware"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Handler
|
||||||
|
func hello() echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
return c.String(http.StatusOK, "Hello, World!\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Echo instance
|
||||||
|
e := echo.New()
|
||||||
|
|
||||||
|
// Middleware
|
||||||
|
e.Use(middleware.Logger())
|
||||||
|
e.Use(middleware.Recover())
|
||||||
|
|
||||||
|
// Routes
|
||||||
|
e.Get("/", hello())
|
||||||
|
|
||||||
|
// Start server
|
||||||
|
e.Run(standard.New(":1323"))
|
||||||
|
}
|
||||||
|
|
||||||
|
Learn more at https://labstack.com/echo
|
||||||
|
*/
|
||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -20,6 +59,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
// Echo is the top-level framework instance.
|
||||||
Echo struct {
|
Echo struct {
|
||||||
prefix string
|
prefix string
|
||||||
middleware []Middleware
|
middleware []Middleware
|
||||||
@ -36,33 +76,43 @@ type (
|
|||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Route contains a handler and information for matching against requests.
|
||||||
Route struct {
|
Route struct {
|
||||||
Method string
|
Method string
|
||||||
Path string
|
Path string
|
||||||
Handler string
|
Handler string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTTPError represents an error that occured while handling a request.
|
||||||
HTTPError struct {
|
HTTPError struct {
|
||||||
Code int
|
Code int
|
||||||
Message string
|
Message string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Middleware defines an interface for middleware via `Handle(Handler) Handler`
|
||||||
|
// function.
|
||||||
Middleware interface {
|
Middleware interface {
|
||||||
Handle(Handler) Handler
|
Handle(Handler) Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MiddlewareFunc is an adapter to allow the use of `func(Handler) Handler` as
|
||||||
|
// middleware.
|
||||||
MiddlewareFunc func(Handler) Handler
|
MiddlewareFunc func(Handler) Handler
|
||||||
|
|
||||||
|
// Handler defines an interface to server HTTP requests via `Handle(Context)`
|
||||||
|
// function.
|
||||||
Handler interface {
|
Handler interface {
|
||||||
Handle(Context) error
|
Handle(Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandlerFunc is an adapter to allow the use of `func(Context)` as an HTTP
|
||||||
|
// handler.
|
||||||
HandlerFunc func(Context) error
|
HandlerFunc func(Context) error
|
||||||
|
|
||||||
// HTTPErrorHandler is a centralized HTTP error handler.
|
// HTTPErrorHandler is a centralized HTTP error handler.
|
||||||
HTTPErrorHandler func(error, Context)
|
HTTPErrorHandler func(error, Context)
|
||||||
|
|
||||||
// Binder is the interface that wraps the Bind method.
|
// Binder is the interface that wraps the Bind function.
|
||||||
Binder interface {
|
Binder interface {
|
||||||
Bind(interface{}, Context) error
|
Bind(interface{}, Context) error
|
||||||
}
|
}
|
||||||
@ -70,41 +120,36 @@ type (
|
|||||||
binder struct {
|
binder struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validator is the interface that wraps the Validate method.
|
// Validator is the interface that wraps the Validate function.
|
||||||
Validator interface {
|
Validator interface {
|
||||||
Validate() error
|
Validate() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renderer is the interface that wraps the Render method.
|
// Renderer is the interface that wraps the Render function.
|
||||||
Renderer interface {
|
Renderer interface {
|
||||||
Render(io.Writer, string, interface{}, Context) error
|
Render(io.Writer, string, interface{}, Context) error
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//--------------
|
||||||
|
// HTTP methods
|
||||||
|
//--------------
|
||||||
const (
|
const (
|
||||||
// CONNECT HTTP method
|
|
||||||
CONNECT = "CONNECT"
|
CONNECT = "CONNECT"
|
||||||
// DELETE HTTP method
|
DELETE = "DELETE"
|
||||||
DELETE = "DELETE"
|
GET = "GET"
|
||||||
// GET HTTP method
|
HEAD = "HEAD"
|
||||||
GET = "GET"
|
|
||||||
// HEAD HTTP method
|
|
||||||
HEAD = "HEAD"
|
|
||||||
// OPTIONS HTTP method
|
|
||||||
OPTIONS = "OPTIONS"
|
OPTIONS = "OPTIONS"
|
||||||
// PATCH HTTP method
|
PATCH = "PATCH"
|
||||||
PATCH = "PATCH"
|
POST = "POST"
|
||||||
// POST HTTP method
|
PUT = "PUT"
|
||||||
POST = "POST"
|
TRACE = "TRACE"
|
||||||
// PUT HTTP method
|
)
|
||||||
PUT = "PUT"
|
|
||||||
// TRACE HTTP method
|
|
||||||
TRACE = "TRACE"
|
|
||||||
|
|
||||||
//-------------
|
|
||||||
// Media types
|
|
||||||
//-------------
|
|
||||||
|
|
||||||
|
//-------------
|
||||||
|
// Media types
|
||||||
|
//-------------
|
||||||
|
const (
|
||||||
ApplicationJSON = "application/json"
|
ApplicationJSON = "application/json"
|
||||||
ApplicationJSONCharsetUTF8 = ApplicationJSON + "; " + CharsetUTF8
|
ApplicationJSONCharsetUTF8 = ApplicationJSON + "; " + CharsetUTF8
|
||||||
ApplicationJavaScript = "application/javascript"
|
ApplicationJavaScript = "application/javascript"
|
||||||
@ -120,17 +165,19 @@ const (
|
|||||||
TextPlainCharsetUTF8 = TextPlain + "; " + CharsetUTF8
|
TextPlainCharsetUTF8 = TextPlain + "; " + CharsetUTF8
|
||||||
MultipartForm = "multipart/form-data"
|
MultipartForm = "multipart/form-data"
|
||||||
OctetStream = "application/octet-stream"
|
OctetStream = "application/octet-stream"
|
||||||
|
)
|
||||||
|
|
||||||
//---------
|
//---------
|
||||||
// Charset
|
// Charset
|
||||||
//---------
|
//---------
|
||||||
|
const (
|
||||||
CharsetUTF8 = "charset=utf-8"
|
CharsetUTF8 = "charset=utf-8"
|
||||||
|
)
|
||||||
|
|
||||||
//---------
|
//---------
|
||||||
// Headers
|
// Headers
|
||||||
//---------
|
//---------
|
||||||
|
const (
|
||||||
AcceptEncoding = "Accept-Encoding"
|
AcceptEncoding = "Accept-Encoding"
|
||||||
Authorization = "Authorization"
|
Authorization = "Authorization"
|
||||||
ContentDisposition = "Content-Disposition"
|
ContentDisposition = "Content-Disposition"
|
||||||
@ -158,22 +205,24 @@ var (
|
|||||||
PUT,
|
PUT,
|
||||||
TRACE,
|
TRACE,
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
//--------
|
//--------
|
||||||
// Errors
|
// Errors
|
||||||
//--------
|
//--------
|
||||||
|
var (
|
||||||
ErrUnsupportedMediaType = NewHTTPError(http.StatusUnsupportedMediaType)
|
ErrUnsupportedMediaType = NewHTTPError(http.StatusUnsupportedMediaType)
|
||||||
ErrNotFound = NewHTTPError(http.StatusNotFound)
|
ErrNotFound = NewHTTPError(http.StatusNotFound)
|
||||||
ErrUnauthorized = NewHTTPError(http.StatusUnauthorized)
|
ErrUnauthorized = NewHTTPError(http.StatusUnauthorized)
|
||||||
ErrMethodNotAllowed = NewHTTPError(http.StatusMethodNotAllowed)
|
ErrMethodNotAllowed = NewHTTPError(http.StatusMethodNotAllowed)
|
||||||
ErrRendererNotRegistered = errors.New("renderer not registered")
|
ErrRendererNotRegistered = errors.New("renderer not registered")
|
||||||
ErrInvalidRedirectCode = errors.New("invalid redirect status code")
|
ErrInvalidRedirectCode = errors.New("invalid redirect status code")
|
||||||
|
)
|
||||||
|
|
||||||
//----------------
|
//----------------
|
||||||
// Error handlers
|
// Error handlers
|
||||||
//----------------
|
//----------------
|
||||||
|
var (
|
||||||
notFoundHandler = HandlerFunc(func(c Context) error {
|
notFoundHandler = HandlerFunc(func(c Context) error {
|
||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
})
|
})
|
||||||
@ -206,12 +255,14 @@ func New() (e *Echo) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MiddlewareFunc) Handle(h Handler) Handler {
|
// Handle chains middleware.
|
||||||
return m(h)
|
func (f MiddlewareFunc) Handle(h Handler) Handler {
|
||||||
|
return f(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h HandlerFunc) Handle(c Context) error {
|
// Handle serves HTTP request.
|
||||||
return h(c)
|
func (f HandlerFunc) Handle(c Context) error {
|
||||||
|
return f(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Router returns router.
|
// Router returns router.
|
||||||
@ -261,12 +312,12 @@ func (e *Echo) SetHTTPErrorHandler(h HTTPErrorHandler) {
|
|||||||
e.httpErrorHandler = h
|
e.httpErrorHandler = h
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBinder registers a custom binder. It's invoked by Context.Bind().
|
// SetBinder registers a custom binder. It's invoked by `Context#Bind()`.
|
||||||
func (e *Echo) SetBinder(b Binder) {
|
func (e *Echo) SetBinder(b Binder) {
|
||||||
e.binder = b
|
e.binder = b
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRenderer registers an HTML template renderer. It's invoked by Context.Render().
|
// SetRenderer registers an HTML template renderer. It's invoked by `Context#Render()`.
|
||||||
func (e *Echo) SetRenderer(r Renderer) {
|
func (e *Echo) SetRenderer(r Renderer) {
|
||||||
e.renderer = r
|
e.renderer = r
|
||||||
}
|
}
|
||||||
@ -301,59 +352,70 @@ func (e *Echo) chainMiddleware() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect adds a CONNECT route > handler to the router.
|
// Connect registers a new CONNECT route for a path with matching handler in the
|
||||||
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Connect(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Connect(path string, h Handler, m ...Middleware) {
|
||||||
e.add(CONNECT, path, h, m...)
|
e.add(CONNECT, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete adds a DELETE route > handler to the router.
|
// Delete registers a new DELETE route for a path with matching handler in the router
|
||||||
|
// with optional route-level middleware.
|
||||||
func (e *Echo) Delete(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Delete(path string, h Handler, m ...Middleware) {
|
||||||
e.add(DELETE, path, h, m...)
|
e.add(DELETE, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get adds a GET route > handler to the router.
|
// Get registers a new GET route for a path with matching handler in the router
|
||||||
|
// with optional route-level middleware.
|
||||||
func (e *Echo) Get(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Get(path string, h Handler, m ...Middleware) {
|
||||||
e.add(GET, path, h, m...)
|
e.add(GET, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Head adds a HEAD route > handler to the router.
|
// Head registers a new HEAD route for a path with matching handler in the
|
||||||
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Head(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Head(path string, h Handler, m ...Middleware) {
|
||||||
e.add(HEAD, path, h, m...)
|
e.add(HEAD, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options adds an OPTIONS route > handler to the router.
|
// Options registers a new OPTIONS route for a path with matching handler in the
|
||||||
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Options(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Options(path string, h Handler, m ...Middleware) {
|
||||||
e.add(OPTIONS, path, h, m...)
|
e.add(OPTIONS, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch adds a PATCH route > handler to the router.
|
// Patch registers a new PATCH route for a path with matching handler in the
|
||||||
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Patch(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Patch(path string, h Handler, m ...Middleware) {
|
||||||
e.add(PATCH, path, h, m...)
|
e.add(PATCH, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post adds a POST route > handler to the router.
|
// Post registers a new POST route for a path with matching handler in the
|
||||||
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Post(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Post(path string, h Handler, m ...Middleware) {
|
||||||
e.add(POST, path, h, m...)
|
e.add(POST, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put adds a PUT route > handler to the router.
|
// Put registers a new PUT route for a path with matching handler in the
|
||||||
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Put(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Put(path string, h Handler, m ...Middleware) {
|
||||||
e.add(PUT, path, h, m...)
|
e.add(PUT, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trace adds a TRACE route > handler to the router.
|
// Trace registers a new TRACE route for a path with matching handler in the
|
||||||
|
// router with optional route-level middleware.
|
||||||
func (e *Echo) Trace(path string, h Handler, m ...Middleware) {
|
func (e *Echo) Trace(path string, h Handler, m ...Middleware) {
|
||||||
e.add(TRACE, path, h, m...)
|
e.add(TRACE, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any adds a route > handler to the router for all HTTP methods.
|
// Any registers a new route for all HTTP methods and path with matching handler
|
||||||
|
// in the router with optional route-level middleware.
|
||||||
func (e *Echo) Any(path string, handler Handler, middleware ...Middleware) {
|
func (e *Echo) Any(path string, handler Handler, middleware ...Middleware) {
|
||||||
for _, m := range methods {
|
for _, m := range methods {
|
||||||
e.add(m, path, handler, middleware...)
|
e.add(m, path, handler, middleware...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match adds a route > handler to the router for multiple HTTP methods provided.
|
// Match registers a new route for multiple HTTP methods and path with matching
|
||||||
|
// handler in the router with optional route-level middleware.
|
||||||
func (e *Echo) Match(methods []string, path string, handler Handler, middleware ...Middleware) {
|
func (e *Echo) Match(methods []string, path string, handler Handler, middleware ...Middleware) {
|
||||||
for _, m := range methods {
|
for _, m := range methods {
|
||||||
e.add(m, path, handler, middleware...)
|
e.add(m, path, handler, middleware...)
|
||||||
@ -392,7 +454,7 @@ func (e *Echo) add(method, path string, handler Handler, middleware ...Middlewar
|
|||||||
e.router.routes = append(e.router.routes, r)
|
e.router.routes = append(e.router.routes, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group creates a new router group with prefix.
|
// Group creates a new router group with prefix and optional group-level middleware.
|
||||||
func (e *Echo) Group(prefix string, m ...Middleware) (g *Group) {
|
func (e *Echo) Group(prefix string, m ...Middleware) (g *Group) {
|
||||||
g = &Group{prefix: prefix, echo: e}
|
g = &Group{prefix: prefix, echo: e}
|
||||||
g.Use(m...)
|
g.Use(m...)
|
||||||
@ -448,7 +510,7 @@ func (e *Echo) PutContext(c Context) {
|
|||||||
|
|
||||||
func (e *Echo) ServeHTTP(req engine.Request, res engine.Response) {
|
func (e *Echo) ServeHTTP(req engine.Request, res engine.Response) {
|
||||||
c := e.pool.Get().(*context)
|
c := e.pool.Get().(*context)
|
||||||
c.reset(req, res)
|
c.Reset(req, res)
|
||||||
|
|
||||||
// Execute chain
|
// Execute chain
|
||||||
if err := e.head.Handle(c); err != nil {
|
if err := e.head.Handle(c); err != nil {
|
||||||
@ -465,6 +527,7 @@ func (e *Echo) Run(s engine.Server) error {
|
|||||||
return s.Start()
|
return s.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewHTTPError creates a new HTTPError instance.
|
||||||
func NewHTTPError(code int, msg ...string) *HTTPError {
|
func NewHTTPError(code int, msg ...string) *HTTPError {
|
||||||
he := &HTTPError{Code: code, Message: http.StatusText(code)}
|
he := &HTTPError{Code: code, Message: http.StatusText(code)}
|
||||||
if len(msg) > 0 {
|
if len(msg) > 0 {
|
||||||
|
@ -54,7 +54,7 @@ type (
|
|||||||
// RemoteAddress returns the client's network address.
|
// RemoteAddress returns the client's network address.
|
||||||
RemoteAddress() string
|
RemoteAddress() string
|
||||||
|
|
||||||
// Method returns the request's HTTP method.
|
// Method returns the request's HTTP function.
|
||||||
Method() string
|
Method() string
|
||||||
|
|
||||||
// SetMethod sets the HTTP method of the request.
|
// SetMethod sets the HTTP method of the request.
|
||||||
@ -136,7 +136,7 @@ type (
|
|||||||
QueryString() string
|
QueryString() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config defines engine configuration.
|
// Config defines engine config.
|
||||||
Config struct {
|
Config struct {
|
||||||
Address string // TCP address to listen on.
|
Address string // TCP address to listen on.
|
||||||
Listener net.Listener // Custom `net.Listener`. If set, server accepts connections on it.
|
Listener net.Listener // Custom `net.Listener`. If set, server accepts connections on it.
|
||||||
@ -152,7 +152,8 @@ type (
|
|||||||
ServeHTTP(Request, Response)
|
ServeHTTP(Request, Response)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandlerFunc is an adapter to allow the use of `func(Request, Response)` as HTTP handlers.
|
// HandlerFunc is an adapter to allow the use of `func(Request, Response)` as
|
||||||
|
// an HTTP handler.
|
||||||
HandlerFunc func(Request, Response)
|
HandlerFunc func(Request, Response)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,27 +16,27 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Add implements `engine.Header#Add` method.
|
// Add implements `engine.Header#Add` function.
|
||||||
func (h *RequestHeader) Add(key, val string) {
|
func (h *RequestHeader) Add(key, val string) {
|
||||||
// h.RequestHeader.Add(key, val)
|
// h.RequestHeader.Add(key, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Del implements `engine.Header#Del` method.
|
// Del implements `engine.Header#Del` function.
|
||||||
func (h *RequestHeader) Del(key string) {
|
func (h *RequestHeader) Del(key string) {
|
||||||
h.RequestHeader.Del(key)
|
h.RequestHeader.Del(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set implements `engine.Header#Set` method.
|
// Set implements `engine.Header#Set` function.
|
||||||
func (h *RequestHeader) Set(key, val string) {
|
func (h *RequestHeader) Set(key, val string) {
|
||||||
h.RequestHeader.Set(key, val)
|
h.RequestHeader.Set(key, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get implements `engine.Header#Get` method.
|
// Get implements `engine.Header#Get` function.
|
||||||
func (h *RequestHeader) Get(key string) string {
|
func (h *RequestHeader) Get(key string) string {
|
||||||
return string(h.Peek(key))
|
return string(h.Peek(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keys implements `engine.Header#Keys` method.
|
// Keys implements `engine.Header#Keys` function.
|
||||||
func (h *RequestHeader) Keys() (keys []string) {
|
func (h *RequestHeader) Keys() (keys []string) {
|
||||||
keys = make([]string, h.Len())
|
keys = make([]string, h.Len())
|
||||||
i := 0
|
i := 0
|
||||||
@ -51,28 +51,28 @@ func (h *RequestHeader) reset(hdr *fasthttp.RequestHeader) {
|
|||||||
h.RequestHeader = hdr
|
h.RequestHeader = hdr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add implements `engine.Header#Add` method.
|
// Add implements `engine.Header#Add` function.
|
||||||
func (h *ResponseHeader) Add(key, val string) {
|
func (h *ResponseHeader) Add(key, val string) {
|
||||||
// TODO: https://github.com/valyala/fasthttp/issues/69
|
// TODO: https://github.com/valyala/fasthttp/issues/69
|
||||||
// h.header.Add(key, val)
|
// h.header.Add(key, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Del implements `engine.Header#Del` method.
|
// Del implements `engine.Header#Del` function.
|
||||||
func (h *ResponseHeader) Del(key string) {
|
func (h *ResponseHeader) Del(key string) {
|
||||||
h.ResponseHeader.Del(key)
|
h.ResponseHeader.Del(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get implements `engine.Header#Get` method.
|
// Get implements `engine.Header#Get` function.
|
||||||
func (h *ResponseHeader) Get(key string) string {
|
func (h *ResponseHeader) Get(key string) string {
|
||||||
return string(h.Peek(key))
|
return string(h.Peek(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set implements `engine.Header#Set` method.
|
// Set implements `engine.Header#Set` function.
|
||||||
func (h *ResponseHeader) Set(key, val string) {
|
func (h *ResponseHeader) Set(key, val string) {
|
||||||
h.ResponseHeader.Set(key, val)
|
h.ResponseHeader.Set(key, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keys implements `engine.Header#Keys` method.
|
// Keys implements `engine.Header#Keys` function.
|
||||||
func (h *ResponseHeader) Keys() (keys []string) {
|
func (h *ResponseHeader) Keys() (keys []string) {
|
||||||
keys = make([]string, h.Len())
|
keys = make([]string, h.Len())
|
||||||
i := 0
|
i := 0
|
||||||
|
@ -22,72 +22,72 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// TLS implements `engine.Request#TLS` method.
|
// TLS implements `engine.Request#TLS` function.
|
||||||
func (r *Request) TLS() bool {
|
func (r *Request) TLS() bool {
|
||||||
return r.IsTLS()
|
return r.IsTLS()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scheme implements `engine.Request#Scheme` method.
|
// Scheme implements `engine.Request#Scheme` function.
|
||||||
func (r *Request) Scheme() string {
|
func (r *Request) Scheme() string {
|
||||||
return string(r.RequestCtx.URI().Scheme())
|
return string(r.RequestCtx.URI().Scheme())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Host implements `engine.Request#Host` method.
|
// Host implements `engine.Request#Host` function.
|
||||||
func (r *Request) Host() string {
|
func (r *Request) Host() string {
|
||||||
return string(r.RequestCtx.Host())
|
return string(r.RequestCtx.Host())
|
||||||
}
|
}
|
||||||
|
|
||||||
// URL implements `engine.Request#URL` method.
|
// URL implements `engine.Request#URL` function.
|
||||||
func (r *Request) URL() engine.URL {
|
func (r *Request) URL() engine.URL {
|
||||||
return r.url
|
return r.url
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header implements `engine.Request#Header` method.
|
// Header implements `engine.Request#Header` function.
|
||||||
func (r *Request) Header() engine.Header {
|
func (r *Request) Header() engine.Header {
|
||||||
return r.header
|
return r.header
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserAgent implements `engine.Request#UserAgent` method.
|
// UserAgent implements `engine.Request#UserAgent` function.
|
||||||
func (r *Request) UserAgent() string {
|
func (r *Request) UserAgent() string {
|
||||||
return string(r.RequestCtx.UserAgent())
|
return string(r.RequestCtx.UserAgent())
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteAddress implements `engine.Request#RemoteAddress` method.
|
// RemoteAddress implements `engine.Request#RemoteAddress` function.
|
||||||
func (r *Request) RemoteAddress() string {
|
func (r *Request) RemoteAddress() string {
|
||||||
return r.RemoteAddr().String()
|
return r.RemoteAddr().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method implements `engine.Request#Method` method.
|
// Method implements `engine.Request#Method` function.
|
||||||
func (r *Request) Method() string {
|
func (r *Request) Method() string {
|
||||||
return string(r.RequestCtx.Method())
|
return string(r.RequestCtx.Method())
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMethod implements `engine.Request#SetMethod` method.
|
// SetMethod implements `engine.Request#SetMethod` function.
|
||||||
func (r *Request) SetMethod(method string) {
|
func (r *Request) SetMethod(method string) {
|
||||||
r.Request.Header.SetMethod(method)
|
r.Request.Header.SetMethod(method)
|
||||||
}
|
}
|
||||||
|
|
||||||
// URI implements `engine.Request#URI` method.
|
// URI implements `engine.Request#URI` function.
|
||||||
func (r *Request) URI() string {
|
func (r *Request) URI() string {
|
||||||
return string(r.RequestURI())
|
return string(r.RequestURI())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Body implements `engine.Request#Body` method.
|
// Body implements `engine.Request#Body` function.
|
||||||
func (r *Request) Body() io.Reader {
|
func (r *Request) Body() io.Reader {
|
||||||
return bytes.NewBuffer(r.PostBody())
|
return bytes.NewBuffer(r.PostBody())
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormValue implements `engine.Request#FormValue` method.
|
// FormValue implements `engine.Request#FormValue` function.
|
||||||
func (r *Request) FormValue(name string) string {
|
func (r *Request) FormValue(name string) string {
|
||||||
return string(r.RequestCtx.FormValue(name))
|
return string(r.RequestCtx.FormValue(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormFile implements `engine.Request#FormFile` method.
|
// FormFile implements `engine.Request#FormFile` function.
|
||||||
func (r *Request) FormFile(name string) (*multipart.FileHeader, error) {
|
func (r *Request) FormFile(name string) (*multipart.FileHeader, error) {
|
||||||
return r.RequestCtx.FormFile(name)
|
return r.RequestCtx.FormFile(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MultipartForm implements `engine.Request#MultipartForm` method.
|
// MultipartForm implements `engine.Request#MultipartForm` function.
|
||||||
func (r *Request) MultipartForm() (*multipart.Form, error) {
|
func (r *Request) MultipartForm() (*multipart.Form, error) {
|
||||||
return r.RequestCtx.MultipartForm()
|
return r.RequestCtx.MultipartForm()
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,12 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Header implements `engine.Response#Header` method.
|
// Header implements `engine.Response#Header` function.
|
||||||
func (r *Response) Header() engine.Header {
|
func (r *Response) Header() engine.Header {
|
||||||
return r.header
|
return r.header
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteHeader implements `engine.Response#WriteHeader` method.
|
// WriteHeader implements `engine.Response#WriteHeader` function.
|
||||||
func (r *Response) WriteHeader(code int) {
|
func (r *Response) WriteHeader(code int) {
|
||||||
if r.committed {
|
if r.committed {
|
||||||
r.logger.Warn("response already committed")
|
r.logger.Warn("response already committed")
|
||||||
@ -40,34 +40,34 @@ func (r *Response) WriteHeader(code int) {
|
|||||||
r.committed = true
|
r.committed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write implements `engine.Response#Write` method.
|
// Write implements `engine.Response#Write` function.
|
||||||
func (r *Response) Write(b []byte) (n int, err error) {
|
func (r *Response) Write(b []byte) (n int, err error) {
|
||||||
n, err = r.writer.Write(b)
|
n, err = r.writer.Write(b)
|
||||||
r.size += int64(n)
|
r.size += int64(n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status implements `engine.Response#Status` method.
|
// Status implements `engine.Response#Status` function.
|
||||||
func (r *Response) Status() int {
|
func (r *Response) Status() int {
|
||||||
return r.status
|
return r.status
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size implements `engine.Response#Size` method.
|
// Size implements `engine.Response#Size` function.
|
||||||
func (r *Response) Size() int64 {
|
func (r *Response) Size() int64 {
|
||||||
return r.size
|
return r.size
|
||||||
}
|
}
|
||||||
|
|
||||||
// Committed implements `engine.Response#Committed` method.
|
// Committed implements `engine.Response#Committed` function.
|
||||||
func (r *Response) Committed() bool {
|
func (r *Response) Committed() bool {
|
||||||
return r.committed
|
return r.committed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writer implements `engine.Response#Writer` method.
|
// Writer implements `engine.Response#Writer` function.
|
||||||
func (r *Response) Writer() io.Writer {
|
func (r *Response) Writer() io.Writer {
|
||||||
return r.writer
|
return r.writer
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetWriter implements `engine.Response#SetWriter` method.
|
// SetWriter implements `engine.Response#SetWriter` function.
|
||||||
func (r *Response) SetWriter(w io.Writer) {
|
func (r *Response) SetWriter(w io.Writer) {
|
||||||
r.writer = w
|
r.writer = w
|
||||||
}
|
}
|
||||||
|
@ -87,17 +87,17 @@ func NewFromConfig(c engine.Config) (s *Server) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHandler implements `engine.Server#SetHandler` method.
|
// SetHandler implements `engine.Server#SetHandler` function.
|
||||||
func (s *Server) SetHandler(h engine.Handler) {
|
func (s *Server) SetHandler(h engine.Handler) {
|
||||||
s.handler = h
|
s.handler = h
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLogger implements `engine.Server#SetLogger` method.
|
// SetLogger implements `engine.Server#SetLogger` function.
|
||||||
func (s *Server) SetLogger(l *log.Logger) {
|
func (s *Server) SetLogger(l *log.Logger) {
|
||||||
s.logger = l
|
s.logger = l
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start implements `engine.Server#Start` method.
|
// Start implements `engine.Server#Start` function.
|
||||||
func (s *Server) Start() error {
|
func (s *Server) Start() error {
|
||||||
if s.config.Listener == nil {
|
if s.config.Listener == nil {
|
||||||
return s.startDefaultListener()
|
return s.startDefaultListener()
|
||||||
|
@ -11,22 +11,22 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Path implements `engine.URL#Path` method.
|
// Path implements `engine.URL#Path` function.
|
||||||
func (u *URL) Path() string {
|
func (u *URL) Path() string {
|
||||||
return string(u.URI.Path())
|
return string(u.URI.Path())
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPath implements `engine.URL#SetPath` method.
|
// SetPath implements `engine.URL#SetPath` function.
|
||||||
func (u *URL) SetPath(path string) {
|
func (u *URL) SetPath(path string) {
|
||||||
u.URI.SetPath(path)
|
u.URI.SetPath(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryValue implements `engine.URL#QueryValue` method.
|
// QueryValue implements `engine.URL#QueryValue` function.
|
||||||
func (u *URL) QueryValue(name string) string {
|
func (u *URL) QueryValue(name string) string {
|
||||||
return string(u.QueryArgs().Peek(name))
|
return string(u.QueryArgs().Peek(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryString implements `engine.URL#QueryString` method.
|
// QueryString implements `engine.URL#QueryString` function.
|
||||||
func (u *URL) QueryString() string {
|
func (u *URL) QueryString() string {
|
||||||
return string(u.URI.QueryString())
|
return string(u.URI.QueryString())
|
||||||
}
|
}
|
||||||
|
@ -9,27 +9,27 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Add implements `engine.Header#Add` method.
|
// Add implements `engine.Header#Add` function.
|
||||||
func (h *Header) Add(key, val string) {
|
func (h *Header) Add(key, val string) {
|
||||||
h.Header.Add(key, val)
|
h.Header.Add(key, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Del implements `engine.Header#Del` method.
|
// Del implements `engine.Header#Del` function.
|
||||||
func (h *Header) Del(key string) {
|
func (h *Header) Del(key string) {
|
||||||
h.Header.Del(key)
|
h.Header.Del(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set implements `engine.Header#Set` method.
|
// Set implements `engine.Header#Set` function.
|
||||||
func (h *Header) Set(key, val string) {
|
func (h *Header) Set(key, val string) {
|
||||||
h.Header.Set(key, val)
|
h.Header.Set(key, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get implements `engine.Header#Get` method.
|
// Get implements `engine.Header#Get` function.
|
||||||
func (h *Header) Get(key string) string {
|
func (h *Header) Get(key string) string {
|
||||||
return h.Header.Get(key)
|
return h.Header.Get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keys implements `engine.Header#Keys` method.
|
// Keys implements `engine.Header#Keys` function.
|
||||||
func (h *Header) Keys() (keys []string) {
|
func (h *Header) Keys() (keys []string) {
|
||||||
keys = make([]string, len(h.Header))
|
keys = make([]string, len(h.Header))
|
||||||
i := 0
|
i := 0
|
||||||
|
@ -17,12 +17,12 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// TLS implements `engine.Request#TLS` method.
|
// TLS implements `engine.Request#TLS` function.
|
||||||
func (r *Request) TLS() bool {
|
func (r *Request) TLS() bool {
|
||||||
return r.Request.TLS != nil
|
return r.Request.TLS != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scheme implements `engine.Request#Scheme` method.
|
// Scheme implements `engine.Request#Scheme` function.
|
||||||
func (r *Request) Scheme() string {
|
func (r *Request) Scheme() string {
|
||||||
if r.TLS() {
|
if r.TLS() {
|
||||||
return "https"
|
return "https"
|
||||||
@ -30,17 +30,17 @@ func (r *Request) Scheme() string {
|
|||||||
return "http"
|
return "http"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Host implements `engine.Request#Host` method.
|
// Host implements `engine.Request#Host` function.
|
||||||
func (r *Request) Host() string {
|
func (r *Request) Host() string {
|
||||||
return r.Request.Host
|
return r.Request.Host
|
||||||
}
|
}
|
||||||
|
|
||||||
// URL implements `engine.Request#URL` method.
|
// URL implements `engine.Request#URL` function.
|
||||||
func (r *Request) URL() engine.URL {
|
func (r *Request) URL() engine.URL {
|
||||||
return r.url
|
return r.url
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header implements `engine.Request#URL` method.
|
// Header implements `engine.Request#URL` function.
|
||||||
func (r *Request) Header() engine.Header {
|
func (r *Request) Header() engine.Header {
|
||||||
return r.header
|
return r.header
|
||||||
}
|
}
|
||||||
@ -57,48 +57,48 @@ func (r *Request) Header() engine.Header {
|
|||||||
// return r.request.ProtoMinor()
|
// return r.request.ProtoMinor()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// UserAgent implements `engine.Request#UserAgent` method.
|
// UserAgent implements `engine.Request#UserAgent` function.
|
||||||
func (r *Request) UserAgent() string {
|
func (r *Request) UserAgent() string {
|
||||||
return r.Request.UserAgent()
|
return r.Request.UserAgent()
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteAddress implements `engine.Request#RemoteAddress` method.
|
// RemoteAddress implements `engine.Request#RemoteAddress` function.
|
||||||
func (r *Request) RemoteAddress() string {
|
func (r *Request) RemoteAddress() string {
|
||||||
return r.RemoteAddr
|
return r.RemoteAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method implements `engine.Request#Method` method.
|
// Method implements `engine.Request#Method` function.
|
||||||
func (r *Request) Method() string {
|
func (r *Request) Method() string {
|
||||||
return r.Request.Method
|
return r.Request.Method
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMethod implements `engine.Request#SetMethod` method.
|
// SetMethod implements `engine.Request#SetMethod` function.
|
||||||
func (r *Request) SetMethod(method string) {
|
func (r *Request) SetMethod(method string) {
|
||||||
r.Request.Method = method
|
r.Request.Method = method
|
||||||
}
|
}
|
||||||
|
|
||||||
// URI implements `engine.Request#URI` method.
|
// URI implements `engine.Request#URI` function.
|
||||||
func (r *Request) URI() string {
|
func (r *Request) URI() string {
|
||||||
return r.RequestURI
|
return r.RequestURI
|
||||||
}
|
}
|
||||||
|
|
||||||
// Body implements `engine.Request#Body` method.
|
// Body implements `engine.Request#Body` function.
|
||||||
func (r *Request) Body() io.Reader {
|
func (r *Request) Body() io.Reader {
|
||||||
return r.Request.Body
|
return r.Request.Body
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormValue implements `engine.Request#FormValue` method.
|
// FormValue implements `engine.Request#FormValue` function.
|
||||||
func (r *Request) FormValue(name string) string {
|
func (r *Request) FormValue(name string) string {
|
||||||
return r.Request.FormValue(name)
|
return r.Request.FormValue(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormFile implements `engine.Request#FormFile` method.
|
// FormFile implements `engine.Request#FormFile` function.
|
||||||
func (r *Request) FormFile(name string) (*multipart.FileHeader, error) {
|
func (r *Request) FormFile(name string) (*multipart.FileHeader, error) {
|
||||||
_, fh, err := r.Request.FormFile(name)
|
_, fh, err := r.Request.FormFile(name)
|
||||||
return fh, err
|
return fh, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// MultipartForm implements `engine.Request#MultipartForm` method.
|
// MultipartForm implements `engine.Request#MultipartForm` function.
|
||||||
func (r *Request) MultipartForm() (*multipart.Form, error) {
|
func (r *Request) MultipartForm() (*multipart.Form, error) {
|
||||||
err := r.Request.ParseMultipartForm(32 << 20) // 32 MB
|
err := r.Request.ParseMultipartForm(32 << 20) // 32 MB
|
||||||
return r.Request.MultipartForm, err
|
return r.Request.MultipartForm, err
|
||||||
|
@ -28,12 +28,12 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Header implements `engine.Response#Header` method.
|
// Header implements `engine.Response#Header` function.
|
||||||
func (r *Response) Header() engine.Header {
|
func (r *Response) Header() engine.Header {
|
||||||
return r.header
|
return r.header
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteHeader implements `engine.Response#WriteHeader` method.
|
// WriteHeader implements `engine.Response#WriteHeader` function.
|
||||||
func (r *Response) WriteHeader(code int) {
|
func (r *Response) WriteHeader(code int) {
|
||||||
if r.committed {
|
if r.committed {
|
||||||
r.logger.Warn("response already committed")
|
r.logger.Warn("response already committed")
|
||||||
@ -44,48 +44,48 @@ func (r *Response) WriteHeader(code int) {
|
|||||||
r.committed = true
|
r.committed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write implements `engine.Response#Write` method.
|
// Write implements `engine.Response#Write` function.
|
||||||
func (r *Response) Write(b []byte) (n int, err error) {
|
func (r *Response) Write(b []byte) (n int, err error) {
|
||||||
n, err = r.writer.Write(b)
|
n, err = r.writer.Write(b)
|
||||||
r.size += int64(n)
|
r.size += int64(n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status implements `engine.Response#Status` method.
|
// Status implements `engine.Response#Status` function.
|
||||||
func (r *Response) Status() int {
|
func (r *Response) Status() int {
|
||||||
return r.status
|
return r.status
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size implements `engine.Response#Size` method.
|
// Size implements `engine.Response#Size` function.
|
||||||
func (r *Response) Size() int64 {
|
func (r *Response) Size() int64 {
|
||||||
return r.size
|
return r.size
|
||||||
}
|
}
|
||||||
|
|
||||||
// Committed implements `engine.Response#Committed` method.
|
// Committed implements `engine.Response#Committed` function.
|
||||||
func (r *Response) Committed() bool {
|
func (r *Response) Committed() bool {
|
||||||
return r.committed
|
return r.committed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writer implements `engine.Response#Writer` method.
|
// Writer implements `engine.Response#Writer` function.
|
||||||
func (r *Response) Writer() io.Writer {
|
func (r *Response) Writer() io.Writer {
|
||||||
return r.writer
|
return r.writer
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetWriter implements `engine.Response#SetWriter` method.
|
// SetWriter implements `engine.Response#SetWriter` function.
|
||||||
func (r *Response) SetWriter(w io.Writer) {
|
func (r *Response) SetWriter(w io.Writer) {
|
||||||
r.writer = w
|
r.writer = w
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush implements the http.Flusher interface to allow an HTTP handler to flush
|
// Flush implements the http.Flusher interface to allow an HTTP handler to flush
|
||||||
// buffered data to the client.
|
// buffered data to the client.
|
||||||
// See [http.Flusher](https://golang.org/pkg/net/http/#Flusher)
|
// See https://golang.org/pkg/net/http/#Flusher
|
||||||
func (r *Response) Flush() {
|
func (r *Response) Flush() {
|
||||||
r.ResponseWriter.(http.Flusher).Flush()
|
r.ResponseWriter.(http.Flusher).Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hijack implements the http.Hijacker interface to allow an HTTP handler to
|
// Hijack implements the http.Hijacker interface to allow an HTTP handler to
|
||||||
// take over the connection.
|
// take over the connection.
|
||||||
// See [http.Hijacker](https://golang.org/pkg/net/http/#Hijacker)
|
// See https://golang.org/pkg/net/http/#Hijacker
|
||||||
func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||||
return r.ResponseWriter.(http.Hijacker).Hijack()
|
return r.ResponseWriter.(http.Hijacker).Hijack()
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
|||||||
// when the underlying connection has gone away.
|
// when the underlying connection has gone away.
|
||||||
// This mechanism can be used to cancel long operations on the server if the
|
// This mechanism can be used to cancel long operations on the server if the
|
||||||
// client has disconnected before the response is ready.
|
// client has disconnected before the response is ready.
|
||||||
// See [http.CloseNotifier](https://golang.org/pkg/net/http/#CloseNotifier)
|
// See https://golang.org/pkg/net/http/#CloseNotifier
|
||||||
func (r *Response) CloseNotify() <-chan bool {
|
func (r *Response) CloseNotify() <-chan bool {
|
||||||
return r.ResponseWriter.(http.CloseNotifier).CloseNotify()
|
return r.ResponseWriter.(http.CloseNotifier).CloseNotify()
|
||||||
}
|
}
|
||||||
|
@ -80,17 +80,17 @@ func NewFromConfig(c engine.Config) (s *Server) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHandler implements `engine.Server#SetHandler` method.
|
// SetHandler implements `engine.Server#SetHandler` function.
|
||||||
func (s *Server) SetHandler(h engine.Handler) {
|
func (s *Server) SetHandler(h engine.Handler) {
|
||||||
s.handler = h
|
s.handler = h
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLogger implements `engine.Server#SetLogger` method.
|
// SetLogger implements `engine.Server#SetLogger` function.
|
||||||
func (s *Server) SetLogger(l *log.Logger) {
|
func (s *Server) SetLogger(l *log.Logger) {
|
||||||
s.logger = l
|
s.logger = l
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start implements `engine.Server#Start` method.
|
// Start implements `engine.Server#Start` function.
|
||||||
func (s *Server) Start() error {
|
func (s *Server) Start() error {
|
||||||
if s.config.Listener == nil {
|
if s.config.Listener == nil {
|
||||||
return s.startDefaultListener()
|
return s.startDefaultListener()
|
||||||
|
@ -10,17 +10,17 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Path implements `engine.URL#Path` method.
|
// Path implements `engine.URL#Path` function.
|
||||||
func (u *URL) Path() string {
|
func (u *URL) Path() string {
|
||||||
return u.URL.Path
|
return u.URL.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPath implements `engine.URL#SetPath` method.
|
// SetPath implements `engine.URL#SetPath` function.
|
||||||
func (u *URL) SetPath(path string) {
|
func (u *URL) SetPath(path string) {
|
||||||
u.URL.Path = path
|
u.URL.Path = path
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryValue implements `engine.URL#QueryValue` method.
|
// QueryValue implements `engine.URL#QueryValue` function.
|
||||||
func (u *URL) QueryValue(name string) string {
|
func (u *URL) QueryValue(name string) string {
|
||||||
if u.query == nil {
|
if u.query == nil {
|
||||||
u.query = u.Query()
|
u.query = u.Query()
|
||||||
@ -28,7 +28,7 @@ func (u *URL) QueryValue(name string) string {
|
|||||||
return u.query.Get(name)
|
return u.query.Get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryString implements `engine.URL#QueryString` method.
|
// QueryString implements `engine.URL#QueryString` function.
|
||||||
func (u *URL) QueryString() string {
|
func (u *URL) QueryString() string {
|
||||||
return u.URL.RawQuery
|
return u.URL.RawQuery
|
||||||
}
|
}
|
||||||
|
17
group.go
17
group.go
@ -1,6 +1,9 @@
|
|||||||
package echo
|
package echo
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
// Group is a set of sub-routes for a specified route. It can be used for inner
|
||||||
|
// routes that share a common middlware or functionality that should be separate
|
||||||
|
// from the parent echo instance while still inheriting from it.
|
||||||
Group struct {
|
Group struct {
|
||||||
prefix string
|
prefix string
|
||||||
middleware []Middleware
|
middleware []Middleware
|
||||||
@ -8,59 +11,71 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Use implements `Echo#Use()` for sub-routes within the Group.
|
||||||
func (g *Group) Use(m ...Middleware) {
|
func (g *Group) Use(m ...Middleware) {
|
||||||
g.middleware = append(g.middleware, m...)
|
g.middleware = append(g.middleware, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Connect implements `Echo#Connect()` for sub-routes within the Group.
|
||||||
func (g *Group) Connect(path string, h Handler, m ...Middleware) {
|
func (g *Group) Connect(path string, h Handler, m ...Middleware) {
|
||||||
g.add(CONNECT, path, h, m...)
|
g.add(CONNECT, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete implements `Echo#Delete()` for sub-routes within the Group.
|
||||||
func (g *Group) Delete(path string, h Handler, m ...Middleware) {
|
func (g *Group) Delete(path string, h Handler, m ...Middleware) {
|
||||||
g.add(DELETE, path, h, m...)
|
g.add(DELETE, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get implements `Echo#Get()` for sub-routes within the Group.
|
||||||
func (g *Group) Get(path string, h Handler, m ...Middleware) {
|
func (g *Group) Get(path string, h Handler, m ...Middleware) {
|
||||||
g.add(GET, path, h, m...)
|
g.add(GET, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Head implements `Echo#Head()` for sub-routes within the Group.
|
||||||
func (g *Group) Head(path string, h Handler, m ...Middleware) {
|
func (g *Group) Head(path string, h Handler, m ...Middleware) {
|
||||||
g.add(HEAD, path, h, m...)
|
g.add(HEAD, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Options implements `Echo#Options()` for sub-routes within the Group.
|
||||||
func (g *Group) Options(path string, h Handler, m ...Middleware) {
|
func (g *Group) Options(path string, h Handler, m ...Middleware) {
|
||||||
g.add(OPTIONS, path, h, m...)
|
g.add(OPTIONS, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Patch implements `Echo#Patch()` for sub-routes within the Group.
|
||||||
func (g *Group) Patch(path string, h Handler, m ...Middleware) {
|
func (g *Group) Patch(path string, h Handler, m ...Middleware) {
|
||||||
g.add(PATCH, path, h, m...)
|
g.add(PATCH, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Post implements `Echo#Post()` for sub-routes within the Group.
|
||||||
func (g *Group) Post(path string, h Handler, m ...Middleware) {
|
func (g *Group) Post(path string, h Handler, m ...Middleware) {
|
||||||
g.add(POST, path, h, m...)
|
g.add(POST, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Put implements `Echo#Put()` for sub-routes within the Group.
|
||||||
func (g *Group) Put(path string, h Handler, m ...Middleware) {
|
func (g *Group) Put(path string, h Handler, m ...Middleware) {
|
||||||
g.add(PUT, path, h, m...)
|
g.add(PUT, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Trace implements `Echo#Trace()` for sub-routes within the Group.
|
||||||
func (g *Group) Trace(path string, h Handler, m ...Middleware) {
|
func (g *Group) Trace(path string, h Handler, m ...Middleware) {
|
||||||
g.add(TRACE, path, h, m...)
|
g.add(TRACE, path, h, m...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Any implements `Echo#Any()` for sub-routes within the Group.
|
||||||
func (g *Group) Any(path string, handler Handler, middleware ...Middleware) {
|
func (g *Group) Any(path string, handler Handler, middleware ...Middleware) {
|
||||||
for _, m := range methods {
|
for _, m := range methods {
|
||||||
g.add(m, path, handler, middleware...)
|
g.add(m, path, handler, middleware...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Match implements `Echo#Match()` for sub-routes within the Group.
|
||||||
func (g *Group) Match(methods []string, path string, handler Handler, middleware ...Middleware) {
|
func (g *Group) Match(methods []string, path string, handler Handler, middleware ...Middleware) {
|
||||||
for _, m := range methods {
|
for _, m := range methods {
|
||||||
g.add(m, path, handler, middleware...)
|
g.add(m, path, handler, middleware...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group creates a new sub-group with prefix.
|
// Group creates a new sub-group with prefix and optional sub-group-level middleware.
|
||||||
func (g *Group) Group(prefix string, m ...Middleware) *Group {
|
func (g *Group) Group(prefix string, m ...Middleware) *Group {
|
||||||
m = append(g.middleware, m...)
|
m = append(g.middleware, m...)
|
||||||
return g.echo.Group(g.prefix+prefix, m...)
|
return g.echo.Group(g.prefix+prefix, m...)
|
||||||
|
@ -7,10 +7,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
// BasicAuthConfig defines config for HTTP basic auth middleware.
|
||||||
BasicAuthConfig struct {
|
BasicAuthConfig struct {
|
||||||
AuthFunc BasicAuthFunc
|
AuthFunc BasicAuthFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BasicAuthFunc defines a function to validate basic auth credentials.
|
||||||
BasicAuthFunc func(string, string) bool
|
BasicAuthFunc func(string, string) bool
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -19,10 +21,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// DefaultBasicAuthConfig is the default basic auth middleware config.
|
||||||
DefaultBasicAuthConfig = BasicAuthConfig{}
|
DefaultBasicAuthConfig = BasicAuthConfig{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// BasicAuth returns an HTTP basic authentication middleware.
|
// BasicAuth returns an HTTP basic auth middleware.
|
||||||
//
|
//
|
||||||
// For valid credentials it calls the next handler.
|
// For valid credentials it calls the next handler.
|
||||||
// For invalid credentials, it sends "401 - Unauthorized" response.
|
// For invalid credentials, it sends "401 - Unauthorized" response.
|
||||||
@ -32,6 +35,8 @@ func BasicAuth(f BasicAuthFunc) echo.MiddlewareFunc {
|
|||||||
return BasicAuthFromConfig(c)
|
return BasicAuthFromConfig(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BasicAuthFromConfig returns an HTTP basic auth middleware from config.
|
||||||
|
// See `BasicAuth()`.
|
||||||
func BasicAuthFromConfig(config BasicAuthConfig) echo.MiddlewareFunc {
|
func BasicAuthFromConfig(config BasicAuthConfig) echo.MiddlewareFunc {
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.Handler) echo.Handler {
|
||||||
return echo.HandlerFunc(func(c echo.Context) error {
|
return echo.HandlerFunc(func(c echo.Context) error {
|
||||||
|
@ -13,7 +13,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
// GzipConfig defines config for gzip middleware.
|
||||||
GzipConfig struct {
|
GzipConfig struct {
|
||||||
|
// Level is the gzip level.
|
||||||
Level int
|
Level int
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,7 +26,8 @@ type (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
defaultGzipConfig = GzipConfig{
|
// DefaultGzipConfig is the default gzip middleware config.
|
||||||
|
DefaultGzipConfig = GzipConfig{
|
||||||
Level: gzip.DefaultCompression,
|
Level: gzip.DefaultCompression,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -32,10 +35,11 @@ var (
|
|||||||
// Gzip returns a middleware which compresses HTTP response using gzip compression
|
// Gzip returns a middleware which compresses HTTP response using gzip compression
|
||||||
// scheme.
|
// scheme.
|
||||||
func Gzip() echo.MiddlewareFunc {
|
func Gzip() echo.MiddlewareFunc {
|
||||||
return GzipFromConfig(defaultGzipConfig)
|
return GzipFromConfig(DefaultGzipConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GzipFromConfig return `Gzip` middleware from config.
|
// GzipFromConfig return gzip middleware from config.
|
||||||
|
// See `Gzip()`.
|
||||||
func GzipFromConfig(config GzipConfig) echo.MiddlewareFunc {
|
func GzipFromConfig(config GzipConfig) echo.MiddlewareFunc {
|
||||||
pool := gzipPool(config)
|
pool := gzipPool(config)
|
||||||
scheme := "gzip"
|
scheme := "gzip"
|
||||||
|
@ -15,26 +15,46 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
// LoggerConfig defines config for logger middleware.
|
||||||
|
//
|
||||||
LoggerConfig struct {
|
LoggerConfig struct {
|
||||||
Format string
|
// Format is the log format.
|
||||||
Output io.Writer
|
//
|
||||||
|
// Example "${remote_id} ${status}"
|
||||||
|
// Available tags:
|
||||||
|
// - time_rfc3339
|
||||||
|
// - remote_ip
|
||||||
|
// - method
|
||||||
|
// - path
|
||||||
|
// - status
|
||||||
|
// - response_time
|
||||||
|
// - response_size
|
||||||
|
Format string
|
||||||
|
|
||||||
|
// Output is the writer where logs are written. Default is `os.Stdout`.
|
||||||
|
Output io.Writer
|
||||||
|
|
||||||
template *fasttemplate.Template
|
template *fasttemplate.Template
|
||||||
color *color.Color
|
color *color.Color
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// DefaultLoggerConfig is the default logger middleware config.
|
||||||
DefaultLoggerConfig = LoggerConfig{
|
DefaultLoggerConfig = LoggerConfig{
|
||||||
Format: "time=${time_rfc3339}, remote_ip=${remote_ip}, method=${method}, path=${path}, status=${status}, response_time=${response_time}, size=${size}\n",
|
Format: "time=${time_rfc3339}, remote_ip=${remote_ip}, method=${method}, path=${path}, status=${status}, response_time=${response_time}, response_size=${response_size} bytes\n",
|
||||||
color: color.New(),
|
color: color.New(),
|
||||||
Output: os.Stdout,
|
Output: os.Stdout,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Logger returns a middleware that logs HTTP requests.
|
||||||
func Logger() echo.MiddlewareFunc {
|
func Logger() echo.MiddlewareFunc {
|
||||||
return LoggerFromConfig(DefaultLoggerConfig)
|
return LoggerFromConfig(DefaultLoggerConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoggerFromConfig returns a logger middleware from config.
|
||||||
|
// See `Logger()`.
|
||||||
func LoggerFromConfig(config LoggerConfig) echo.MiddlewareFunc {
|
func LoggerFromConfig(config LoggerConfig) echo.MiddlewareFunc {
|
||||||
config.template = fasttemplate.New(config.Format, "${", "}")
|
config.template = fasttemplate.New(config.Format, "${", "}")
|
||||||
config.color = color.New()
|
config.color = color.New()
|
||||||
@ -94,7 +114,7 @@ func LoggerFromConfig(config LoggerConfig) echo.MiddlewareFunc {
|
|||||||
return w.Write([]byte(status))
|
return w.Write([]byte(status))
|
||||||
case "response_time":
|
case "response_time":
|
||||||
return w.Write([]byte(took.String()))
|
return w.Write([]byte(took.String()))
|
||||||
case "size":
|
case "response_size":
|
||||||
return w.Write([]byte(size))
|
return w.Write([]byte(size))
|
||||||
default:
|
default:
|
||||||
return w.Write([]byte(fmt.Sprintf("[unknown tag %s]", tag)))
|
return w.Write([]byte(fmt.Sprintf("[unknown tag %s]", tag)))
|
||||||
|
@ -9,14 +9,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
// RecoverConfig defines config for recover middleware.
|
||||||
RecoverConfig struct {
|
RecoverConfig struct {
|
||||||
StackSize int
|
// StackSize is the stack size to be printed.
|
||||||
StackAll bool
|
StackSize int
|
||||||
|
|
||||||
|
// StackAll is flag to format stack traces of all other goroutines into
|
||||||
|
// buffer after the trace for the current goroutine, or not. Default is true.
|
||||||
|
StackAll bool
|
||||||
|
|
||||||
|
// PrintStack is the flag to print stack or not. Default is true.
|
||||||
PrintStack bool
|
PrintStack bool
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// DefaultRecoverConfig is the default recover middleware config.
|
||||||
DefaultRecoverConfig = RecoverConfig{
|
DefaultRecoverConfig = RecoverConfig{
|
||||||
StackSize: 4 << 10, // 4 KB
|
StackSize: 4 << 10, // 4 KB
|
||||||
StackAll: true,
|
StackAll: true,
|
||||||
@ -24,12 +32,14 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Recover returns a middleware which recovers from panics anywhere in the chain
|
||||||
|
// and handles the control to the centralized HTTPErrorHandler.
|
||||||
func Recover() echo.MiddlewareFunc {
|
func Recover() echo.MiddlewareFunc {
|
||||||
return RecoverFromConfig(DefaultRecoverConfig)
|
return RecoverFromConfig(DefaultRecoverConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recover returns a middleware which recovers from panics anywhere in the chain
|
// RecoverFromConfig returns a recover middleware from config.
|
||||||
// and handles the control to the centralized HTTPErrorHandler.
|
// See `Recover()`.
|
||||||
func RecoverFromConfig(config RecoverConfig) echo.MiddlewareFunc {
|
func RecoverFromConfig(config RecoverConfig) echo.MiddlewareFunc {
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.Handler) echo.Handler {
|
||||||
return echo.HandlerFunc(func(c echo.Context) error {
|
return echo.HandlerFunc(func(c echo.Context) error {
|
||||||
|
@ -9,26 +9,38 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
// StaticConfig defines config for static middleware.
|
||||||
StaticConfig struct {
|
StaticConfig struct {
|
||||||
Root string `json:"root"`
|
// Root is the directory from where the static content is served.
|
||||||
Index string `json:"index"`
|
Root string `json:"root"`
|
||||||
Browse bool `json:"browse"`
|
|
||||||
|
// Index is the index file to be used while serving a directory.
|
||||||
|
// Default is `index.html`.
|
||||||
|
Index string `json:"index"`
|
||||||
|
|
||||||
|
// Browse is the flag to list directory or not. Default is false.
|
||||||
|
Browse bool `json:"browse"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// DefaultStaticConfig is the default static middleware config.
|
||||||
DefaultStaticConfig = StaticConfig{
|
DefaultStaticConfig = StaticConfig{
|
||||||
Index: "index.html",
|
Index: "index.html",
|
||||||
Browse: false,
|
Browse: false,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Static returns a static middleware to deliever static content from the provided
|
||||||
|
// root directory.
|
||||||
func Static(root string) echo.MiddlewareFunc {
|
func Static(root string) echo.MiddlewareFunc {
|
||||||
c := DefaultStaticConfig
|
c := DefaultStaticConfig
|
||||||
c.Root = root
|
c.Root = root
|
||||||
return StaticFromConfig(c)
|
return StaticFromConfig(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StaticFromConfig returns a static middleware from config.
|
||||||
|
// See `Static()`.
|
||||||
func StaticFromConfig(config StaticConfig) echo.MiddlewareFunc {
|
func StaticFromConfig(config StaticConfig) echo.MiddlewareFunc {
|
||||||
return func(next echo.Handler) echo.Handler {
|
return func(next echo.Handler) echo.Handler {
|
||||||
return echo.HandlerFunc(func(c echo.Context) error {
|
return echo.HandlerFunc(func(c echo.Context) error {
|
||||||
|
14
router.go
14
router.go
@ -1,6 +1,8 @@
|
|||||||
package echo
|
package echo
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
// Router is the registry of all registered routes for an `Echo` instance for
|
||||||
|
// request matching and URL path parameter parsing.
|
||||||
Router struct {
|
Router struct {
|
||||||
tree *node
|
tree *node
|
||||||
routes []Route
|
routes []Route
|
||||||
@ -37,6 +39,7 @@ const (
|
|||||||
akind
|
akind
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewRouter returns a new Router instance.
|
||||||
func NewRouter(e *Echo) *Router {
|
func NewRouter(e *Echo) *Router {
|
||||||
return &Router{
|
return &Router{
|
||||||
tree: &node{
|
tree: &node{
|
||||||
@ -47,6 +50,7 @@ func NewRouter(e *Echo) *Router {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle implements `echo.Middleware` which makes router a middleware.
|
||||||
func (r *Router) Handle(next Handler) Handler {
|
func (r *Router) Handle(next Handler) Handler {
|
||||||
return HandlerFunc(func(c Context) error {
|
return HandlerFunc(func(c Context) error {
|
||||||
method := c.Request().Method()
|
method := c.Request().Method()
|
||||||
@ -56,10 +60,12 @@ func (r *Router) Handle(next Handler) Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Priority is super secret.
|
||||||
func (r *Router) Priority() int {
|
func (r *Router) Priority() int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add registers a new route for method and path with matching handler.
|
||||||
func (r *Router) Add(method, path string, h Handler, e *Echo) {
|
func (r *Router) Add(method, path string, h Handler, e *Echo) {
|
||||||
ppath := path // Pristine path
|
ppath := path // Pristine path
|
||||||
pnames := []string{} // Param names
|
pnames := []string{} // Param names
|
||||||
@ -280,6 +286,14 @@ func (n *node) check405() HandlerFunc {
|
|||||||
return notFoundHandler
|
return notFoundHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find lookup a handler registed for method and path. It also parses URL for path
|
||||||
|
// parameters and load them into context.
|
||||||
|
//
|
||||||
|
// For performance:
|
||||||
|
//
|
||||||
|
// - Get context from `Echo#GetContext()`
|
||||||
|
// - Reset it `Context#Reset()`
|
||||||
|
// - Return it `Echo#PutContext()`.
|
||||||
func (r *Router) Find(method, path string, context Context) {
|
func (r *Router) Find(method, path string, context Context) {
|
||||||
ctx := context.Object()
|
ctx := context.Object()
|
||||||
cn := r.tree // Current node as root
|
cn := r.tree // Current node as root
|
||||||
|
Loading…
Reference in New Issue
Block a user