ship

package module
v1.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2019 License: Apache-2.0 Imports: 30 Imported by: 0

README

ship Build Status GoDoc License

ship is a flexible, powerful, high performance and minimalist Go Web HTTP router framework. It is inspired by echo and httprouter. Thanks for those contributors.

ship has been stable, and the current version is v1.

Install

go get -u github.com/xgfone/ship

Prerequisite

Now ship requires Go 1.11+.

Quick Start

// example.go

package main

import (
	"net/http"

	"github.com/xgfone/ship"
)

func main() {
	router := ship.New()
	router.Route("/ping").GET(func(ctx *ship.Context) error {
		return ctx.JSON(200, map[string]interface{}{"message": "pong"})
	})

	// Start the HTTP server.
	router.Start(":8080")
	// or
	// http.ListenAndServe(":8080", router)
}
$ go run example.go
$ curl http://127.0.0.1:8080/ping
{"message":"pong"}

API Example

See GoDOC.

Router
Using Connect, Get, Post, Put, Patch, Delete and Option
func main() {
    router := ship.New()

    router.Route("/path/get").GET(getHandler)
    router.Route("/path/put").PUT(putHandler)
    router.Route("/path/post").POST(postHandler)
    router.Route("/path/patch").PATCH(patchHandler)
    router.Route("/path/delete").DELETE(deleteHandler)
    router.Route("/path/option").OPTIONS(optionHandler)
    router.Route("/path/connect").CONNECT(connectHandler)

    // Start the HTTP server.
    router.Start(":8080")
}

Notice: you can register the same handler with more than one method by Route(path string).Method(handler Handler, method ...string).

R is the alias of Route, you can register the routes by R(path string).Method(handler Handler, method ...string).

There is a default global ship, DefaultShip, and some its methods as the global functions, such as Pre, Use, G, R, GroupWithoutMiddleware, RouteWithoutMiddleware, URL, Start, StartServer, Wait, Shutdown. Suggest: You should use the default DefaultShip preferentially.

Cascade the registered routes
func main() {
    router := ship.New()
    router.R("/path/to").GET(getHandler).POST(postHandler).DELETE(deleteHandler)

    // Start the HTTP server.
    router.Start(":8080")
}

or use the mapping from method to handler:

func main() {
    router := ship.New()
    router.R("/path/to").Map(map[string]ship.Handler{
        "GET": getHandler,
        "POST": postHandler,
        "DELETE": deleteHandler,
    })

    // Start the HTTP server.
    router.Start(":8080")
}
Naming route and building URL

You can name the route when registering it, then you can build a URL by the name.

func main() {
    router := ship.New()

    router.Route("/path/:id").Name("get_url").GET(func(ctx *ship.Context) error {
        fmt.Println(ctx.URL("get_url", ctx.Param("id)))
    })

    // Start the HTTP server.
    router.Start(":8080")
}
Add the Header and Scheme filter
func main() {
    router := ship.New()

    handler := func(ctx *ship.Context) error { return nil }
    router.R("/path1").Schemes("https", "wss").GET(handler)
    router.R("/path2").Headers("Content-Type", "application/json").POST(handler)

    // Start the HTTP server.
    router.Start(":8080")
}
Map methods into Router
package main

import (
    "net/http"

    "github.com/xgfone/ship"
)

type TestType struct{}

func (t TestType) Create(ctx *ship.Context) error { return nil }
func (t TestType) Delete(ctx *ship.Context) error { return nil }
func (t TestType) Update(ctx *ship.Context) error { return nil }
func (t TestType) Get(ctx *ship.Context) error    { return nil }
func (t TestType) Has(ctx *ship.Context) error    { return nil }
func (t TestType) NotHandler()              {}

func main() {
    router := ship.New()
    router.Route("/v1").MapType(TestType{})
    router.Start(":8080")
}

router.Route("/v1").MapType(TestType{}) is equal to

tv := TestType{}
router.Route("/v1/testtype/get").Name("testtype_get").GET(tv.Get)
router.Route("/v1/testtype/update").Name("testtype_update").PUT(tv.Update)
router.Route("/v1/testtype/create").Name("testtype_create").POST(tv.Create)
router.Route("/v1/testtype/delete").Name("testtype_delete").DELETE(tv.Delete)

The default method mapping is as follow, which can be reset by SetDefaultMethodMapping when configuring Ship.

opt := SetDefaultMethodMapping (map[string]string{
    // "MethodName": "RequestMethod"
    "Create": "POST",
    "Delete": "DELETE",
    "Update": "PUT",
    "Get":    "GET",
})
router.Configure(opt)

Notice:

  • The name of type and method will be converted to the lower.
  • The mapping format of the route path is %{prefix}/%{lower_type_name}/%{lower_method_name}.
  • The mapping format of the route name is %{lower_type_name}_%{lower_method_name}.
  • The type of the method must be func(*ship.Context) error or it will be ignored.
Using SubRouter
func main() {
    router := ship.New()

    router.Use(middleware.Logger())
    router.Use(middleware.Recover())

    // v1 SubRouter, which will inherit the middlewares of the parent router.
    v1 := router.Group("/v1")
    v1.Route("/get/path").GET(getHandler)

    // v2 SubRouter, which won't inherit the middlewares of the parent router.
    v2 := router.GroupWithoutMiddleware("/v2")
    v2.Use(MyAuthMiddleware())
    v2.Route("/post/path").POST(postHandler)

    router.Start(":8080")
}
Traverse the registered route
func main() {
    router := ship.New()

    router.Route("/get/path").Name("get_name").GET(getHandler)
    router.Route("/post/path").Name("post_name").POST(posttHandler)

    router.Traverse(func(name, method, path string) {
        fmt.Println(name, method, path)
        // Output:
        // get_name GET /get/path
        // post_name POST /post/path
    })

    router.Start(":8080")
}
Filter the unacceptable route
func filter(name, path, method string) bool {
	if name == "" {
		return false
	} else if !strings.HasPrefix(path, "/prefix/") {
		return false
	}
	return true
}

func main() {
	// Don't register the router without name.
	app := ship.New(SetRouteFilter(filter))

	app.Group("/prefix").R("/name").Name("test").GET(handler) // Register the route
	app.Group("/prefix").R("/noname").GET(handler)            // Don't register the route
	app.R("/no_group").GET(handler)                           // Don't register the route
}
Modify the registered route
func modifier(name, path, method string) (string, string, string) {
	return name, "/prefix"+path, method
}

func main() {
	app := ship.New(SetRouteModifier(modifier))

	// Register the path as "/prefix/path".
	app.R("/path").Name("test").GET(handler)
}
Using Middleware
package main

import (
    "net/http"

    "github.com/xgfone/ship"
    "github.com/xgfone/ship/middleware"
)

func main() {
    // We disable the default error log because we have used the Logger middleware.
    app := ship.New(ship.DisableErrorLog(true))
    app.Use(middleware.Logger(), middleware.Recover())
    app.Use(MyAuthMiddleware())
    app.Route("/url/path").GET(handler)
    app.Start(":8080").Wait()
}

You can register a middleware to run before finding the router. You may affect the router finding by registering Before middleware. For example,

func RemovePathPrefix(prefix string) ship.Middleware {
    if len(prefix) < 2 || prefix[len(prefix)-1] == "/" {
        panic(fmt.Errorf("invalid prefix: '%s'", prefix))
    }

    return func(next ship.Handler) Handler {
        return func(ctx *ship.Context) error {
            req := ctx.Request()
            req.URL.Path = strings.TrimPrefix(req.URL.Path, prefix)
        }
    }
}

func main() {
    router := ship.New()

    // Use and Before have no interference each other.
    router.Use(middleware.Logger())
    router.Pre(RemovePathPrefix("/static"))
    router.Use(middleware.Recover())

    router.Route("/url/path").GET(handler)
    router.Start(":8080")
}

The sub-packages middleware has implemented some middleware as follows:

Add the Virtual Host
func main() {
    router := ship.New()
    router.Route("/router").GET(func(c *ship.Context) error { return c.String(200, "default") })

    vhost1 := router.VHost("host1.example.com")
    vhost1.Route("/router").GET(func(c *ship.Context) error { return c.String(200, "vhost1") })

    vhost2 := router.VHost("host2.example.com")
    vhost2.Route("/router").GET(func(c *ship.Context) error { return c.String(200, "vhost2") })

    router.Start(":8080")
}
$ curl http://127.0.0.1:8080/router
default

$ curl http://127.0.0.1:8080/router -H 'Host: host1.example.com'
vhost1

$ curl http://127.0.0.1:8080/router -H 'Host: host2.example.com'
vhost2
Many HTTP Server
package main

import (
	"github.com/xgfone/ship"
)

func main() {
	app1 := ship.New(ship.SetName("app1"))
	app1.Route("/").GET(func(ctx *ship.Context) error { return ctx.String(200, "app1") })

	app2 := app1.Clone("app2").Link(app1)
	app2.Route("/").GET(func(ctx *ship.Context) error { return ctx.String(200, "app2") })

	go app2.Start(":8001")
	app1.Start(":8000").Wait()
}

When you runs it, the console will output like this:

2019/03/07 22:25:41.701704 ship.go:571: [I] The HTTP Server [app1] is running on :8000
2019/03/07 22:25:41.702308 ship.go:571: [I] The HTTP Server [app2] is running on :8001

Then you can access http://127.0.0.1:8000 and http://127.0.0.1:8001. The servers returns app1 and app2.

When you keys Ctrl+C, the two servers will exit and output like this.

2019/03/07 22:26:16.243693 once.go:44: [I] The HTTP Server [app1] is shutdown
2019/03/07 22:26:16.243998 once.go:44: [I] The HTTP Server [app2] is shutdown

Notice:

  1. The router app returned by ship.New() will listen on the signals.
  2. For Clone(), app2 will also exit when app1 exits.
  3. For Link(), both app1 and app2 will exit when either exits.
Handle the complex response
package main

import (
	"fmt"
	"net/http"

	"github.com/xgfone/ship"
	"github.com/xgfone/ship/middleware"
)

func Responder := func(ctx *ship.Context, args ...interface{}) error {
	switch len(args) {
	case 0:
		return ctx.NoContent(http.StatusOK)
	case 1:
		switch v := args[0].(type) {
		case int:
			return ctx.NoContent(v)
		case string:
			return ctx.String(http.StatusOK, v)
		}
	case 2:
		switch v0 := args[0].(type) {
		case int:
			return ctx.String(v0, "%v", args[1])
		}
	}
	return ctx.NoContent(http.StatusInternalServerError)
}

func main() {
	router := ship.New()
	router.Use(middleware.SetCtxHandler(Responder))
	router.Route("/path1").GET(func(c *ship.Context) error { return c.Handle() })
	router.Route("/path2").GET(func(c *ship.Context) error { return c.Handle(200) })
	router.Route("/path3").GET(func(c *ship.Context) error { return c.Handle("Hello, World") })
	router.Route("/path4").GET(func(c *ship.Context) error { return c.Handle(200, "Hello, World") })

	router.Start(":8080")
}
Bind JSON, XML or Form data form payload

ship supply a default data binding to bind the JSON, XML or Form data from payload.

type Login struct {
    Username string `json:"username" xml:"username"`
    Password string `json:"password" xml:"password"`
}

func main() {
    router := ship.New()

    router.Route("/login").POST(func(ctx *ship.Context) error {
        var login Login
        if err := ctx.Bind(&login); err != nil {
            return err
        }
        ...
    })

    router.Start(":8080")
}
Render JSON, XML, HTML or other format data
package main

import (
	"net/http"

	"github.com/xgfone/ship"
	"github.com/xgfone/ship/renderers/django"
)

var filename = "test_django_engine.html"

func main() {
	engine := django.New(".", ".html")

	router := ship.New()
	router.MuxRenderer().Add(engine.Ext(), engine)

	// For JSON
	router.Route("/json").GET(func(ctx *ship.Context) error {
		if ctx.QueryParam("pretty") == "1" {
			return ctx.JSONPretty(200, map[string]interface{}{"msg": "json"}, "    ")
			// Or
			// return ctx.Render("jsonpretty", 200, map[string]interface{}{"msg": "json"})
		}
		return ctx.JSON(200, map[string]interface{}{"msg": "json"})
		// Or
		// return ctx.Render("json", 200, map[string]interface{}{"msg": "json"})
	})

	// For XML
	router.Route("/xml").GET(func(ctx *ship.Context) error {
		if ctx.QueryParam("pretty") == "1" {
			return ctx.XMLPretty(200, []string{"msg", "xml"}, "    ")
			// Or
			// return ctx.Render("xmlpretty", 200, []string{"msg", "xml"})
		}
		return ctx.XML(200, []string{"msg", "xml"})
		// Or
		// return ctx.Render("xml", 200, []string{"msg", "xml"})
	})

	// For HTML
	router.Route("/html").GET(func(ctx *ship.Context) error {
		return ctx.Render(filename, 200, map[string]interface{}{"name": "django"})
		// Or
		// return ctx.HTML(200, `<html>...</html>`)
	})

	// For others
	// ...

	// Start the HTTP server.
	router.Start(":8080")
}
Prometheus Metric
package main

import (
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/xgfone/ship"
)

func main() {
	app := ship.New()
	app.R("/metrics").GET(ship.FromHTTPHandler(promhttp.Handler()))
	app.Start(":8080")
	app.Wait()

	// You can write it like this:
	//
	// ship.New().R("/metrics").GET(ship.FromHTTPHandler(promhttp.Handler())).Ship().Start(":8080").Wait()
}

You can disable or remove the default collectors like this.

package main

import (
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/xgfone/ship"
)

// DisableBuiltinCollector removes the collectors that the default prometheus
// register registered.
func DisableBuiltinCollector() {
	prometheus.Unregister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}))
	prometheus.Unregister(prometheus.NewGoCollector())
}

func main() {
	DisableBuiltinCollector()
	ship.New().R("/metrics").GET(ship.FromHTTPHandler(promhttp.Handler())).Ship().Start(":8080").Wait()
}

The default prometheus HTTP handler, promhttp.Handler(), will collect two metrics: promhttp_metric_handler_requests_in_flight and promhttp_metric_handler_requests_total{code="200/500/503"}. However, you can rewrite it like this.

package main

import (
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/expfmt"
	"github.com/xgfone/ship"
)

// DisableBuiltinCollector removes the collectors that the default prometheus
// register registered.
func DisableBuiltinCollector() {
	prometheus.Unregister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}))
	prometheus.Unregister(prometheus.NewGoCollector())
}

// Prometheus returns a prometheus handler.
//
// if missing gatherer, it is prometheus.DefaultGatherer by default.
func Prometheus(gatherer ...prometheus.Gatherer) ship.Handler {
	gather := prometheus.DefaultGatherer
	if len(gatherer) > 0 && gatherer[0] != nil {
		gather = gatherer[0]
	}

	return func(ctx *ship.Context) error {
		mfs, err := gather.Gather()
		if err != nil {
			return err
		}

		ct := expfmt.Negotiate(ctx.Request().Header)
		ctx.SetContentType(string(ct))
		enc := expfmt.NewEncoder(ctx, ct)

		for _, mf := range mfs {
			if err = enc.Encode(mf); err != nil {
				ctx.Logger().Error("failed to encode prometheus metric: %s", err)
			}
		}

		return nil
	}
}

func main() {
	DisableBuiltinCollector()
	ship.New().R("/metrics").GET(Prometheus()).Ship().Start(":8080").Wait()
}

Route Management

ship supply a default implementation based on Radix tree to manage the route, which refers to echo, that's, NewRouter().

You can appoint your own implementation by implementing the interface ship.Router.

type Router interface {
	// Generate a URL by the url name and parameters.
	URL(name string, params ...interface{}) string

	// Add a route with name, path, method and handler,
	// and return the number of the parameters if there are the parameters
	// in the route. Or return 0.
	//
	// If the name has been added for the same path, it should be allowed.
	// Or it should panic.
	//
	// If the router does not support the parameter, it should panic.
	//
	// Notice: for keeping consistent, the parameter should start with ":"
	// or "*". ":" stands for a single parameter, and "*" stands for
	// a wildcard parameter.
	Add(name string, path string, method string, handler interface{}) (paramNum int)

	// Find a route handler by the method and path of the request.
	//
	// Return nil if the route does not exist.
	//
	// If the route has more than one parameter, the name and value
	// of the parameters should be stored `pnames` and `pvalues` respectively.
	Find(method string, path string, pnames []string, pvalues []string) (handler interface{})

	// Traverse each route.
	Each(func(name string, method string, path string))
}
func main() {
    NewMyRouter := func() ship.Router { return ... }
    router := ship.New(ship.SetNewRouter(NewMyRouter))
    ...
}

TODO

  • Add Host match for Route, referring to mux.Route.Host. We use the Virtual Host instead.
  • Add Query match for Route, referring to mux.Route.Queries. We use Matcher to operate it.
  • Add the serialization and deserialization middleware. We use Binder and Renderer.
  • Add HTML template render.
  • Add CORS middlware.
  • Add JWT middleware.
  • Add OAuth 2.0 middleware.

Documentation

Overview

Package ship has implemented a flexible, powerful, high performance and minimalist Go Web HTTP router framework, which is inspired by echo and httprouter.

Index

Examples

Constants

View Source
const (
	CharsetUTF8 = "charset=UTF-8"
	PROPFIND    = "PROPFIND"
)

Predefine some variables

View Source
const (
	MIMEApplicationJSON                  = "application/json"
	MIMEApplicationJSONCharsetUTF8       = MIMEApplicationJSON + "; " + CharsetUTF8
	MIMEApplicationJavaScript            = "application/javascript"
	MIMEApplicationJavaScriptCharsetUTF8 = MIMEApplicationJavaScript + "; " + CharsetUTF8
	MIMEApplicationXML                   = "application/xml"
	MIMEApplicationXMLCharsetUTF8        = MIMEApplicationXML + "; " + CharsetUTF8
	MIMETextXML                          = "text/xml"
	MIMETextXMLCharsetUTF8               = MIMETextXML + "; " + CharsetUTF8
	MIMEApplicationForm                  = "application/x-www-form-urlencoded"
	MIMEApplicationProtobuf              = "application/protobuf"
	MIMEApplicationMsgpack               = "application/msgpack"
	MIMETextHTML                         = "text/html"
	MIMETextHTMLCharsetUTF8              = MIMETextHTML + "; " + CharsetUTF8
	MIMETextPlain                        = "text/plain"
	MIMETextPlainCharsetUTF8             = MIMETextPlain + "; " + CharsetUTF8
	MIMEMultipartForm                    = "multipart/form-data"
	MIMEOctetStream                      = "application/octet-stream"
)

MIME types

View Source
const (
	HeaderAccept              = "Accept"
	HeaderAcceptedLanguage    = "Accept-Language"
	HeaderAcceptEncoding      = "Accept-Encoding"
	HeaderAllow               = "Allow"
	HeaderAuthorization       = "Authorization"
	HeaderConnection          = "Connection"
	HeaderContentDisposition  = "Content-Disposition"
	HeaderContentEncoding     = "Content-Encoding"
	HeaderContentLength       = "Content-Length"
	HeaderContentType         = "Content-Type"
	HeaderCookie              = "Cookie"
	HeaderSetCookie           = "Set-Cookie"
	HeaderIfModifiedSince     = "If-Modified-Since"
	HeaderLastModified        = "Last-Modified"
	HeaderEtag                = "Etag"
	HeaderLocation            = "Location"
	HeaderUpgrade             = "Upgrade"
	HeaderVary                = "Vary"
	HeaderWWWAuthenticate     = "WWW-Authenticate"
	HeaderXForwardedFor       = "X-Forwarded-For"
	HeaderXForwardedProto     = "X-Forwarded-Proto"
	HeaderXForwardedProtocol  = "X-Forwarded-Protocol"
	HeaderXForwardedSsl       = "X-Forwarded-Ssl"
	HeaderXUrlScheme          = "X-Url-Scheme"
	HeaderXHTTPMethodOverride = "X-HTTP-Method-Override"
	HeaderXRealIP             = "X-Real-IP"
	HeaderXRequestID          = "X-Request-ID"
	HeaderXRequestedWith      = "X-Requested-With"
	HeaderServer              = "Server"
	HeaderOrigin              = "Origin"
	HeaderReferer             = "Referer"
	HeaderUserAgent           = "User-Agent"

	// Access control
	HeaderAccessControlRequestMethod    = "Access-Control-Request-Method"
	HeaderAccessControlRequestHeaders   = "Access-Control-Request-Headers"
	HeaderAccessControlAllowOrigin      = "Access-Control-Allow-Origin"
	HeaderAccessControlAllowMethods     = "Access-Control-Allow-Methods"
	HeaderAccessControlAllowHeaders     = "Access-Control-Allow-Headers"
	HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"
	HeaderAccessControlExposeHeaders    = "Access-Control-Expose-Headers"
	HeaderAccessControlMaxAge           = "Access-Control-Max-Age"

	// Security
	HeaderStrictTransportSecurity = "Strict-Transport-Security"
	HeaderXContentTypeOptions     = "X-Content-Type-Options"
	HeaderXXSSProtection          = "X-XSS-Protection"
	HeaderXFrameOptions           = "X-Frame-Options"
	HeaderContentSecurityPolicy   = "Content-Security-Policy"
	HeaderXCSRFToken              = "X-CSRF-Token"
)

Headers

Variables

View Source
var (
	MIMEApplicationJSONs                  = []string{MIMEApplicationJSON}
	MIMEApplicationJSONCharsetUTF8s       = []string{MIMEApplicationJSONCharsetUTF8}
	MIMEApplicationJavaScripts            = []string{MIMEApplicationJavaScript}
	MIMEApplicationJavaScriptCharsetUTF8s = []string{MIMEApplicationJavaScriptCharsetUTF8}
	MIMEApplicationXMLs                   = []string{MIMEApplicationXML}
	MIMEApplicationXMLCharsetUTF8s        = []string{MIMEApplicationXMLCharsetUTF8}
	MIMETextXMLs                          = []string{MIMETextXML}
	MIMETextXMLCharsetUTF8s               = []string{MIMETextXMLCharsetUTF8}
	MIMEApplicationForms                  = []string{MIMEApplicationForm}
	MIMEApplicationProtobufs              = []string{MIMEApplicationProtobuf}
	MIMEApplicationMsgpacks               = []string{MIMEApplicationMsgpack}
	MIMETextHTMLs                         = []string{MIMETextHTML}
	MIMETextHTMLCharsetUTF8s              = []string{MIMETextHTMLCharsetUTF8}
	MIMETextPlains                        = []string{MIMETextPlain}
	MIMETextPlainCharsetUTF8s             = []string{MIMETextPlainCharsetUTF8}
	MIMEMultipartForms                    = []string{MIMEMultipartForm}
	MIMEOctetStreams                      = []string{MIMEOctetStream}
)

MIME slice types

View Source
var (
	ErrRendererNotRegistered = errors.New("renderer not registered")
	ErrInvalidRedirectCode   = errors.New("invalid redirect status code")
	ErrCookieNotFound        = errors.New("cookie not found")
	ErrNoHandler             = errors.New("no handler")
	ErrNoSessionSupport      = errors.New("no session support")
	ErrInvalidSession        = errors.New("invalid session")
	ErrSessionNotExist       = errors.New("session does not exist")
	ErrMissingContentType    = errors.New("missing the header 'Content-Type'")
)

Some non-HTTP Errors

View Source
var (
	ErrUnsupportedMediaType        = NewHTTPError(http.StatusUnsupportedMediaType)
	ErrNotFound                    = NewHTTPError(http.StatusNotFound)
	ErrUnauthorized                = NewHTTPError(http.StatusUnauthorized)
	ErrForbidden                   = NewHTTPError(http.StatusForbidden)
	ErrMethodNotAllowed            = NewHTTPError(http.StatusMethodNotAllowed)
	ErrStatusRequestEntityTooLarge = NewHTTPError(http.StatusRequestEntityTooLarge)
	ErrTooManyRequests             = NewHTTPError(http.StatusTooManyRequests)
	ErrBadRequest                  = NewHTTPError(http.StatusBadRequest)
	ErrBadGateway                  = NewHTTPError(http.StatusBadGateway)
	ErrInternalServerError         = NewHTTPError(http.StatusInternalServerError)
	ErrRequestTimeout              = NewHTTPError(http.StatusRequestTimeout)
	ErrServiceUnavailable          = NewHTTPError(http.StatusServiceUnavailable)
)

Some HTTP error.

View Source
var DefaultShip = New()

DefaultShip is the default global ship.

View Source
var ErrSkip = errors.New("skip")

ErrSkip is not an error, which is used to suggest that the middeware should skip and return it back to the outer middleware to handle.

Notice: it is only a suggestion.

View Source
var MaxMemoryLimit int64 = 32 << 20 // 32MB

MaxMemoryLimit is the maximum memory.

Functions

func AddContentTypeToSlice added in v1.0.0

func AddContentTypeToSlice(contentType string, contentTypeSlice []string)

AddContentTypeToSlice add a rule to convert contentType to contentTypeSlice.

When calling `Context#SetContentType(contentType)` to set the response header Content-Type, it will use contentTypeSlice to avoid to allocate the memory. See the function `ToContentTypes(contentType)`.

func BindURLValues added in v1.0.0

func BindURLValues(ptr interface{}, data url.Values, tag string) error

BindURLValues parses the data and assign to the pointer ptr to a struct.

Notice: tag is the name of the struct tag. such as "form", "query", etc.

func MaxNumOfURLParams added in v1.6.0

func MaxNumOfURLParams() int

MaxNumOfURLParams is equal to DefaultShip.MaxNumOfURLParams().

func Shutdown added in v1.6.0

func Shutdown(ctx context.Context) error

Shutdown is equal to DefaultShip.Shutdown(ctx).

func ToContentTypes added in v1.4.0

func ToContentTypes(contentType string) []string

ToContentTypes converts the Content-Type to the Content-Type slice.

func ToHTTPHandler

func ToHTTPHandler(s *Ship, h Handler) http.Handler

ToHTTPHandler converts the Handler to http.Handler

func Traverse added in v1.6.0

func Traverse(f func(name string, method string, path string))

Traverse is equal to DefaultShip.Traverse(f).

func URL added in v1.6.0

func URL(name string, params ...interface{}) string

URL is equal to DefaultShip.URL(name, params...).

func Wait added in v1.6.0

func Wait()

Wait is equal to DefaultShip.Wait().

Types

type BindUnmarshaler added in v1.0.0

type BindUnmarshaler interface {
	// Unmarshal decodes the argument param and assigns to itself.
	UnmarshalBind(param string) error
}

BindUnmarshaler is the interface used to wrap the UnmarshalParam method.

type Binder

type Binder interface {
	// Bind parses the data from ctx and assigns to v.
	//
	// Notice: v must be a non-nil pointer.
	Bind(ctx *Context, v interface{}) error
}

Binder is the interface to bind the value to v from ctx.

func BinderFunc added in v1.0.0

func BinderFunc(f func(*Context, interface{}) error) Binder

BinderFunc converts a function to Binder.

func FormBinder added in v1.0.0

func FormBinder(tag ...string) Binder

FormBinder returns a Form binder to bind the Form request.

Notice: The bound value must be a pointer to a struct. You can modify the name of the field by the tag, which is "form" by default.

func JSONBinder added in v1.0.0

func JSONBinder() Binder

JSONBinder returns a JSON binder to bind the JSON request.

func QueryBinder added in v1.0.0

func QueryBinder(tag ...string) Binder

QueryBinder returns a query binder to bind the query parameters..

Notice: The bound value must be a pointer to a struct. You can modify the name of the field by the tag, which is "query" by default.

func XMLBinder added in v1.0.0

func XMLBinder() Binder

XMLBinder returns a XML binder to bind the XML request.

type Context

type Context struct {
	// you can use it to pass the error between the handlers or the middlewares.
	//
	// Notice: when the new request is coming, it will be reset to nil.
	Err error

	// ReqCtxData is the data what each request has, the lifecycle of which is
	// the same as this context, that's, when creating this context, it will
	// call `newCtxData()`, which is set by `SetNewCtxData()` as the option of
	// the ship router, to creating ReqCtxData. When finishing the request,
	// it will be reset by the context and put into the pool with this context.
	ReqCtxData Resetter

	// Data is used to store many key-value pairs about the context.
	//
	// Data maybe asks the system to allocate many memories.
	// If the interim context value is too few and you don't want the system
	// to allocate many memories, the three context variables is for you
	// and you can consider them as the context register to use.
	//
	// Notice: when the new request is coming, they will be reset to nil.
	Key1 interface{}
	Key2 interface{}
	Key3 interface{}
	Data map[string]interface{}
	// contains filtered or unexported fields
}

Context represetns a request and response context.

func GetContext added in v1.0.0

func GetContext(req *http.Request) *Context

GetContext gets the Context from the http Request.

Notice: you must enable it by SetEnableCtxHTTPContext(true).

func (*Context) Accept added in v1.0.0

func (c *Context) Accept() []string

Accept returns the content of the header Accept.

If there is no the header Accept , it return nil.

Notice:

  1. It will sort the content by the q-factor weighting.
  2. If the value is "<MIME_type>/*", it will be amended as "<MIME_type>/". So you can use it to match the prefix.
  3. If the value is "*/*", it will be amended as "".

func (*Context) AcquireBuffer added in v1.0.0

func (c *Context) AcquireBuffer() *bytes.Buffer

AcquireBuffer acquires a buffer.

Notice: you should call ReleaseBuffer() to release it.

func (*Context) AddHeader added in v1.5.0

func (c *Context) AddHeader(name, value string)

AddHeader appends the value for the response header name.

func (*Context) Attachment added in v1.0.0

func (c *Context) Attachment(file string, name string) error

Attachment sends a response as attachment, prompting client to save the file.

If the file does not exist, it returns ErrNotFound.

func (*Context) BasicAuth added in v1.8.0

func (c *Context) BasicAuth() (username, password string, ok bool)

BasicAuth returns the username and password from the request.

func (*Context) Bind added in v1.0.0

func (c *Context) Bind(v interface{}) error

Bind binds the request information into the provided value v.

The default binder does it based on Content-Type header.

func (*Context) BindQuery added in v1.0.0

func (c *Context) BindQuery(v interface{}) error

BindQuery binds the request URL query into the provided value v.

func (*Context) Blob added in v1.0.0

func (c *Context) Blob(code int, contentType string, b []byte) (err error)

Blob sends a blob response with status code and content type.

func (*Context) BlobString added in v1.0.0

func (c *Context) BlobString(code int, contentType string, format string, args ...interface{}) (err error)

BlobString sends a string blob response with status code and content type.

func (*Context) Body added in v1.7.0

func (c *Context) Body() io.ReadCloser

Body returns the reader of the request body.

func (*Context) Charset added in v1.0.0

func (c *Context) Charset() string

Charset returns the charset of the request content.

Return "" if there is no charset.

func (*Context) ClearData added in v1.0.0

func (c *Context) ClearData()

ClearData clears the data.

func (*Context) ContentLength added in v1.0.0

func (c *Context) ContentLength() int64

ContentLength return the length of the request body.

func (*Context) ContentType added in v1.0.0

func (c *Context) ContentType() (ct string)

ContentType returns the Content-Type of the request without the charset.

func (*Context) Context added in v1.8.0

func (c *Context) Context() context.Context

Context returns the Context from the request.

func (*Context) Cookie added in v1.0.0

func (c *Context) Cookie(name string) (*http.Cookie, error)

Cookie returns the named cookie provided in the request.

func (*Context) Cookies added in v1.0.0

func (c *Context) Cookies() []*http.Cookie

Cookies returns the HTTP cookies sent with the request.

func (*Context) DelSession added in v1.0.0

func (c *Context) DelSession(id string) (err error)

DelSession deletes the session from the backend store.

id must not be "".

func (*Context) Error added in v1.5.0

func (c *Context) Error(code int, err error) error

Error sends an error response with status code.

If the error is the type of HTTPError, it will extract the fields of code and ct from it as the status code and the content-type.

func (*Context) File added in v1.0.0

func (c *Context) File(file string) (err error)

File sends a response with the content of the file.

If the file does not exist, it returns ErrNotFound.

If not set the Content-Type, it will deduce it from the extension of the file name.

func (*Context) FindHandler added in v1.0.0

func (c *Context) FindHandler(method, path string) Handler

FindHandler finds the registered router handler by the method and path of the request.

Return nil if not found.

func (*Context) FormFile added in v1.0.0

func (c *Context) FormFile(name string) (*multipart.FileHeader, error)

FormFile returns the multipart form file for the provided name.

func (*Context) FormFile2 added in v1.8.0

func (c *Context) FormFile2(name string) (multipart.File, *multipart.FileHeader, error)

FormFile2 returns the multipart form file for the provided name.

func (*Context) FormParams added in v1.0.0

func (c *Context) FormParams() (url.Values, error)

FormParams returns the form parameters as `url.Values`.

func (*Context) FormValue added in v1.0.0

func (c *Context) FormValue(name string) string

FormValue returns the form field value for the provided name.

func (*Context) GetBody added in v1.0.0

func (c *Context) GetBody() (string, error)

GetBody reads all the contents from the body and returns it as string.

func (*Context) GetBodyReader added in v1.0.0

func (c *Context) GetBodyReader() (buf *bytes.Buffer, err error)

GetBodyReader reads all the contents from the body to buffer and returns it.

Notice: You should call ReleaseBuffer(buf) to release the buffer at last.

func (*Context) GetHeader added in v1.0.0

func (c *Context) GetHeader(name string) string

GetHeader returns the first value of the request header named name.

Return "" if the header does not exist.

func (*Context) GetSession added in v1.0.0

func (c *Context) GetSession(id string) (v interface{}, err error)

GetSession returns the session content by id from the backend store.

If the session id does not exist, it maybe return (nil, nil).

Notice: for the same session id, the context maybe optimize GetSession by the cache, which will call the backend store only once.

func (*Context) HTML added in v1.0.0

func (c *Context) HTML(code int, html string) error

HTML sends an HTTP response with status code.

func (*Context) HTMLBlob added in v1.0.0

func (c *Context) HTMLBlob(code int, b []byte) error

HTMLBlob sends an HTTP blob response with status code.

func (*Context) Handle added in v1.0.0

func (c *Context) Handle(args ...interface{}) error

Handle calls the context handler.

Return ErrNoHandler if the context handler or the global handler is not set.

Example
responder := func(ctx *Context, args ...interface{}) error {
	return ctx.String(http.StatusOK, fmt.Sprintf("%s, %s", args...))
}

sethandler := func(next Handler) Handler {
	return func(ctx *Context) error {
		ctx.SetHandler(responder)
		return next(ctx)
	}
}

router := New()
router.Use(sethandler)
router.Route("/path/to").GET(func(c *Context) error { return c.Handle("Hello", "World") })

// For test
req := httptest.NewRequest(http.MethodGet, "/path/to", nil)
resp := httptest.NewRecorder()
router.ServeHTTP(resp, req)
fmt.Println(resp.Code)
fmt.Println(resp.Body.String())
Output:

200
Hello, World

func (*Context) Header added in v1.0.0

func (c *Context) Header(name string) string

Header is the alias of GetHeader.

func (*Context) Host added in v1.0.0

func (c *Context) Host() string

Host returns the host of the request.

func (*Context) Hostname added in v1.7.0

func (c *Context) Hostname() string

Hostname returns the hostname of the request.

func (*Context) Inline added in v1.0.0

func (c *Context) Inline(file string, name string) error

Inline sends a response as inline, opening the file in the browser.

If the file does not exist, it returns ErrNotFound.

func (*Context) IsAjax added in v1.0.0

func (c *Context) IsAjax() bool

IsAjax reports whether the request is ajax or not.

func (*Context) IsDebug added in v1.0.0

func (c *Context) IsDebug() bool

IsDebug reports whether to enable the debug mode.

func (*Context) IsResponded added in v1.0.0

func (c *Context) IsResponded() bool

IsResponded reports whether the response is sent.

func (*Context) IsTLS added in v1.0.0

func (c *Context) IsTLS() bool

IsTLS reports whether HTTP connection is TLS or not.

func (*Context) IsWebSocket added in v1.0.0

func (c *Context) IsWebSocket() bool

IsWebSocket reports whether HTTP connection is WebSocket or not.

func (*Context) JSON added in v1.0.0

func (c *Context) JSON(code int, i interface{}) error

JSON sends a JSON response with status code.

func (*Context) JSONBlob added in v1.0.0

func (c *Context) JSONBlob(code int, b []byte) error

JSONBlob sends a JSON blob response with status code.

func (*Context) JSONP added in v1.0.0

func (c *Context) JSONP(code int, callback string, i interface{}) error

JSONP sends a JSONP response with status code. It uses `callback` to construct the JSONP payload.

func (*Context) JSONPBlob added in v1.0.0

func (c *Context) JSONPBlob(code int, callback string, b []byte) (err error)

JSONPBlob sends a JSONP blob response with status code. It uses `callback` to construct the JSONP payload.

func (*Context) JSONPretty added in v1.0.0

func (c *Context) JSONPretty(code int, i interface{}, indent string) error

JSONPretty sends a pretty-print JSON with status code.

func (*Context) Logger added in v1.0.0

func (c *Context) Logger() Logger

Logger returns the logger implementation.

func (*Context) Method added in v1.0.0

func (c *Context) Method() string

Method returns the method of the request.

func (*Context) MultipartForm added in v1.0.0

func (c *Context) MultipartForm() (*multipart.Form, error)

MultipartForm returns the multipart form.

func (*Context) MultipartReader added in v1.8.0

func (c *Context) MultipartReader() (*multipart.Reader, error)

MultipartReader returns the multipart reader from the request.

func (*Context) NoContent added in v1.0.0

func (c *Context) NoContent(code int) error

NoContent sends a response with no body and a status code.

func (*Context) NotFoundHandler added in v1.0.0

func (c *Context) NotFoundHandler() Handler

NotFoundHandler returns the configured NotFound handler.

func (*Context) Param added in v1.0.0

func (c *Context) Param(name string) string

Param returns the parameter value in the url path by name.

func (*Context) ParamNames added in v1.0.0

func (c *Context) ParamNames() []string

ParamNames returns all the names of the URL parameters.

func (*Context) ParamToStruct added in v1.0.0

func (c *Context) ParamToStruct(v interface{}) error

ParamToStruct scans the url parameters to a pointer v to the struct.

For the struct, the argument name is the field name by default. But you can change it by the tag "url", such as `url:"name"`. The tag `url:"-"`, however, will ignore this field.

func (*Context) ParamValues added in v1.0.0

func (c *Context) ParamValues() []string

ParamValues returns all the names of the URL parameters.

func (*Context) Params added in v1.0.0

func (c *Context) Params() map[string]string

Params returns all the parameters as the key-value map in the url path.

func (*Context) Path added in v1.7.0

func (c *Context) Path() string

Path returns the path of the request.

func (*Context) QueryParam added in v1.0.0

func (c *Context) QueryParam(name string) string

QueryParam returns the query param for the provided name.

func (*Context) QueryParams added in v1.0.0

func (c *Context) QueryParams() url.Values

QueryParams returns the query parameters as `url.Values`.

func (*Context) QueryRawString added in v1.0.0

func (c *Context) QueryRawString() string

QueryRawString returns the URL query string.

func (*Context) RealIP added in v1.0.0

func (c *Context) RealIP() string

RealIP returns the client's network address based on `X-Forwarded-For` or `X-Real-IP` request header.

func (*Context) Redirect added in v1.0.0

func (c *Context) Redirect(code int, toURL string) error

Redirect redirects the request to a provided URL with status code.

func (*Context) Referer added in v1.8.0

func (c *Context) Referer() string

Referer returns the Referer header of the request.

func (*Context) ReleaseBuffer added in v1.0.0

func (c *Context) ReleaseBuffer(buf *bytes.Buffer)

ReleaseBuffer releases a buffer into the pool.

func (*Context) RemoteAddr added in v1.0.0

func (c *Context) RemoteAddr() string

RemoteAddr returns the remote address of the http connection.

func (*Context) Render added in v1.0.0

func (c *Context) Render(name string, code int, data interface{}) error

Render renders a template named name with data and sends a text/html response with status code.

func (*Context) ReqHeader added in v1.7.0

func (c *Context) ReqHeader() http.Header

ReqHeader returns the header of the request.

func (*Context) Request added in v1.0.0

func (c *Context) Request() *http.Request

Request returns the inner Request.

func (*Context) RequestURI added in v1.0.0

func (c *Context) RequestURI() string

RequestURI returns the URI of the request.

func (*Context) RespHeader added in v1.7.0

func (c *Context) RespHeader() http.Header

RespHeader returns the header of the response.

func (*Context) Response added in v1.0.0

func (c *Context) Response() http.ResponseWriter

Response returns the inner http.ResponseWriter.

Notice: you should not cache the returned response.

func (*Context) Router added in v1.0.0

func (c *Context) Router() Router

Router returns the router.

func (*Context) Scheme added in v1.0.0

func (c *Context) Scheme() (scheme string)

Scheme returns the HTTP protocol scheme, `http` or `https`.

func (*Context) SetConnectionClose added in v1.0.0

func (c *Context) SetConnectionClose()

SetConnectionClose tell the server to close the connection.

func (*Context) SetContentType added in v1.0.0

func (c *Context) SetContentType(contentType string)

SetContentType sets the Content-Type of the response body to contentType, but does nothing if contentType is "".

Notice: In order to avoid the memory allocation to improve performance, it will look up the corresponding Content-Type slice constant firstly, or generate one by the argument contentType, then set the response header Content-Type to the Content-Type slice. Howevre, you can call SetContentTypes() to set it to avoid the memory allocation, and pass "" to the response function, for example, JSON(), String(), Blob(), etc.

For the pre-defined Content-Type slices, please see https://godoc.org/github.com/xgfone/ship/#pkg-variables.

func (*Context) SetContentTypes added in v1.0.0

func (c *Context) SetContentTypes(contentTypes []string)

SetContentTypes sets the Content-Type of the response body to more than one.

func (*Context) SetCookie added in v1.0.0

func (c *Context) SetCookie(cookie *http.Cookie)

SetCookie adds a `Set-Cookie` header in HTTP response.

func (*Context) SetHandler added in v1.0.0

func (c *Context) SetHandler(h func(*Context, ...interface{}) error)

SetHandler sets a context handler in order to call it across the functions by the method Handle(), which is used to handle the various arguments.

For example,

responder := func(ctx *Context, args ...interface{}) error {
    switch len(args) {
    case 0:
        return ctx.NoContent(http.StatusOK)
    case 1:
        switch v := args[0].(type) {
        case int:
            return ctx.NoContent(v)
        case string:
            return ctx.String(http.StatusOK, v)
        }
    case 2:
        switch v0 := args[0].(type) {
        case int:
            return ctx.String(v0, "%v", args[1])
        }
    }
    return ctx.NoContent(http.StatusInternalServerError)
}

sethandler := func(next Handler) Handler {
    return func(ctx *Context) error {
        ctx.SetHandler(responder)
        return next(ctx)
    }
}

router := New()
router.Use(sethandler)
router.Route("/path1").GET(func(c *Context) error { return c.Handle() })
router.Route("/path2").GET(func(c *Context) error { return c.Handle(200) })
router.Route("/path3").GET(func(c *Context) error { return c.Handle("Hello, World") })
router.Route("/path4").GET(func(c *Context) error { return c.Handle(200, "Hello, World") })
Example
responder := func(ctx *Context, args ...interface{}) error {
	return ctx.String(http.StatusOK, fmt.Sprintf("%s, %s", args...))
}

sethandler := func(next Handler) Handler {
	return func(ctx *Context) error {
		ctx.SetHandler(responder)
		return next(ctx)
	}
}

router := New()
router.Use(sethandler)
router.Route("/path/to").GET(func(c *Context) error { return c.Handle("Hello", "World") })

// For test
req := httptest.NewRequest(http.MethodGet, "/path/to", nil)
resp := httptest.NewRecorder()
router.ServeHTTP(resp, req)
fmt.Println(resp.Code)
fmt.Println(resp.Body.String())
Output:

200
Hello, World

func (*Context) SetHeader added in v1.0.0

func (c *Context) SetHeader(name, value string)

SetHeader sets the response header name to value.

func (*Context) SetRequest added in v1.7.0

func (c *Context) SetRequest(req *http.Request)

SetRequest resets the request to req, which will ignore nil.

func (*Context) SetResponded added in v1.0.0

func (c *Context) SetResponded(yes bool)

SetResponded sets the response to be sent or not.

func (*Context) SetResponse added in v1.0.0

func (c *Context) SetResponse(resp http.ResponseWriter)

SetResponse resets the response to resp, which will ignore nil.

func (*Context) SetSession added in v1.0.0

func (c *Context) SetSession(id string, value interface{}) (err error)

SetSession sets the session to the backend store.

id must not be "".

value should not be nil. If nil, however, it will tell the context that the session id is missing, and the context should not forward the request to the underlying session store when calling GetSession.

func (*Context) StatusCode added in v1.2.0

func (c *Context) StatusCode() int

StatusCode returns the status code of the response.

Notice: it's used by the middleware, such as Logger in general.

func (*Context) Stream added in v1.0.0

func (c *Context) Stream(code int, contentType string, r io.Reader) (err error)

Stream sends a streaming response with status code and content type.

func (*Context) String added in v1.0.0

func (c *Context) String(code int, format string, args ...interface{}) (err error)

String sends a string response with status code.

func (*Context) URL added in v1.0.0

func (c *Context) URL(name string, params ...interface{}) string

URL generates an URL by route name and provided parameters.

func (*Context) UserAgent added in v1.8.0

func (c *Context) UserAgent() string

UserAgent returns the User-Agent header of the request.

func (*Context) Write added in v1.0.0

func (c *Context) Write(b []byte) (int, error)

Write writes the content to the peer.

it will write the header firstly if the header is not sent.

func (*Context) XML added in v1.0.0

func (c *Context) XML(code int, i interface{}) error

XML sends an XML response with status code.

func (*Context) XMLBlob added in v1.0.0

func (c *Context) XMLBlob(code int, b []byte) (err error)

XMLBlob sends an XML blob response with status code.

func (*Context) XMLPretty added in v1.0.0

func (c *Context) XMLPretty(code int, i interface{}, indent string) error

XMLPretty sends a pretty-print XML with status code.

type Group

type Group struct {
	// contains filtered or unexported fields
}

Group is a router group, that's, it manages a set of routes.

func G added in v1.6.0

func G(prefix string, middlewares ...Middleware) *Group

G is equal to DefaultShip.Group(prefix, middlewares...).

func GroupWithoutMiddleware added in v1.6.0

func GroupWithoutMiddleware(prefix string, middlewares ...Middleware) *Group

GroupWithoutMiddleware is equal to DefaultShip.GroupWithoutMiddleware(prefix, middlewares...).

func (*Group) Group

func (g *Group) Group(prefix string, middlewares ...Middleware) *Group

Group returns a new sub-group.

func (*Group) GroupWithoutMiddleware added in v1.0.0

func (g *Group) GroupWithoutMiddleware(prefix string, middlewares ...Middleware) *Group

GroupWithoutMiddleware is the same as Group, but not inherit the middlewares of the parent.

func (*Group) R

func (g *Group) R(path string) *Route

R is short for Group#Route(path).

func (*Group) Route

func (g *Group) Route(path string) *Route

Route returns a new route, then you can customize and register it.

You must call Route.Method() or its short method.

func (*Group) RouteWithoutMiddleware added in v1.0.0

func (g *Group) RouteWithoutMiddleware(path string) *Route

RouteWithoutMiddleware is the same as Group, but not inherit the middlewares of the group.

func (*Group) Ship added in v1.4.0

func (g *Group) Ship() *Ship

Ship returns the ship that the current group belongs to.

func (*Group) Use

func (g *Group) Use(middlewares ...Middleware) *Group

Use adds some middlwares for the group and returns the origin group to write the chained router.

type HTMLTemplateEngine added in v1.0.0

type HTMLTemplateEngine interface {
	// Ext should return the final file extension which this template engine
	// is responsible to render.
	Ext() string

	// Load or reload all the templates.
	Load() error

	// Eexecute and render a template by its filename.
	Execute(w io.Writer, filename string, data interface{}, metadata map[string]interface{}) error
}

HTMLTemplateEngine is the interface which all html template engines should be implemented.

type HTTPError

type HTTPError struct {
	Code int
	Msg  string
	Err  error
	CT   string // For Content-Type
}

HTTPError represents an error with HTTP Status Code.

func NewHTTPError

func NewHTTPError(code int, msg ...string) HTTPError

NewHTTPError returns a new HTTPError.

func (HTTPError) Error added in v1.0.0

func (e HTTPError) Error() string

func (HTTPError) GetError added in v1.3.0

func (e HTTPError) GetError() error

GetError returns the inner error.

If Err is nil but Msg is not "", return `errors.New(e.Msg)` instead; Or return nil.

HTTPError{Err: errors.New("")}.GetError() != nil
HTTPError{Msg: "xxx"}.GetError() != nil
HTTPError{Code: 200}.GetError() == nil

func (HTTPError) GetMsg added in v1.3.0

func (e HTTPError) GetMsg() string

GetMsg returns a message.

func (HTTPError) NewCT added in v1.3.0

func (e HTTPError) NewCT(ct string) HTTPError

NewCT returns a new HTTPError with the new ContentType ct.

func (HTTPError) NewError added in v1.0.0

func (e HTTPError) NewError(err error) HTTPError

NewError returns a new HTTPError with the new error.

func (HTTPError) NewMsg added in v1.0.0

func (e HTTPError) NewMsg(msg string, args ...interface{}) HTTPError

NewMsg returns a new HTTPError with the new msg.

type Handler

type Handler func(*Context) error

Handler is a handler of the HTTP request.

func FromHTTPHandler

func FromHTTPHandler(h http.Handler) Handler

FromHTTPHandler converts http.Handler to Handler.

func FromHTTPHandlerFunc

func FromHTTPHandlerFunc(h http.HandlerFunc) Handler

FromHTTPHandlerFunc converts http.HandlerFunc to Handler.

func MethodNotAllowedHandler

func MethodNotAllowedHandler() Handler

MethodNotAllowedHandler returns a MethodNotAllowed handler.

func NotFoundHandler

func NotFoundHandler() Handler

NotFoundHandler returns a NotFound handler.

func NothingHandler

func NothingHandler() Handler

NothingHandler returns a Handler doing nothing.

func OkHandler

func OkHandler() Handler

OkHandler returns a Handler only sending the response "200 OK"

func OptionsHandler

func OptionsHandler() Handler

OptionsHandler returns OPTIONS handler.

type Logger

type Logger interface {
	Writer() io.Writer
	Trace(format string, args ...interface{}) error
	Debug(foramt string, args ...interface{}) error
	Info(foramt string, args ...interface{}) error
	Warn(foramt string, args ...interface{}) error
	Error(foramt string, args ...interface{}) error
}

Logger stands for a logger.

func NewNoLevelLogger

func NewNoLevelLogger(w io.Writer, flag ...int) Logger

NewNoLevelLogger returns a new Logger based on the std library log.Logger, which has no level, that's, its level is always DEBUG.

type Marshaler added in v1.0.0

type Marshaler func(data interface{}) ([]byte, error)

Marshaler is used to marshal a value to []byte.

type Matcher added in v1.0.0

type Matcher func(*http.Request) error

Matcher is used to check whether the request match some conditions.

type Middleware

type Middleware func(Handler) Handler

Middleware represents a middleware.

type MuxBinder added in v1.0.0

type MuxBinder struct {
	// contains filtered or unexported fields
}

MuxBinder is a multiplexer for kinds of Binders.

func NewMuxBinder added in v1.0.0

func NewMuxBinder() *MuxBinder

NewMuxBinder returns a new MuxBinder.

func (*MuxBinder) Add added in v1.0.0

func (mb *MuxBinder) Add(contentType string, binder Binder)

Add adds a binder to bind the content for the header Content-Type.

func (*MuxBinder) Bind added in v1.0.0

func (mb *MuxBinder) Bind(ctx *Context, v interface{}) error

Bind implements the interface Binder, which will call the registered binder to bind the request to v by the request header Content-Type.

func (*MuxBinder) Del added in v1.0.0

func (mb *MuxBinder) Del(contentType string)

Del removes the corresponding binder by the header Content-Type.

func (*MuxBinder) Get added in v1.0.0

func (mb *MuxBinder) Get(contentType string) Binder

Get returns the corresponding binder by the header Content-Type.

Return nil if not found.

type MuxRenderer added in v1.0.0

type MuxRenderer struct {
	// contains filtered or unexported fields
}

MuxRenderer is a multiplexer for kinds of Renderers.

func NewMuxRenderer added in v1.0.0

func NewMuxRenderer() *MuxRenderer

NewMuxRenderer returns a new MuxRenderer.

func (*MuxRenderer) Add added in v1.0.0

func (mr *MuxRenderer) Add(suffix string, renderer Renderer)

Add adds a renderer with a suffix identifier.

func (*MuxRenderer) Del added in v1.0.0

func (mr *MuxRenderer) Del(suffix string)

Del removes the corresponding renderer by the suffix.

func (*MuxRenderer) Get added in v1.0.0

func (mr *MuxRenderer) Get(suffix string) Renderer

Get returns the corresponding renderer by the suffix.

Return nil if not found.

func (*MuxRenderer) Render added in v1.0.0

func (mr *MuxRenderer) Render(ctx *Context, name string, code int, data interface{}) error

Render implements the interface Renderer, which will get the renderer the name suffix then render the content.

type Option added in v1.0.0

type Option func(*Ship)

Option is used to configure Ship.

func DisableErrorLog added in v1.1.0

func DisableErrorLog(disabled bool) Option

DisableErrorLog disables the default error handler to log the error.

func EnableCtxHTTPContext added in v1.1.0

func EnableCtxHTTPContext(enable bool) Option

EnableCtxHTTPContext sets whether to inject the Context into the HTTP request as the http context, then you can use `GetContext(httpReq)` to get the Context.

func KeepTrailingSlashPath added in v1.1.0

func KeepTrailingSlashPath(keep bool) Option

KeepTrailingSlashPath sets whether to remove the trailing slash from the registered url path.

func SetBindQuery added in v1.0.0

func SetBindQuery(bind func(interface{}, url.Values) error) Option

SetBindQuery sets the query binder to bind the query to a value, which is `BindURLValues(v, d, "query")` by default.

func SetBinder added in v1.0.0

func SetBinder(b Binder) Option

SetBinder sets the Binder, which is used to bind a value from the request.

It's `MuxBinder` by default, which has added some binders, for example, "application/json", "application/xml", "text/xml", "multipart/form-data", and "application/x-www-form-urlencoded" as follow.

mb := New().MuxBinder()  // or NewMuxBinder(), but you need to set it.
mb.Add(MIMEApplicationJSON, JSONBinder())
mb.Add(MIMETextXML, XMLBinder())
mb.Add(MIMEApplicationXML, XMLBinder())
mb.Add(MIMEMultipartForm, FormBinder())
mb.Add(MIMEApplicationForm, FormBinder())

Then, you can add yourself binder, for example,

mb.Add("Content-Type", binder)

So you can use it by the four ways:

mb.Bind(ctx, ptr)

In the context, you can call it like this:

ctx.Bind(ptr)

func SetBufferSize added in v1.0.0

func SetBufferSize(size int) Option

SetBufferSize sets the buffer size, which is used to initializing the buffer pool.

The default is 2048.

func SetCtxDataSize added in v1.0.0

func SetCtxDataSize(size int) Option

SetCtxDataSize sets the initializing size of the context data, that's, Context.Data.

func SetCtxHandler added in v1.0.0

func SetCtxHandler(handler func(*Context, ...interface{}) error) Option

SetCtxHandler sets the default global context handler.

func SetDebug added in v1.0.0

func SetDebug(debug bool) Option

SetDebug sets whether to enable the debug mode, which is false by default.

func SetDefaultMethodMapping added in v1.0.0

func SetDefaultMethodMapping(m map[string]string) Option

SetDefaultMethodMapping sets the default mapping when registering the struct route.

The default is

map[string]string{
    "Create": "POST",
    "Delete": "DELETE",
    "Update": "PUT",
    "Get":    "GET",
}

func SetEnableCtxHTTPContext added in v1.0.0

func SetEnableCtxHTTPContext(enable bool) Option

SetEnableCtxHTTPContext is the alias of EnableCtxHTTPContext.

DEPRECATED! In order to keep the backward compatibility, it does not removed until the next major version.

func SetErrorHandler added in v1.0.0

func SetErrorHandler(handler func(*Context, error)) Option

SetErrorHandler sets default error handler, which will handle the error returned by the handler or the middleware at last.

The default will send the response to the peer if the error is a HTTPError. Or only send 500 if no response.

func SetKeepTrailingSlashPath added in v1.0.0

func SetKeepTrailingSlashPath(keep bool) Option

SetKeepTrailingSlashPath is the alias of KeepTrailingSlashPath.

DEPRECATED! In order to keep the backward compatibility, it does not removed until the next major version.

func SetLogger added in v1.0.0

func SetLogger(log Logger) Option

SetLogger sets the Logger, which is `NewNoLevelLogger(os.Stderr)` by default.

func SetMaxMiddlewareNum added in v1.0.0

func SetMaxMiddlewareNum(num int) Option

SetMaxMiddlewareNum sets the maximum number of the middlewares, which is 256 by default.

func SetMethodNotAllowedHandler added in v1.0.0

func SetMethodNotAllowedHandler(h Handler) Option

SetMethodNotAllowedHandler sets the handler to handle MethodNotAllowed.

It is used by the default router implemetation.

func SetName added in v1.0.0

func SetName(name string) Option

SetName sets the name, which is "" by default.

func SetNewCtxData added in v1.0.0

func SetNewCtxData(newCtxData func(*Context) Resetter) Option

SetNewCtxData sets the creator of the request data to correlating to the context when newing the context.

Notice: The lifecycle of the request data is the same as its context. When the context is created, the request data is also created. When finishing to handle the request, it will be reset by the context, not destroyed.

func SetNewRouter added in v1.0.0

func SetNewRouter(newRouter func() Router) Option

SetNewRouter sets the NewRouter to generate the new router.

if newRouter is nil, it will be reset to the default.

func SetNotFoundHandler added in v1.0.0

func SetNotFoundHandler(h Handler) Option

SetNotFoundHandler sets the handler to handle NotFound, which is `NotFoundHandler()` by default.

func SetOptionsHandler added in v1.0.0

func SetOptionsHandler(h Handler) Option

SetOptionsHandler sets the handler to handle the OPTIONS request.

It is used by the default router implemetation.

func SetPrefix added in v1.0.0

func SetPrefix(prefix string) Option

SetPrefix sets the route prefix, which is "" by default.

func SetRenderer added in v1.0.0

func SetRenderer(r Renderer) Option

SetRenderer sets the Renderer, which is used to render the response to the peer.

It's `MuxRenderer` by default, which has added some renderers, such as json, jsonpretty, xml, and xmlpretty as follow.

mr := New().MuxRenderer()  // or NewMuxRenderer(), but you need to set it.
mr.Add("json", JSONRenderer())
mr.Add("jsonpretty", JSONPrettyRenderer("    "))
mr.Add("xml", XMLRenderer())
mr.Add("xmlpretty", XMLPrettyRenderer("    "))

Then, you can add yourself renderer, for example,

engine := django.New(".", ".html"))
mr.Add(engine.Ext(), HTMLTemplate(engine))

So you can use it by the four ways:

mr.Render(ctx, "json", 200, data)
mr.Render(ctx, "jsonpretty", 200, data)
mr.Render(ctx, "xml", 200, data)
mr.Render(ctx, "xmlpretty", 200, data)
mr.Render(ctx, "index.html", 200, data)

In the context, you can call it like this:

ctx.Render("json", 200, data)
ctx.Render("jsonpretty", 200, data)
ctx.Render("xml", 200, data)
ctx.Render("xmlpretty", 200, data)
ctx.Render("index.html", 200, data)

func SetRouteFilter added in v1.7.0

func SetRouteFilter(filter func(name, path, method string) bool) Option

SetRouteFilter sets the route filter, which will ignore the route and not register it if the filter returns false.

For matching the group, you maybe check whether the path has the prefix, that's, the group name.

func SetRouteModifier added in v1.7.0

func SetRouteModifier(modifier func(name, path, method string) (string, string, string)) Option

SetRouteModifier sets the route modifier, which will modify the route before registering it.

The modifier maybe return the new name, path and method.

Notice: the modifier will be run before filter.

func SetSession added in v1.0.0

func SetSession(session Session) Option

SetSession sets the Session, which is `NewMemorySession()` by default.

func SetSignal added in v1.0.0

func SetSignal(sigs []os.Signal) Option

SetSignal sets the signals.

Notice: the signals will be wrapped and handled by the http server if running it.

The default is

[]os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGABRT, syscall.SIGINT}

In order to disable the signals, you can set it to []os.Signal{}.

type Renderer

type Renderer interface {
	Render(ctx *Context, name string, code int, data interface{}) error
}

Renderer is the interface to render the response.

func HTMLTemplateRenderer added in v1.0.0

func HTMLTemplateRenderer(engine HTMLTemplateEngine) Renderer

HTMLTemplateRenderer returns HTML template renderer.

func JSONPrettyRenderer added in v1.0.0

func JSONPrettyRenderer(indent string, marshal ...Marshaler) Renderer

JSONPrettyRenderer returns a pretty JSON renderer.

Example

renderer := JSONPrettyRenderer("    ")
renderer.Render(ctx, "jsonpretty", code, data)

# Or appoint a specific Marshaler.
renderer := JSONPrettyRenderer("", func(v interface{}) ([]byte, error) {
    return json.MarshalIndent(v, "", "  ")
})
renderer.Render(ctx, "jsonpretty", code, data)

Notice: the renderer name must be "jsonpretty".

func JSONRenderer added in v1.0.0

func JSONRenderer(marshal ...Marshaler) Renderer

JSONRenderer returns a JSON renderer.

Example

renderer := JSONRenderer()
renderer.Render(ctx, "json", code, data)

Notice: the renderer name must be "json".

func RendererFunc added in v1.0.0

func RendererFunc(f func(ctx *Context, name string, code int, v interface{}) error) Renderer

RendererFunc converts a function to Renderer.

func SimpleRenderer added in v1.0.0

func SimpleRenderer(name string, contentType string, marshaler Marshaler) Renderer

SimpleRenderer returns a simple renderer, which is the same as follow:

b, err := encode(data)
if err != nil {
    return err
}
return ctx.Blob(code, contentType, b)

func XMLPrettyRenderer added in v1.0.0

func XMLPrettyRenderer(indent string, marshal ...Marshaler) Renderer

XMLPrettyRenderer returns a pretty XML renderer.

Example

renderer := XMLPrettyRenderer("    ")
renderer.Render(ctx, "xmlpretty", code, data)

# Or appoint a specific Marshaler.
renderer := XMLPrettyRenderer("", func(v interface{}) ([]byte, error) {
    return xml.MarshalIndent(v, "", "  ")
})
renderer.Render(ctx, "xmlpretty", code, data)

Notice: the default marshaler won't add the XML header, and the renderer name must be "xmlpretty".

func XMLRenderer added in v1.0.0

func XMLRenderer(marshal ...Marshaler) Renderer

XMLRenderer returns a XML renderer.

Example

renderer := XMLRenderer()
renderer.Render(ctx, "xml", code, data)

Notice: the default marshaler won't add the XML header. and the renderer name must be "xml".

type Resetter added in v1.0.0

type Resetter interface {
	Reset()
}

Resetter is an Reset interface.

type Route

type Route struct {
	// contains filtered or unexported fields
}

Route represents a route information.

func R added in v1.6.0

func R(path string) *Route

R is equal to DefaultShip.Route(path).

func RouteWithoutMiddleware added in v1.6.0

func RouteWithoutMiddleware(path string) *Route

RouteWithoutMiddleware is equal to DefaultShip.RouteWithoutMiddleware(path).

func (*Route) Any

func (r *Route) Any(handler Handler) *Route

Any registers all the supported methods , which is short for r.Method(handler, "GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "CONNECT", "OPTIONS", "TRACE" )

func (*Route) CONNECT

func (r *Route) CONNECT(handler Handler) *Route

CONNECT is the short for r.Method(handler, "CONNECT").

func (*Route) DELETE

func (r *Route) DELETE(handler Handler) *Route

DELETE is the short for r.Method(handler, "DELETE").

func (*Route) GET

func (r *Route) GET(handler Handler) *Route

GET is the short for r.Method(handler, "GET").

func (*Route) Group added in v1.4.0

func (r *Route) Group() *Group

Group returns the group that the current route belongs to.

Notice: it will return nil if the route is from ship.Route.

func (*Route) HEAD

func (r *Route) HEAD(handler Handler) *Route

HEAD is the short for r.Method(handler, "HEAD").

func (*Route) HasSchemes added in v1.0.0

func (r *Route) HasSchemes(schemes ...string) *Route

HasSchemes checks whether the request is one of the schemes. If no, the request will be rejected.

Example

s := ship.New()
// We only handle https and wss, others will be rejected.
s.R("/path/to").HasSchemes("https", "wss").POST(handler)

Notice: it is implemented by using Matcher.

func (*Route) Header added in v1.0.0

func (r *Route) Header(headerK string, headerV ...string) *Route

Header checks whether the request contains the request header. If no, the request will be rejected.

If the header value is given, it will be tested to match.

Example

s := ship.New()
// The request must contains the header "Content-Type: application/json".
s.R("/path/to").HasHeader("Content-Type", "application/json").POST(handler)

Notice: it is implemented by using Matcher.

func (*Route) Map

func (r *Route) Map(method2handlers map[string]Handler) *Route

Map registers a group of methods with handlers, which is equal to

for method, handler := range method2handlers {
    r.Method(handler, method)
}

func (*Route) MapType

func (r *Route) MapType(tv interface{}, mapping ...map[string]string) *Route

MapType registers the methods of a type as the routes.

By default, mapping is Ship.Config.DefaultMethodMapping if not given.

Example

type TestType struct{}
func (t TestType) Create(ctx *ship.Context) error { return nil }
func (t TestType) Delete(ctx *ship.Context) error { return nil }
func (t TestType) Update(ctx *ship.Context) error { return nil }
func (t TestType) Get(ctx *ship.Context) error    { return nil }
func (t TestType) Has(ctx *ship.Context) error    { return nil }
func (t TestType) NotHandler()                   {}

router := ship.New()
router.Route("/path/to").MapType(TestType{})

It's equal to the operation as follow:

router.Route("/v1/testtype/get").Name("testtype_get").GET(ts.Get)
router.Route("/v1/testtype/update").Name("testtype_update").PUT(ts.Update)
router.Route("/v1/testtype/create").Name("testtype_create").POST(ts.Create)
router.Route("/v1/testtype/delete").Name("testtype_delete").DELETE(ts.Delete)

If you don't like the default mapping policy, you can give the customized mapping by the last argument, the key of which is the name of the method of the type, and the value of that is the request method, such as GET, POST, etc. Notice that the method type must be compatible with

func (*Context) error

Notice: the name of type and method will be converted to the lower.

func (*Route) Match added in v1.0.0

func (r *Route) Match(matchers ...Matcher) *Route

Match adds the matchers of the request to check whether the request matches these conditions.

These matchers will be executes as the middlewares.

func (*Route) MatchMiddleware added in v1.0.0

func (r *Route) MatchMiddleware(f func([]Matcher) Middleware) *Route

MatchMiddleware sets the matcher middleware.

The default implementation will execute those matchers in turn. If a certain matcher returns an error, it will return a HTTPError with 404 and the error.

func (*Route) Method

func (r *Route) Method(handler Handler, methods ...string) *Route

Method sets the methods and registers the route.

If methods is nil, it will register all the supported methods for the route.

Notice: The method must be called at last.

func (*Route) Name

func (r *Route) Name(name string) *Route

Name sets the route name.

func (*Route) New added in v1.0.0

func (r *Route) New() *Route

New clones a new Route based on the current route.

func (*Route) OPTIONS

func (r *Route) OPTIONS(handler Handler) *Route

OPTIONS is the short for r.Method(handler, "OPTIONS").

func (*Route) PATCH

func (r *Route) PATCH(handler Handler) *Route

PATCH is the short for r.Method(handler, "PATCH").

func (*Route) POST

func (r *Route) POST(handler Handler) *Route

POST is the short for r.Method(handler, "POST").

func (*Route) PUT

func (r *Route) PUT(handler Handler) *Route

PUT is the short for r.Method(handler, "PUT").

func (*Route) Redirect added in v1.1.0

func (r *Route) Redirect(code int, toURL string, method ...string) *Route

Redirect is used to redirect the path to toURL.

method is GET by default.

func (*Route) Ship added in v1.4.0

func (r *Route) Ship() *Ship

Ship returns the ship that the current route is associated with.

func (*Route) Static added in v1.0.0

func (r *Route) Static(dirpath string) *Route

Static is the same as StaticFS, but listing the files for a directory.

func (*Route) StaticFS added in v1.0.0

func (r *Route) StaticFS(fs http.FileSystem) *Route

StaticFS registers a route to serve a static filesystem.

func (*Route) StaticFile added in v1.0.0

func (r *Route) StaticFile(filePath string) *Route

StaticFile registers a route for a static file, which supports the HEAD method to get the its length and the GET method to download it.

func (*Route) TRACE

func (r *Route) TRACE(handler Handler) *Route

TRACE is the short for r.Method(handler, "TRACE").

func (*Route) Use

func (r *Route) Use(middlewares ...Middleware) *Route

Use adds some middlwares for the route.

type Router

type Router interface {
	// Generate a URL by the url name and parameters.
	URL(name string, params ...interface{}) string

	// Add a route with name, path, method and handler,
	// and return the number of the parameters if there are the parameters
	// in the route. Or return 0.
	//
	// If the name has been added for the same path, it should be allowed.
	// Or it should panic.
	//
	// If the router does not support the parameter, it should panic.
	//
	// Notice: for keeping consistent, the parameter should start with ":"
	// or "*". ":" stands for a single parameter, and "*" stands for
	// a wildcard parameter.
	Add(name string, path string, method string, handler interface{}) (paramNum int)

	// Find a route handler by the method and path of the request.
	//
	// Return nil if the route does not exist.
	//
	// If the route has more than one parameter, the name and value
	// of the parameters should be stored `pnames` and `pvalues` respectively.
	Find(method string, path string, pnames []string, pvalues []string) (handler interface{})

	// Traverse each route.
	Each(func(name string, method string, path string))
}

Router stands for a router management.

type Session added in v1.0.0

type Session interface {
	// If the session id does not exist, it should return (nil, nil).
	GetSession(id string) (value interface{}, err error)
	SetSession(id string, value interface{}) error
	DelSession(id string) error
}

Session represents an interface about the session.

func NewMemorySession added in v1.0.0

func NewMemorySession() Session

NewMemorySession return a Session implementation based on the memory.

type Ship

type Ship struct {
	// contains filtered or unexported fields
}

Ship is an app to be used to manage the router.

func Clone added in v1.6.0

func Clone(name ...string) *Ship

Clone is equal to DefaultShip.Clone(name...).

func Configure added in v1.6.0

func Configure(options ...Option) *Ship

Configure is equal to DefaultShip.Configure(options...).

func Link(other *Ship) *Ship

Link is equal to DefaultShip.Link(other).

func New

func New(options ...Option) *Ship

New returns a new Ship.

func Pre added in v1.6.0

func Pre(middlewares ...Middleware) *Ship

Pre is equal to DefaultShip.Pre(middlewares...).

func RegisterOnShutdown added in v1.6.0

func RegisterOnShutdown(functions ...func()) *Ship

RegisterOnShutdown is equal to DefaultShip.RegisterOnShutdown(functions...).

func SetConnStateHandler added in v1.6.0

func SetConnStateHandler(h func(net.Conn, http.ConnState)) *Ship

SetConnStateHandler is equal to DefaultShip.SetConnStateHandler(h).

func Start added in v1.6.0

func Start(addr string, tlsFiles ...string) *Ship

Start is equal to DefaultShip.Start(addr, tlsFiles...).

func StartServer added in v1.6.0

func StartServer(server *http.Server) *Ship

StartServer is equal to DefaultShip.StartServer(server).

func Use added in v1.6.0

func Use(middlewares ...Middleware) *Ship

Use is equal to DefaultShip.Use(middlewares...).

func VHost added in v1.6.0

func VHost(host string) *Ship

VHost is equal to DefaultShip.VHost(host).

func (*Ship) AcquireBuffer added in v1.0.0

func (s *Ship) AcquireBuffer() *bytes.Buffer

AcquireBuffer gets a Buffer from the pool.

func (*Ship) AcquireContext

func (s *Ship) AcquireContext(r *http.Request, w http.ResponseWriter) *Context

AcquireContext gets a Context from the pool.

func (*Ship) Binder added in v1.0.0

func (s *Ship) Binder() Binder

Binder returns the inner Binder.

func (*Ship) Clone added in v1.0.0

func (s *Ship) Clone(name ...string) *Ship

Clone returns a new Ship router with a new name by the current configuration.

Notice: the new router will disable the signals and register the shutdown function into the parent Ship router.

func (*Ship) Configure added in v1.0.0

func (s *Ship) Configure(options ...Option) *Ship

Configure configures the Ship.

Notice: the method must be called before starting the http server.

func (*Ship) Group

func (s *Ship) Group(prefix string, middlewares ...Middleware) *Group

Group returns a new sub-group.

func (*Ship) GroupWithoutMiddleware added in v1.0.0

func (s *Ship) GroupWithoutMiddleware(prefix string, middlewares ...Middleware) *Group

GroupWithoutMiddleware is the same as Group, but not inherit the middlewares of Ship.

func (s *Ship) Link(other *Ship) *Ship

Link links other to the current router, that's, only if either of the two routers is shutdown, another is also shutdown.

Return the current router.

func (*Ship) Logger

func (s *Ship) Logger() Logger

Logger returns the inner Logger

func (*Ship) MaxNumOfURLParams added in v1.6.0

func (s *Ship) MaxNumOfURLParams() int

MaxNumOfURLParams reports the maximum number of the parameters of all the URLs.

Notice: it should be only called after adding all the urls.

func (*Ship) MuxBinder added in v1.0.0

func (s *Ship) MuxBinder() *MuxBinder

MuxBinder check whether the inner Binder is MuxBinder.

If yes, return it as "*MuxBinder"; or return nil.

func (*Ship) MuxRenderer added in v1.0.0

func (s *Ship) MuxRenderer() *MuxRenderer

MuxRenderer check whether the inner Renderer is MuxRenderer.

If yes, return it as "*MuxRenderer"; or return nil.

func (*Ship) NewContext

func (s *Ship) NewContext(r *http.Request, w http.ResponseWriter) *Context

NewContext news and returns a Context.

func (*Ship) Pre

func (s *Ship) Pre(middlewares ...Middleware) *Ship

Pre registers the Pre-middlewares, which are executed before finding the route. then returns the origin ship router to write the chained router.

func (*Ship) R

func (s *Ship) R(path string) *Route

R is short for Ship#Route(path).

func (*Ship) RegisterOnShutdown added in v1.0.0

func (s *Ship) RegisterOnShutdown(functions ...func()) *Ship

RegisterOnShutdown registers some functions to run when the http server is shut down.

func (*Ship) ReleaseBuffer added in v1.0.0

func (s *Ship) ReleaseBuffer(buf *bytes.Buffer)

ReleaseBuffer puts a Buffer into the pool.

func (*Ship) ReleaseContext

func (s *Ship) ReleaseContext(c *Context)

ReleaseContext puts a Context into the pool.

func (*Ship) Renderer added in v1.0.0

func (s *Ship) Renderer() Renderer

Renderer returns the inner Renderer.

func (*Ship) Route

func (s *Ship) Route(path string) *Route

Route returns a new route, then you can customize and register it.

You must call Route.Method() or its short method.

func (*Ship) RouteWithoutMiddleware added in v1.0.0

func (s *Ship) RouteWithoutMiddleware(path string) *Route

RouteWithoutMiddleware is the same as Route, but not inherit the middlewares of Ship.

func (*Ship) Router

func (s *Ship) Router() Router

Router returns the inner Router.

func (*Ship) ServeHTTP

func (s *Ship) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the interface http.Handler.

func (*Ship) SetConnStateHandler added in v1.0.0

func (s *Ship) SetConnStateHandler(h func(net.Conn, http.ConnState)) *Ship

SetConnStateHandler sets a handler to monitor the change of the connection state, which is used by the HTTP server.

func (*Ship) Shutdown added in v1.0.0

func (s *Ship) Shutdown(ctx context.Context) error

Shutdown stops the HTTP server.

func (*Ship) Start added in v1.0.0

func (s *Ship) Start(addr string, tlsFiles ...string) *Ship

Start starts a HTTP server with addr and ends when the server is closed.

If tlsFile is not nil, it must be certFile and keyFile. That's,

router := ship.New()
rouetr.Start(addr, certFile, keyFile)

func (*Ship) StartServer added in v1.0.0

func (s *Ship) StartServer(server *http.Server) *Ship

StartServer starts a HTTP server and ends when the server is closed.

func (*Ship) Stop added in v1.9.0

func (s *Ship) Stop()

Stop is equal to s.Shutdown(context.Background()).

func (*Ship) Traverse

func (s *Ship) Traverse(f func(name string, method string, path string))

Traverse traverses the registered route.

func (*Ship) URL

func (s *Ship) URL(name string, params ...interface{}) string

URL generates an URL from route name and provided parameters.

func (*Ship) Use

func (s *Ship) Use(middlewares ...Middleware) *Ship

Use registers the global middlewares and returns the origin ship router to write the chained router.

func (*Ship) VHost added in v1.0.0

func (s *Ship) VHost(host string) *Ship

VHost returns a new ship used to manage the virtual host.

For the different virtual host, you can register the same route.

Notice: the new virtual host won't inherit anything except the configuration.

func (*Ship) Wait added in v1.0.0

func (s *Ship) Wait()

Wait waits until all the registered shutdown functions have finished.

Directories

Path Synopsis
_examples
Package middleware is the collection of the middlewares.
Package middleware is the collection of the middlewares.
render
django Module
Package router supplies some the builtin implementation about Router.
Package router supplies some the builtin implementation about Router.
echo
Package echo supplies a Router implementation based on github.com/labstack/echo.
Package echo supplies a Router implementation based on github.com/labstack/echo.
lock
Package lock makes a unsafe Router implementation to be thread-safe.
Package lock makes a unsafe Router implementation to be thread-safe.
Package utils supplies some utility tools.
Package utils supplies some utility tools.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL