fasthttp

package module
v0.0.0-...-9e531e8 Latest Latest
Warning

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

Go to latest
Published: Dec 4, 2015 License: MIT Imports: 23 Imported by: 0

README

fasthttp

Fast HTTP implementation for Go.

Currently fasthttp is successfully used in a production serving 100K rps from 1M concurrent keep-alive connections on a single server.

Build Status

Documentation

Examples from docs

Code examples

Switching from net/http to fasthttp

Fasthttp best practicies

Tricks with byte buffers

FAQ

HTTP server performance comparison with net/http

In short, fasthttp server is up to 10 times faster than net/http. Below are benchmark results.

GOMAXPROCS=1

net/http:

$ GOMAXPROCS=1 go test -bench=NetHTTPServerGet -benchmem -benchtime=5s
PASS
BenchmarkNetHTTPServerGet1ReqPerConn            	  300000	     21236 ns/op	    2404 B/op	      30 allocs/op
BenchmarkNetHTTPServerGet2ReqPerConn            	  500000	     14634 ns/op	    2371 B/op	      24 allocs/op
BenchmarkNetHTTPServerGet10ReqPerConn           	 1000000	      9447 ns/op	    2101 B/op	      19 allocs/op
BenchmarkNetHTTPServerGet10KReqPerConn          	 1000000	      7939 ns/op	    2033 B/op	      18 allocs/op
BenchmarkNetHTTPServerGet1ReqPerConn10KClients  	  300000	     30291 ns/op	    4589 B/op	      31 allocs/op
BenchmarkNetHTTPServerGet2ReqPerConn10KClients  	  500000	     23199 ns/op	    3581 B/op	      25 allocs/op
BenchmarkNetHTTPServerGet10ReqPerConn10KClients 	  500000	     13270 ns/op	    2621 B/op	      19 allocs/op
BenchmarkNetHTTPServerGet100ReqPerConn10KClients	  500000	     11412 ns/op	    2119 B/op	      18 allocs/op

fasthttp:

$ GOMAXPROCS=1 go test -bench=kServerGet -benchmem -benchtime=5s
PASS
BenchmarkServerGet1ReqPerConn            	 3000000	      2341 ns/op	       0 B/op	       0 allocs/op
BenchmarkServerGet2ReqPerConn            	 5000000	      1799 ns/op	       0 B/op	       0 allocs/op
BenchmarkServerGet10ReqPerConn           	 5000000	      1239 ns/op	       0 B/op	       0 allocs/op
BenchmarkServerGet10KReqPerConn          	10000000	      1090 ns/op	       0 B/op	       0 allocs/op
BenchmarkServerGet1ReqPerConn10KClients  	 3000000	      2860 ns/op	       4 B/op	       0 allocs/op
BenchmarkServerGet2ReqPerConn10KClients  	 3000000	      1992 ns/op	       1 B/op	       0 allocs/op
BenchmarkServerGet10ReqPerConn10KClients 	 5000000	      1297 ns/op	       1 B/op	       0 allocs/op
BenchmarkServerGet100ReqPerConn10KClients	10000000	      1264 ns/op	       9 B/op	       0 allocs/op

GOMAXPROCS=4

net/http:

$ GOMAXPROCS=4 go test -bench=NetHTTPServerGet -benchmem -benchtime=5s
PASS
BenchmarkNetHTTPServerGet1ReqPerConn-4            	 1000000	      5545 ns/op	    2433 B/op	      30 allocs/op
BenchmarkNetHTTPServerGet2ReqPerConn-4            	 2000000	      4147 ns/op	    2398 B/op	      24 allocs/op
BenchmarkNetHTTPServerGet10ReqPerConn-4           	 3000000	      2628 ns/op	    2118 B/op	      19 allocs/op
BenchmarkNetHTTPServerGet10KReqPerConn-4          	 3000000	      2304 ns/op	    2037 B/op	      18 allocs/op
BenchmarkNetHTTPServerGet1ReqPerConn10KClients-4  	 1000000	      7327 ns/op	    3561 B/op	      30 allocs/op
BenchmarkNetHTTPServerGet2ReqPerConn10KClients-4  	 1000000	      5952 ns/op	    3073 B/op	      24 allocs/op
BenchmarkNetHTTPServerGet10ReqPerConn10KClients-4 	 2000000	      4345 ns/op	    2530 B/op	      19 allocs/op
BenchmarkNetHTTPServerGet100ReqPerConn10KClients-4	 2000000	      3866 ns/op	    2132 B/op	      18 allocs/op

fasthttp:

$ GOMAXPROCS=4 go test -bench=kServerGet -benchmem -benchtime=5s
PASS
BenchmarkServerGet1ReqPerConn-4            	10000000	      1053 ns/op	       0 B/op	       0 allocs/op
BenchmarkServerGet2ReqPerConn-4            	10000000	       685 ns/op	       0 B/op	       0 allocs/op
BenchmarkServerGet10ReqPerConn-4           	20000000	       393 ns/op	       0 B/op	       0 allocs/op
BenchmarkServerGet10KReqPerConn-4          	20000000	       338 ns/op	       0 B/op	       0 allocs/op
BenchmarkServerGet1ReqPerConn10KClients-4  	10000000	      1033 ns/op	       0 B/op	       0 allocs/op
BenchmarkServerGet2ReqPerConn10KClients-4  	10000000	       668 ns/op	       0 B/op	       0 allocs/op
BenchmarkServerGet10ReqPerConn10KClients-4 	20000000	       393 ns/op	       0 B/op	       0 allocs/op
BenchmarkServerGet100ReqPerConn10KClients-4	20000000	       384 ns/op	       4 B/op	       0 allocs/op

HTTP client comparison with net/http

In short, fasthttp client is up to 10 times faster than net/http. Below are benchmark results.

GOMAXPROCS=1

net/http:

$ GOMAXPROCS=1 go test -bench='HTTPClient(Do|GetEndToEnd)' -benchmem -benchtime=5s
PASS
BenchmarkNetHTTPClientDoFastServer	  500000	     17535 ns/op	    2624 B/op	      38 allocs/op
BenchmarkNetHTTPClientGetEndToEnd 	  200000	     56593 ns/op	    5012 B/op	      59 allocs/op

fasthttp:

$ GOMAXPROCS=1 go test -bench='kClient(Do|GetEndToEnd)' -benchmem -benchtime=5s
PASS
BenchmarkClientDoFastServer	 5000000	      1420 ns/op	       0 B/op	       0 allocs/op
BenchmarkClientGetEndToEnd 	  500000	     17912 ns/op	       0 B/op	       0 allocs/op

GOMAXPROCS=4

net/http:

$ GOMAXPROCS=4 go test -bench='HTTPClient(Do|GetEndToEnd)' -benchmem -benchtime=5s
PASS
BenchmarkNetHTTPClientDoFastServer-4	 1000000	      5795 ns/op	    2626 B/op	      38 allocs/op
BenchmarkNetHTTPClientGetEndToEnd-4 	  500000	     19304 ns/op	    5953 B/op	      62 allocs/op

fasthttp:

$ GOMAXPROCS=4 go test -bench='kClient(Do|GetEndToEnd)' -benchmem -benchtime=5s
PASS
BenchmarkClientDoFastServer-4	20000000	       443 ns/op	       0 B/op	       0 allocs/op
BenchmarkClientGetEndToEnd-4 	 1000000	      5954 ns/op	       0 B/op	       0 allocs/op

Switching from net/http to fasthttp

Unfortunately, fasthttp doesn't provide API identical to net/http. See the FAQ for details.

Important points:

type MyHandler struct {
	foobar string
}

// request handler in net/http style, i.e. method bound to MyHandler struct.
func (h *MyHandler) HandleFastHTTP(ctx *fasthttp.RequestCtx) {
	// notice that we may access MyHandler properties here - see h.foobar.
	fmt.Fprintf(ctx, "Hello, world! Requested path is %q. Foobar is %q",
		ctx.Path(), h.foobar)
}

// request handler in fasthttp style, i.e. just plain function.
func fastHTTPHandler(ctx *fasthttp.RequestCtx) {
	fmt.Fprintf(ctx, "Hi there! RequestURI is %q", ctx.RequestURI())
}

// pass bound struct method to fasthttp
myHandler := &MyHandler{
	foobar: "foobar",
}
fasthttp.ListenAndServe(":8080", myHandler.HandleFastHTTP)

// pass plain function to fasthttp
fasthttp.ListenAndServe(":8081", fastHTTPHandler)
  • The RequestHandler accepts only one argument - RequestCtx. It contains all the functionality required for http request processing and response writing. Below is an example of a simple request handler conversion from net/http to fasthttp.
// net/http request handler
requestHandler := func(w http.ResponseWriter, r *http.Request) {
	switch r.URL.Path {
	case "/foo":
		fooHandler(w, r)
	case "/bar":
		barHandler(w, r)
	default:
		http.Error(w, "Unsupported path", http.StatusNotFound)
	}
}
// the corresponding fasthttp request handler
requestHandler := func(ctx *fasthttp.RequestCtx) {
	switch string(ctx.Path()) {
	case "/foo":
		fooHandler(ctx)
	case "/bar":
		barHandler(ctx)
	default:
		ctx.Error("Unsupported path", fasthttp.StatusNotFound)
	}
}
  • Fasthttp allows setting response headers and writing response body in arbitray order. There is no 'headers first, then body' restriction like in net/http. The following code is valid for fasthttp:
requestHandler := func(ctx *fasthttp.RequestCtx) {
	// set some headers and status code first
	ctx.SetContentType("foo/bar")
	ctx.SetStatusCode(fasthttp.StatusOK)

	// then write the first part of body
	fmt.Fprintf(ctx, "this is the first part of body\n")

	// then set more headers
	ctx.Response.Header.Set("Foo-Bar", "baz")

	// then write more body
	fmt.Fprintf(ctx, "this is the second part of body\n")

	// then override already written body
	ctx.SetBody([]byte("this is completely new body contents"))

	// then update status code
	ctx.SetStatusCode(fasthttp.StatusNotFound)

	// basically, anything may be updated many times before
	// returning from RequestHandler.
	//
	// Unlike net/http fasthttp doesn't put response to the wire until
	// returning from RequestHandler.
}
  • Fasthttp doesn't provide ServeMux, since I believe third-party request routers like httprouter must be used instead. Net/http code with simple ServeMux is trivially converted to fasthttp code:
// net/http code

m := &http.ServeMux{}
m.HandleFunc("/foo", fooHandlerFunc)
m.HandleFunc("/bar", barHandlerFunc)
m.Handle("/baz", bazHandler)

http.ListenAndServe(":80", m)
// the corresponding fasthttp code
m := func(ctx *fasthttp.RequestCtx) {
	switch string(ctx.Path()) {
	case "/foo":
		fooHandlerFunc(ctx)
	case "/bar":
		barHandlerFunc(ctx)
	case "/baz":
		bazHandler.HandlerFunc(ctx)
	default:
		ctx.Error("not found", fasthttp.StatusNotFound)
	}
}

fastttp.ListenAndServe(":80", m)

Use brilliant tool - race detector - for detecting and eliminating data races in your program. If you detected data race related to fasthttp in your program, then there is high probability you forgot calling TimeoutError before returning from RequestHandler.

  • Blind switching from net/http to fasthttp won't give you performance boost. While fasthttp is optimized for speed, its' performance may be easily saturated by slow RequestHandler. So profile and optimize your code after switching to fasthttp.

Performance optimization tips for multi-core systems

  • Use reuseport listener.
  • Run a separate server instance per CPU core with GOMAXPROCS=1.
  • Pin each server instance to a separate CPU core using taskset.
  • Ensure the interrupts of multiqueue network card are evenly distributed between CPU cores. See this article for details.

Fasthttp best practicies

  • Do not allocate objects and []byte buffers - just reuse them as much as possible. Fasthttp API design encourages this.
  • sync.Pool is your best friend.
  • Profile your program in production. go tool pprof --alloc_objects your-program mem.pprof usually gives better insights for optimization opportunities than go tool pprof your-program cpu.pprof.
  • Write tests and benchmarks for hot paths.
  • Avoid conversion between []byte and string, since this may result in memory allocation+copy. Fasthttp API provides functions for both []byte and string - use these functions instead of converting manually between []byte and string.
  • Verify your tests and production code under race detector on a regular basis.

Tricks with []byte buffers

The following tricks are used by fasthttp. Use them in your code too.

  • Standard Go functions accept nil buffers
var (
	// both buffers are uninitialized
	dst []byte
	src []byte
)
dst = append(dst, src...)  // this is legal code
copy(dst, src)  // this is legal code
(string(src) == "")  // is true
(len(src) == 0)  // is true

So throw away nil checks for []byte buffers from you code. For example,

srcLen := 0
if src != nil {
	srcLen = len(src)
}

becomes

srcLen := len(src)
  • String may be appended to []byte buffer with append
dst = append(dst, "foobar"...)
  • All fasthttp functions accept nil []byte buffer
statusCode, body, err := fasthttp.Get(nil, "http://google.com/")
uintBuf := fasthttp.AppendUint(nil, 1234)

FAQ

  • Why creating yet another http package instead of optimizing net/http?

    Because net/http API limits many optimization opportunities. For example:

    • net/http Request object lifetime isn't limited by request handler execution time. So the server must create new request object per each request instead of reusing existing objects like fasthttp do.
    • net/http headers are stored in a map[string][]string. So the server must parse all the headers, convert them from []byte to string and put them into the map before calling user-provided request handler. This all requires unnesessary memory allocations avoided by fasthttp.
    • net/http client API requires creating new response object per each request.
  • Why fasthttp API is incompatible with net/http?

    Because net/http API limits many optimization opportunities. See the answer above for more details. Also certain net/http API parts are suboptimal for use:

  • Why fasthttp doesn't support HTTP/2.0 and WebSockets?

    There are plans for adding HTTP/2.0 and WebSockets support in the future. In the mean time, third parties may use RequestCtx.Hijack for implementing these goodies.

  • Are there known net/http advantages comparing to fasthttp?

    Yes:

    • net/http supports HTTP/2.0 starting from go1.6.
    • net/http API is stable, while fasthttp API constantly evolves.
    • net/http handles more HTTP corner cases.
    • net/http should contain less bugs, since it is used and tested by much wider audience.
    • Many existing web frameworks and request routers are built on top of net/http.
    • net/http works on Go older than 1.5.
  • Which GO versions are supported by fasthttp?

    Go1.5+. Older versions won't be supported, since their standard package miss useful functions.

  • Please provide real benchmark data and sever information

    See this issue.

  • Are there plans to add request routing to fasthttp?

    There are no plans to add request routing into fasthttp. I believe request routing must be implemented in a separate package(s) like httprouter. See this issue for more info.

  • I detected data race in fasthttp!

    Cool! File a bug. But before doing this check the following in your code:

Documentation

Overview

Package fasthttp provides fast HTTP server and client API.

Fasthttp provides the following features:

  • Optimized for speed. Easily handles more than 100K qps and more than 1M concurrent keep-alive connections on modern hardware.

  • Optimized for low memory usage.

  • Easy 'Connection: Upgrade' support via RequestCtx.Hijack.

  • Server supports requests' pipelining. Multiple requests may be read from a single network packet and multiple responses may be sent in a single network packet. This may be useful for highly loaded REST services.

  • Server provides the following anti-DoS limits:

  • The number of concurrent connections.

  • The number of concurrent connections per client IP.

  • The number of requests per connection.

  • Request read timeout.

  • Response write timeout.

  • Maximum request header size.

  • Maximum request body size.

  • Maximum request execution time.

  • Maximum keep-alive connection lifetime.

  • Early filtering out non-GET requests.

  • A lot of additional useful info is exposed to request handler:

  • Server and client address.

  • Per-request logger.

  • Unique request id.

  • Request start time.

  • Connection start time.

  • Request sequence number for the current connection.

  • Client supports automatic retry on idempotent requests' failure.

  • Fasthttp API is designed with the ability to extend existing client and server implementations or to write custom client and server implementations from scratch.

Index

Examples

Constants

View Source
const (
	StatusContinue           = 100
	StatusSwitchingProtocols = 101

	StatusOK                   = 200
	StatusCreated              = 201
	StatusAccepted             = 202
	StatusNonAuthoritativeInfo = 203
	StatusNoContent            = 204
	StatusResetContent         = 205
	StatusPartialContent       = 206

	StatusMultipleChoices   = 300
	StatusMovedPermanently  = 301
	StatusFound             = 302
	StatusSeeOther          = 303
	StatusNotModified       = 304
	StatusUseProxy          = 305
	StatusTemporaryRedirect = 307

	StatusBadRequest                   = 400
	StatusUnauthorized                 = 401
	StatusPaymentRequired              = 402
	StatusForbidden                    = 403
	StatusNotFound                     = 404
	StatusMethodNotAllowed             = 405
	StatusNotAcceptable                = 406
	StatusProxyAuthRequired            = 407
	StatusRequestTimeout               = 408
	StatusConflict                     = 409
	StatusGone                         = 410
	StatusLengthRequired               = 411
	StatusPreconditionFailed           = 412
	StatusRequestEntityTooLarge        = 413
	StatusRequestURITooLong            = 414
	StatusUnsupportedMediaType         = 415
	StatusRequestedRangeNotSatisfiable = 416
	StatusExpectationFailed            = 417
	StatusTeapot                       = 418

	StatusInternalServerError     = 500
	StatusNotImplemented          = 501
	StatusBadGateway              = 502
	StatusServiceUnavailable      = 503
	StatusGatewayTimeout          = 504
	StatusHTTPVersionNotSupported = 505
)

HTTP status codes were stolen from net/http.

View Source
const DefaultConcurrency = 256 * 1024

Default maximum number of concurrent connections the Server may serve.

View Source
const DefaultMaxConnsPerHost = 100

Maximum number of concurrent connections http client may establish per host by default.

View Source
const FSHandlerCacheDuration = 5 * time.Second

FSHandlerCacheDuration is the duration for caching open file handles by FSHandler.

Variables

View Source
var (
	// ErrNoFreeConns is returned when no free connections available
	// to the given host.
	ErrNoFreeConns = errors.New("no free connections available to host")

	// ErrTimeout is returned from timed out calls.
	ErrTimeout = errors.New("timeout")
)
View Source
var (
	// CookieExpireDelete may be set on Cookie.Expire for expiring the given cookie.
	CookieExpireDelete = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)

	// CookieExpireUnlimited indicates that the cookie doesn't expire.
	CookieExpireUnlimited = zeroTime
)
View Source
var (
	// ErrPerIPConnLimit may be returned from ServeConn if the number of connections
	// per ip exceeds Server.MaxConnsPerIP.
	ErrPerIPConnLimit = errors.New("too many connections per ip")

	// ErrConcurrencyLimit may be returned from ServeConn if the number
	// of concurrenty served connections exceeds Server.Concurrency.
	ErrConcurrencyLimit = errors.New("canot serve the connection because Server.Concurrency concurrent connections are served")

	// ErrKeepaliveTimeout is returned from ServeConn
	// if the connection lifetime exceeds MaxKeepaliveDuration.
	ErrKeepaliveTimeout = errors.New("MaxKeepaliveDuration exceeded")
)
View Source
var ErrBodyTooLarge = errors.New("body size exceeds the given limit")

ErrBodyTooLarge is returned if either request or response body exceeds the given limit.

View Source
var ErrNoArgValue = errors.New("no Args value for the given key")

ErrNoArgValue is returned when Args value with the given key is missing.

View Source
var ErrNoMultipartForm = errors.New("request has no multipart/form-data Content-Type")

ErrNoMultipartForm means that the request's Content-Type isn't 'multipart/form-data'.

Functions

func AppendBytesStr

func AppendBytesStr(dst []byte, src string) []byte

AppendBytesStr appends src to dst and returns dst (which may be newly allocated).

This function has no performance benefits comparing to append(dst, src...). It is left here for backwards compatibility only.

func AppendHTTPDate

func AppendHTTPDate(dst []byte, date time.Time) []byte

AppendHTTPDate appends HTTP-compliant (RFC1123) representation of date to dst and returns dst (which may be newly allocated).

func AppendUint

func AppendUint(dst []byte, n int) []byte

AppendUint appends n to dst and returns dst (which may be newly allocated).

func Do

func Do(req *Request, resp *Response) error

Do performs the given http request and fills the given http response.

Request must contain at least non-zero RequestURI with full url (including scheme and host) or non-zero Host header + RequestURI.

Response is ignored if resp is nil.

Client determines the server to be requested in the following order:

  • from RequestURI if it contains full url with scheme and host;
  • from Host header otherwise.

ErrNoFreeConns is returned if all Client.MaxConnsPerHost connections to the requested host are busy.

func DoTimeout

func DoTimeout(req *Request, resp *Response, timeout time.Duration) error

DoTimeout performs the given request and waits for response during the given timeout duration.

Request must contain at least non-zero RequestURI with full url (including scheme and host) or non-zero Host header + RequestURI.

Client determines the server to be requested in the following order:

  • from RequestURI if it contains full url with scheme and host;
  • from Host header otherwise.

ErrTimeout is returned if the response wasn't returned during the given timeout.

func EqualBytesStr

func EqualBytesStr(b []byte, s string) bool

EqualBytesStr returns true if string(b) == s.

This function has no performance benefits comparing to string(b) == s. It is left here for backwards compatibility only.

func Get

func Get(dst []byte, url string) (statusCode int, body []byte, err error)

Get appends url contents to dst and returns it as body.

New body buffer is allocated if dst is nil.

func GetTimeout

func GetTimeout(dst []byte, url string, timeout time.Duration) (statusCode int, body []byte, err error)

GetTimeout appends url contents to dst and returns it as body.

New body buffer is allocated if dst is nil.

ErrTimeout error is returned if url contents couldn't be fetched during the given timeout.

func ListenAndServe

func ListenAndServe(addr string, handler RequestHandler) error

ListenAndServe serves HTTP requests from the given TCP addr using the given handler.

Example
// The server will listen for incoming requests on this address.
listenAddr := "127.0.0.1:80"

// This function will be called by the server for each incoming request.
//
// RequestCtx provides a lot of functionality related to http request
// processing. See RequestCtx docs for details.
requestHandler := func(ctx *RequestCtx) {
	fmt.Fprintf(ctx, "Hello, world! Requested path is %q", ctx.Path())
}

// Start the server with default settings.
// Create Server instance for adjusting server settings.
//
// ListenAndServe returns only on error, so usually it blocks forever.
if err := ListenAndServe(listenAddr, requestHandler); err != nil {
	log.Fatalf("error in ListenAndServe: %s", err)
}
Output:

func ListenAndServeTLS

func ListenAndServeTLS(addr, certFile, keyFile string, handler RequestHandler) error

ListenAndServeTLS serves HTTPS requests from the given TCP addr using the given handler.

certFile and keyFile are paths to TLS certificate and key files.

func ParseUfloat

func ParseUfloat(buf []byte) (float64, error)

ParseUfloat parses unsigned float from buf.

func ParseUint

func ParseUint(buf []byte) (int, error)

ParseUint parses uint from buf.

func Post

func Post(dst []byte, url string, postArgs *Args) (statusCode int, body []byte, err error)

Post sends POST request to the given url with the given POST arguments.

Response body is appended to dst, which is returned as body.

New body buffer is allocated if dst is nil.

Empty POST body is sent if postArgs is nil.

func Serve

func Serve(ln net.Listener, handler RequestHandler) error

Serve serves incoming connections from the given listener using the given handler.

Serve blocks until the given listener returns permanent error.

Example
// Create network listener for accepting incoming requests.
//
// Note that you are not limited by TCP listener - arbitrary
// net.Listener may be used by the server.
// For example, unix socket listener or TLS listener.
ln, err := net.Listen("tcp4", "127.0.0.1:8080")
if err != nil {
	log.Fatalf("error in net.Listen: %s", err)
}

// This function will be called by the server for each incoming request.
//
// RequestCtx provides a lot of functionality related to http request
// processing. See RequestCtx docs for details.
requestHandler := func(ctx *RequestCtx) {
	fmt.Fprintf(ctx, "Hello, world! Requested path is %q", ctx.Path())
}

// Start the server with default settings.
// Create Server instance for adjusting server settings.
//
// Serve returns on ln.Close() or error, so usually it blocks forever.
if err := Serve(ln, requestHandler); err != nil {
	log.Fatalf("error in Serve: %s", err)
}
Output:

func ServeConn

func ServeConn(c net.Conn, handler RequestHandler) error

ServeConn serves HTTP requests from the given connection using the given handler.

ServeConn returns nil if all requests from the c are successfully served. It returns non-nil error otherwise.

Connection c must immediately propagate all the data passed to Write() to the client. Otherwise requests' processing may hang.

ServeConn closes c before returning.

func StatusMessage

func StatusMessage(statusCode int) string

StatusMessage returns HTTP status message for the given status code.

Types

type Args

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

Args represents query arguments.

It is forbidden copying Args instances. Create new instances instead and use CopyTo().

It is unsafe modifying/reading Args instance from concurrently running goroutines.

func (*Args) AppendBytes

func (a *Args) AppendBytes(dst []byte) []byte

AppendBytes appends query string to dst and returns dst (which may be newly allocated).

func (*Args) CopyTo

func (a *Args) CopyTo(dst *Args)

CopyTo copies all args to dst.

func (*Args) Del

func (a *Args) Del(key string)

Del deletes argument with the given key from query args.

func (*Args) DelBytes

func (a *Args) DelBytes(key []byte)

DelBytes deletes argument with the given key from query args.

func (*Args) GetUfloat

func (a *Args) GetUfloat(key string) (float64, error)

GetUfloat returns ufloat value for the given key.

func (*Args) GetUfloatOrZero

func (a *Args) GetUfloatOrZero(key string) float64

GetUfloatOrZero returns ufloat value for the given key.

Zero (0) is returned on error.

func (*Args) GetUint

func (a *Args) GetUint(key string) (int, error)

GetUint returns uint value for the given key.

func (*Args) GetUintOrZero

func (a *Args) GetUintOrZero(key string) int

GetUintOrZero returns uint value for the given key.

Zero (0) is returned on error.

func (*Args) Has

func (a *Args) Has(key string) bool

Has returns true if the given key exists in Args.

func (*Args) HasBytes

func (a *Args) HasBytes(key []byte) bool

HasBytes returns true if the given key exists in Args.

func (*Args) Len

func (a *Args) Len() int

Len returns the number of query args.

func (*Args) Parse

func (a *Args) Parse(s string)

Parse parses the given string containing query args.

func (*Args) ParseBytes

func (a *Args) ParseBytes(b []byte)

ParseBytes parses the given b containing query args.

func (*Args) Peek

func (a *Args) Peek(key string) []byte

Peek returns query arg value for the given key.

Returned value is valid until the next Args call.

func (*Args) PeekBytes

func (a *Args) PeekBytes(key []byte) []byte

PeekBytes returns query arg value for the given key.

Returned value is valid until the next Args call.

func (*Args) QueryString

func (a *Args) QueryString() []byte

QueryString returns query string for the args.

The returned value is valid until the next call to Args methods.

func (*Args) Reset

func (a *Args) Reset()

Reset clears query args.

func (*Args) Set

func (a *Args) Set(key, value string)

Set sets 'key=value' argument.

func (*Args) SetBytesK

func (a *Args) SetBytesK(key []byte, value string)

SetBytesK sets 'key=value' argument.

func (*Args) SetBytesKV

func (a *Args) SetBytesKV(key, value []byte)

SetBytesKV sets 'key=value' argument.

func (*Args) SetBytesV

func (a *Args) SetBytesV(key string, value []byte)

SetBytesV sets 'key=value' argument.

func (*Args) SetUint

func (a *Args) SetUint(key string, value int)

SetUint sets uint value for the given key.

func (*Args) SetUintBytes

func (a *Args) SetUintBytes(key []byte, value int)

SetUintBytes sets uint value for the given key.

func (*Args) String

func (a *Args) String() string

String returns string representation of query args.

func (*Args) VisitAll

func (a *Args) VisitAll(f func(key, value []byte))

VisitAll calls f for each existing arg.

f must not retain references to key and value after returning. Make key and/or value copies if you need storing them after returning.

func (*Args) WriteTo

func (a *Args) WriteTo(w io.Writer) (int64, error)

WriteTo writes query string to w.

WriteTo implements io.WriterTo interface.

type Client

type Client struct {
	// Client name. Used in User-Agent request header.
	//
	// Default client name is used if not set.
	Name string

	// Callback for establishing new connections to hosts.
	//
	// Default TCP dialer is used if not set.
	Dial DialFunc

	// Attempt to connect to both ipv4 and ipv6 addresses if set to true.
	//
	// This option is used only if default TCP dialer is used,
	// i.e. if Dial is blank.
	//
	// By default client connects only to ipv4 addresses,
	// since unfortunately ipv6 remains broken in many networks worldwide :)
	DialDualStack bool

	// TLS config for https connections.
	//
	// Default TLS config is used if not set.
	TLSConfig *tls.Config

	// Maximum number of connections per each host which may be established.
	//
	// DefaultMaxConnsPerHost is used if not set.
	MaxConnsPerHost int

	// Per-connection buffer size for responses' reading.
	// This also limits the maximum header size.
	//
	// Default buffer size is used if 0.
	ReadBufferSize int

	// Per-connection buffer size for requests' writing.
	//
	// Default buffer size is used if 0.
	WriteBufferSize int

	// Maximum duration for full response reading (including body).
	//
	// By default response read timeout is unlimited.
	ReadTimeout time.Duration

	// Maximum duration for full request writing (including body).
	//
	// By default request write timeout is unlimited.
	WriteTimeout time.Duration

	// Maximum response body size.
	//
	// The client returns ErrBodyTooLarge if this limit is greater than 0
	// and response body is greater than the limit.
	//
	// By default response body size is unlimited.
	MaxResponseBodySize int
	// contains filtered or unexported fields
}

Client implements http client.

Copying Client by value is prohibited. Create new instance instead.

It is safe calling Client methods from concurrently running goroutines.

func (*Client) Do

func (c *Client) Do(req *Request, resp *Response) error

Do performs the given http request and fills the given http response.

Request must contain at least non-zero RequestURI with full url (including scheme and host) or non-zero Host header + RequestURI.

Response is ignored if resp is nil.

Client determines the server to be requested in the following order:

  • from RequestURI if it contains full url with scheme and host;
  • from Host header otherwise.

ErrNoFreeConns is returned if all Client.MaxConnsPerHost connections to the requested host are busy.

func (*Client) DoTimeout

func (c *Client) DoTimeout(req *Request, resp *Response, timeout time.Duration) error

DoTimeout performs the given request and waits for response during the given timeout duration.

Request must contain at least non-zero RequestURI with full url (including scheme and host) or non-zero Host header + RequestURI.

Client determines the server to be requested in the following order:

  • from RequestURI if it contains full url with scheme and host;
  • from Host header otherwise.

ErrTimeout is returned if the response wasn't returned during the given timeout.

func (*Client) Get

func (c *Client) Get(dst []byte, url string) (statusCode int, body []byte, err error)

Get appends url contents to dst and returns it as body.

New body buffer is allocated if dst is nil.

func (*Client) GetTimeout

func (c *Client) GetTimeout(dst []byte, url string, timeout time.Duration) (statusCode int, body []byte, err error)

GetTimeout appends url contents to dst and returns it as body.

New body buffer is allocated if dst is nil.

ErrTimeout error is returned if url contents couldn't be fetched during the given timeout.

func (*Client) Post

func (c *Client) Post(dst []byte, url string, postArgs *Args) (statusCode int, body []byte, err error)

Post sends POST request to the given url with the given POST arguments.

Response body is appended to dst, which is returned as body.

New body buffer is allocated if dst is nil.

Empty POST body is sent if postArgs is nil.

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

Cookie represents HTTP response cookie.

Do not copy Cookie obects. Create new obect and use CopyTo instead.

It is unsafe modifying/reading Cookie instance from concurrently running goroutines.

func (*Cookie) AppendBytes

func (c *Cookie) AppendBytes(dst []byte) []byte

AppendBytes appends cookie representation to dst and returns dst (maybe newly allocated).

func (*Cookie) Cookie

func (c *Cookie) Cookie() []byte

Cookie returns cookie representation.

The returned value is valid until the next call to Cookie methods.

func (*Cookie) CopyTo

func (c *Cookie) CopyTo(src *Cookie)

CopyTo copies src cookie to c.

func (*Cookie) Domain

func (c *Cookie) Domain() []byte

Domain returns cookie domain.

The returned domain is valid until the next Cookie modification method call.

func (*Cookie) Expire

func (c *Cookie) Expire() time.Time

Expire returns cookie expiration time.

CookieExpireUnlimited is returned if cookie doesn't expire

func (*Cookie) Key

func (c *Cookie) Key() []byte

Key returns cookie name.

The returned value is valid until the next Cookie modification method call.

func (*Cookie) Parse

func (c *Cookie) Parse(src string) error

Parse parses Set-Cookie header.

func (*Cookie) ParseBytes

func (c *Cookie) ParseBytes(src []byte) error

ParseBytes parses Set-Cookie header.

func (*Cookie) Path

func (c *Cookie) Path() []byte

Path returns cookie path.

func (*Cookie) Reset

func (c *Cookie) Reset()

Reset clears the cookie.

func (*Cookie) SetDomain

func (c *Cookie) SetDomain(domain string)

SetDomain sets cookie domain.

func (*Cookie) SetDomainBytes

func (c *Cookie) SetDomainBytes(domain []byte)

SetDomain

func (*Cookie) SetExpire

func (c *Cookie) SetExpire(expire time.Time)

SetExpire sets cookie expiration time.

Set expiration time to CookieExpireDelete for expiring (deleting) the cookie on the client.

By default cookie lifetime is limited by browser session.

func (*Cookie) SetKey

func (c *Cookie) SetKey(key string)

SetKey sets cookie name.

func (*Cookie) SetKeyBytes

func (c *Cookie) SetKeyBytes(key []byte)

SetKeyBytes sets cookie name.

func (*Cookie) SetPath

func (c *Cookie) SetPath(path string)

SetPath sets cookie path.

func (*Cookie) SetPathBytes

func (c *Cookie) SetPathBytes(path []byte)

SetPathBytes sets cookie path.

func (*Cookie) SetValue

func (c *Cookie) SetValue(value string)

SetValue sets cookie value.

func (*Cookie) SetValueBytes

func (c *Cookie) SetValueBytes(value []byte)

SetValueBytes sets cookie value.

func (*Cookie) String

func (c *Cookie) String() string

String returns cookie representation.

func (*Cookie) Value

func (c *Cookie) Value() []byte

Value returns cookie value.

The returned value is valid until the next Cookie modification method call.

func (*Cookie) WriteTo

func (c *Cookie) WriteTo(w io.Writer) (int64, error)

WriteTo writes cookie representation to w.

WriteTo implements io.WriterTo interface.

type DialFunc

type DialFunc func(addr string) (net.Conn, error)

DialFunc must establish connection to addr.

There is no need in establishing TLS (SSL) connection for https. The client automatically converts connection to TLS if HostClient.IsTLS is set.

TCP address passed to DialFunc always contains host and port. Example TCP addr values:

  • foobar.com:80
  • foobar.com:443
  • foobar.com:8080

type HijackHandler

type HijackHandler func(c net.Conn)

HijackHandler must process the hijacked connection c.

The connection c is automatically closed after returning from HijackHandler.

type HostClient

type HostClient struct {
	// HTTP server host address, which is passed to Dial.
	//
	// The address may contain port if default dialer is used.
	// For example,
	//
	//    - foobar.com:80
	//    - foobar.com:443
	//    - foobar.com:8080
	Addr string

	// Client name. Used in User-Agent request header.
	Name string

	// Callback for establishing new connection to the host.
	//
	// Default TCP dialer is used if not set.
	Dial DialFunc

	// Attempt to connect to both ipv4 and ipv6 host addresses
	// if set to true.
	//
	// This option is used only if default TCP dialer is used,
	// i.e. if Dial is blank.
	//
	// By default client connects only to ipv4 addresses,
	// since unfortunately ipv6 remains broken in many networks worldwide :)
	DialDualStack bool

	// Whether to use TLS (aka SSL or HTTPS) for host connections.
	IsTLS bool

	// Optional TLS config.
	TLSConfig *tls.Config

	// Maximum number of connections to the host which may be established.
	//
	// DefaultMaxConnsPerHost is used if not set.
	MaxConns int

	// Per-connection buffer size for responses' reading.
	// This also limits the maximum header size.
	//
	// Default buffer size is used if 0.
	ReadBufferSize int

	// Per-connection buffer size for requests' writing.
	//
	// Default buffer size is used if 0.
	WriteBufferSize int

	// Maximum duration for full response reading (including body).
	//
	// By default response read timeout is unlimited.
	ReadTimeout time.Duration

	// Maximum duration for full request writing (including body).
	//
	// By default request write timeout is unlimited.
	WriteTimeout time.Duration

	// Maximum response body size.
	//
	// The client returns ErrBodyTooLarge if this limit is greater than 0
	// and response body is greater than the limit.
	//
	// By default response body size is unlimited.
	MaxResponseBodySize int
	// contains filtered or unexported fields
}

HostClient is a single-host http client. It can make http requests to the given Addr only.

It is forbidden copying HostClient instances. Create new instances instead.

It is safe calling HostClient methods from concurrently running goroutines.

func (*HostClient) Do

func (c *HostClient) Do(req *Request, resp *Response) error

Do performs the given http request and sets the corresponding response.

Request must contain at least non-zero RequestURI with full url (including scheme and host) or non-zero Host header + RequestURI.

Response is ignored if resp is nil.

ErrNoFreeConns is returned if all HostClient.MaxConns connections to the host are busy.

func (*HostClient) DoTimeout

func (c *HostClient) DoTimeout(req *Request, resp *Response, timeout time.Duration) error

DoTimeout performs the given request and waits for response during the given timeout duration.

Request must contain at least non-zero RequestURI with full url (including scheme and host) or non-zero Host header + RequestURI.

ErrTimeout is returned if the response wasn't returned during the given timeout.

func (*HostClient) Get

func (c *HostClient) Get(dst []byte, url string) (statusCode int, body []byte, err error)

Get appends url contents to dst and returns it as body.

New body buffer is allocated if dst is nil.

func (*HostClient) GetTimeout

func (c *HostClient) GetTimeout(dst []byte, url string, timeout time.Duration) (statusCode int, body []byte, err error)

GetTimeout appends url contents to dst and returns it as body.

New body buffer is allocated if dst is nil.

ErrTimeout error is returned if url contents couldn't be fetched during the given timeout.

func (*HostClient) LastUseTime

func (c *HostClient) LastUseTime() time.Time

LastUseTime returns time the client was last used

func (*HostClient) Post

func (c *HostClient) Post(dst []byte, url string, postArgs *Args) (statusCode int, body []byte, err error)

Post sends POST request to the given url with the given POST arguments.

Response body is appended to dst, which is returned as body.

New body buffer is allocated if dst is nil.

Empty POST body is sent if postArgs is nil.

type Logger

type Logger interface {
	// Printf must have the same semantics as log.Printf.
	Printf(format string, args ...interface{})
}

Logger is used for logging formatted messages.

type Request

type Request struct {
	// Request header
	//
	// Copying Header by value is forbidden. Use pointer to Header instead.
	Header RequestHeader
	// contains filtered or unexported fields
}

Request represents HTTP request.

It is forbidden copying Request instances. Create new instances and use CopyTo() instead.

It is unsafe modifying/reading Request instance from concurrently running goroutines.

func (*Request) Body

func (req *Request) Body() []byte

Body returns request body.

func (*Request) BodyWriter

func (req *Request) BodyWriter() io.Writer

BodyWriter returns writer for populating request body.

func (*Request) ConnectionClose

func (req *Request) ConnectionClose() bool

ConnectionClose returns true if 'Connection: close' header is set.

func (*Request) CopyTo

func (req *Request) CopyTo(dst *Request)

CopyTo copies req contents to dst.

func (*Request) MultipartForm

func (req *Request) MultipartForm() (*multipart.Form, error)

MultipartForm returns requests's multipart form.

Returns ErrNoMultipartForm if request's content-type isn't 'multipart/form-data'.

func (*Request) PostArgs

func (req *Request) PostArgs() *Args

PostArgs returns POST arguments.

func (*Request) Read

func (req *Request) Read(r *bufio.Reader) error

Read reads request (including body) from the given r.

RemoveMultipartFormFiles or Reset must be called after reading multipart/form-data request in order to delete temporarily uploaded files.

func (*Request) ReadLimitBody

func (req *Request) ReadLimitBody(r *bufio.Reader, maxBodySize int) error

ReadLimitBody reads request from the given r, limiting the body size.

If maxBodySize > 0 and the body size exceeds maxBodySize, then ErrBodyTooLarge is returned.

RemoveMultipartFormFiles or Reset must be called after reading multipart/form-data request in order to delete temporarily uploaded files.

func (*Request) RemoveMultipartFormFiles

func (req *Request) RemoveMultipartFormFiles()

RemoveMultipartFormFiles removes multipart/form-data temporary files associated with the request.

func (*Request) Reset

func (req *Request) Reset()

Reset clears request contents.

func (*Request) ResetBody

func (req *Request) ResetBody()

ResetBody resets request body.

func (*Request) SetBody

func (req *Request) SetBody(body []byte)

SetBody sets request body.

func (*Request) SetConnectionClose

func (req *Request) SetConnectionClose()

SetConnectionClose sets 'Connection: close' header.

func (*Request) SetRequestURI

func (req *Request) SetRequestURI(requestURI string)

SetRequestURI sets RequestURI.

func (*Request) SetRequestURIBytes

func (req *Request) SetRequestURIBytes(requestURI []byte)

SetRequestURIBytes sets RequestURI.

func (*Request) String

func (req *Request) String() string

String returns request representation.

Returns error message instead of request representation on error.

Use Write instead of String for performance-critical code.

func (*Request) URI

func (req *Request) URI() *URI

URI returns request URI

func (*Request) Write

func (req *Request) Write(w *bufio.Writer) error

Write writes request to w.

Write doesn't flush request to w for performance reasons.

type RequestCtx

type RequestCtx struct {
	// Incoming request.
	//
	// Copying Request by value is forbidden. Use pointer to Request instead.
	Request Request

	// Outgoing response.
	//
	// Copying Response by value is forbidden. Use pointer to Response instead.
	Response Response
	// contains filtered or unexported fields
}

RequestCtx contains incoming request and manages outgoing response.

It is forbidden copying RequestCtx instances.

RequestHandler should avoid holding references to incoming RequestCtx and/or its' members after the return. If holding RequestCtx references after the return is unavoidable (for instance, ctx is passed to a separate goroutine and ctx lifetime cannot be controlled), then the RequestHandler MUST call ctx.TimeoutError() before return.

It is unsafe modifying/reading RequestCtx instance from concurrently running goroutines. The only exception is TimeoutError, which may be called when other goroutines access RequestCtx.

func (*RequestCtx) ConnRequestNum

func (ctx *RequestCtx) ConnRequestNum() uint64

ConnRequestNum returns request sequence number for the current connection.

func (*RequestCtx) ConnTime

func (ctx *RequestCtx) ConnTime() time.Time

ConnTime returns the time server starts serving the connection the current request came from.

func (*RequestCtx) Error

func (ctx *RequestCtx) Error(msg string, statusCode int)

Error sets response status code to the given value and sets response body to the given message.

func (*RequestCtx) Hijack

func (ctx *RequestCtx) Hijack(handler HijackHandler)

Hijack registers the given handler for connection hijacking.

The handler is called after returning from RequestHandler and sending http response. The current connection is passed to the handler. The connection is automatically closed after returning from the handler.

The server skips calling the handler in the following cases:

  • 'Connection: close' header exists in either request or response.
  • Unexpected error during response writing to the connection.

The server stops processing requests from hijacked connections. Server limits such as Concurrency, ReadTimeout, WriteTimeout, etc. aren't applied to hijacked connections.

The handler must not retain references to ctx members.

Arbitrary 'Connection: Upgrade' protocols may be implemented with HijackHandler. For instance,

Example
// hijackHandler is called on hijacked connection.
hijackHandler := func(c net.Conn) {
	fmt.Fprintf(c, "This message is sent over a hijacked connection to the client %s\n", c.RemoteAddr())
	fmt.Fprintf(c, "Send me something and I'll echo it to you\n")
	var buf [1]byte
	for {
		if _, err := c.Read(buf[:]); err != nil {
			log.Printf("error when reading from hijacked connection: %s", err)
			return
		}
		fmt.Fprintf(c, "You sent me %q. Waiting for new data\n", buf[:])
	}
}

// requestHandler is called for each incoming request.
requestHandler := func(ctx *RequestCtx) {
	path := ctx.Path()
	switch {
	case string(path) == "/hijack":
		// Note that the connection is hijacked only after
		// returning from requestHandler and sending http response.
		ctx.Hijack(hijackHandler)

		// The connection will be hijacked after sending this response.
		fmt.Fprintf(ctx, "Hijacked the connection!")
	case string(path) == "/":
		fmt.Fprintf(ctx, "Root directory requested")
	default:
		fmt.Fprintf(ctx, "Requested path is %q", path)
	}
}

if err := ListenAndServe(":80", requestHandler); err != nil {
	log.Fatalf("error in ListenAndServe: %s", err)
}
Output:

func (*RequestCtx) Host

func (ctx *RequestCtx) Host() []byte

Host returns requested host.

The host is valid until returning from RequestHandler.

func (*RequestCtx) ID

func (ctx *RequestCtx) ID() uint64

ID returns unique ID of the request.

func (*RequestCtx) Init

func (ctx *RequestCtx) Init(req *Request, remoteAddr net.Addr, logger Logger)

Init prepares ctx for passing to RequestHandler.

remoteAddr and logger are optional. They are used by RequestCtx.Logger().

This function is intended for custom Server implementations.

func (*RequestCtx) IsGet

func (ctx *RequestCtx) IsGet() bool

IsGet returns true if request method is GET.

func (*RequestCtx) IsHead

func (ctx *RequestCtx) IsHead() bool

IsHead returns true if request method is HEAD.

func (*RequestCtx) IsPost

func (ctx *RequestCtx) IsPost() bool

IsPost returns true if request method is POST.

func (*RequestCtx) IsPut

func (ctx *RequestCtx) IsPut() bool

IsPut returns true if request method is PUT.

func (*RequestCtx) IsTLS

func (ctx *RequestCtx) IsTLS() bool

IsTLS returns true if the underlying connection is tls.Conn.

tls.Conn is an encrypted connection (aka SSL, HTTPS).

func (*RequestCtx) LocalAddr

func (ctx *RequestCtx) LocalAddr() net.Addr

LocalAddr returns server address for the given request.

Always returns non-nil result.

func (*RequestCtx) Logger

func (ctx *RequestCtx) Logger() Logger

Logger returns logger, which may be used for logging arbitrary request-specific messages inside RequestHandler.

Each message logged via returned logger contains request-specific information such as request id, request duration, local address, remote address, request method and request url.

It is safe re-using returned logger for logging multiple messages for the current request.

The returned logger is valid until returning from RequestHandler.

Example
requestHandler := func(ctx *RequestCtx) {
	if string(ctx.Path()) == "/top-secret" {
		ctx.Logger().Printf("Alarm! Alien intrusion detected!")
		ctx.Error("Access denied!", StatusForbidden)
		return
	}

	// Logger may be cached in local variables.
	logger := ctx.Logger()

	logger.Printf("Good request from User-Agent %q", ctx.Request.Header.UserAgent())
	fmt.Fprintf(ctx, "Good request to %q", ctx.Path())
	logger.Printf("Multiple log messages may be written during a single request")
}

if err := ListenAndServe(":80", requestHandler); err != nil {
	log.Fatalf("error in ListenAndServe: %s", err)
}
Output:

func (*RequestCtx) Method

func (ctx *RequestCtx) Method() []byte

Method return request method.

Returned value is valid until returning from RequestHandler.

func (*RequestCtx) MultipartForm

func (ctx *RequestCtx) MultipartForm() (*multipart.Form, error)

MultipartForm returns requests's multipart form.

Returns ErrNoMultipartForm if request's content-type isn't 'multipart/form-data'.

All uploaded temporary files are automatically deleted after returning from RequestHandler. Either move or copy uploaded files into new place if you want retaining them.

Returned form is valid until returning from RequestHandler.

func (*RequestCtx) Path

func (ctx *RequestCtx) Path() []byte

Path returns requested path.

The path is valid until returning from RequestHandler.

func (*RequestCtx) PostArgs

func (ctx *RequestCtx) PostArgs() *Args

PostArgs returns POST arguments.

It doesn't return query arguments from RequestURI - use QueryArgs for this.

Returned arguments are valid until returning from RequestHandler.

func (*RequestCtx) PostBody

func (ctx *RequestCtx) PostBody() []byte

PostBody returns POST request body.

The returned value is valid until RequestHandler return.

func (*RequestCtx) QueryArgs

func (ctx *RequestCtx) QueryArgs() *Args

QueryArgs returns query arguments from RequestURI.

It doesn't return POST'ed arguments - use PostArge() for this.

Returned arguments are valid until returning from RequestHandler.

func (*RequestCtx) Redirect

func (ctx *RequestCtx) Redirect(uri string, statusCode int)

Redirect sets 'Location: uri' response header and sets the given statusCode.

statusCode must have one of the following values:

  • StatusMovedPermanently (301)
  • StatusFound (302)
  • StatusSeeOther (303)

All other statusCode values are replaced by StatusFound (302).

The redirect uri may be either absolute or relative to the current request uri.

func (*RequestCtx) RedirectBytes

func (ctx *RequestCtx) RedirectBytes(uri []byte, statusCode int)

Redirect sets 'Location: uri' response header and sets the given statusCode.

statusCode must have one of the following values:

  • StatusMovedPermanently (301)
  • StatusFound (302)
  • StatusSeeOther (303)

All other statusCode values are replaced by StatusFound (302).

The redirect uri may be either absolute or relative to the current request uri.

func (*RequestCtx) Referer

func (ctx *RequestCtx) Referer() []byte

Referer returns request referer.

The referer is valid until returning from RequestHandler.

func (*RequestCtx) RemoteAddr

func (ctx *RequestCtx) RemoteAddr() net.Addr

RemoteAddr returns client address for the given request.

Always returns non-nil result.

func (*RequestCtx) RemoteIP

func (ctx *RequestCtx) RemoteIP() net.IP

RemoteIP returns client ip for the given request.

Always returns non-nil result.

func (*RequestCtx) RequestURI

func (ctx *RequestCtx) RequestURI() []byte

RequestURI returns RequestURI.

This uri is valid until returning from RequestHandler.

func (*RequestCtx) ResetBody

func (ctx *RequestCtx) ResetBody()

ResetBody resets response body contents.

func (*RequestCtx) SetBody

func (ctx *RequestCtx) SetBody(body []byte)

SetBody sets response body to the given value.

func (*RequestCtx) SetBodyStream

func (ctx *RequestCtx) SetBodyStream(bodyStream io.Reader, bodySize int)

SetBodyStream sets response body stream and, optionally body size.

bodyStream.Close() will be called after finishing reading all body data if it implements io.Closer.

If bodySize is >= 0, then bodySize bytes are read from bodyStream and used as response body.

If bodySize < 0, then bodyStream is read until io.EOF.

func (*RequestCtx) SetConnectionClose

func (ctx *RequestCtx) SetConnectionClose()

SetConnectionClose sets 'Connection: close' response header and closes connection after the RequestHandler returns.

func (*RequestCtx) SetContentType

func (ctx *RequestCtx) SetContentType(contentType string)

SetContentType sets response Content-Type.

func (*RequestCtx) SetContentTypeBytes

func (ctx *RequestCtx) SetContentTypeBytes(contentType []byte)

SetContentTypeBytes sets response Content-Type.

It is safe modifying contentType buffer after function return.

func (*RequestCtx) SetStatusCode

func (ctx *RequestCtx) SetStatusCode(statusCode int)

SetStatusCode sets response status code.

func (*RequestCtx) SetUserValue

func (ctx *RequestCtx) SetUserValue(key string, value interface{})

SetUserValue stores the given value (arbitrary object) under the given key in ctx.

The value stored in ctx may be obtained by UserValue().

This functionality may be useful for passing arbitrary values between functions involved in request processing.

All the values stored in ctx are deleted after returning from RequestHandler.

func (*RequestCtx) Success

func (ctx *RequestCtx) Success(contentType string, body []byte)

Success sets response Content-Type and body to the given values.

func (*RequestCtx) Time

func (ctx *RequestCtx) Time() time.Time

Time returns RequestHandler call time.

func (*RequestCtx) TimeoutErrMsg

func (ctx *RequestCtx) TimeoutErrMsg() string

TimeoutErrMsg returns last error message set via TimeoutError call.

This function is intended for custom server implementations.

func (*RequestCtx) TimeoutError

func (ctx *RequestCtx) TimeoutError(msg string)

TimeoutError sets response status code to StatusRequestTimeout and sets body to the given msg.

All response modifications after TimeoutError call are ignored.

TimeoutError MUST be called before returning from RequestHandler if there are references to ctx and/or its members in other goroutines.

Example
requestHandler := func(ctx *RequestCtx) {
	// Emulate long-running task, which touches ctx.
	doneCh := make(chan struct{})
	go func() {
		workDuration := time.Millisecond * time.Duration(rand.Intn(2000))
		time.Sleep(workDuration)

		fmt.Fprintf(ctx, "ctx has been accessed by long-running task\n")
		fmt.Fprintf(ctx, "The reuqestHandler may be finished by this time.\n")

		close(doneCh)
	}()

	select {
	case <-doneCh:
		fmt.Fprintf(ctx, "The task has been finished in less than a second")
	case <-time.After(time.Second):
		// Since the long-running task is still running and may access ctx,
		// we must call TimeoutError before returning from requestHandler.
		//
		// Otherwise the program will suffer from data races.
		ctx.TimeoutError("Timeout!")
	}
}

if err := ListenAndServe(":80", requestHandler); err != nil {
	log.Fatalf("error in ListenAndServe: %s", err)
}
Output:

func (*RequestCtx) URI

func (ctx *RequestCtx) URI() *URI

URI returns requested uri.

The uri is valid until returning from RequestHandler.

func (*RequestCtx) UserValue

func (ctx *RequestCtx) UserValue(key string) interface{}

UserValue returns the value stored via SetUserValue under the given key.

func (*RequestCtx) Write

func (ctx *RequestCtx) Write(p []byte) (int, error)

Write writes p into response body.

type RequestHandler

type RequestHandler func(ctx *RequestCtx)

RequestHandler must process incoming requests.

RequestHandler must call ctx.TimeoutError() before returning if it keeps references to ctx and/or its' members after the return. Consider wrapping RequestHandler into TimeoutHandler if response time must be limited.

func FSHandler

func FSHandler(root string, stripSlashes int) RequestHandler

FSHandler returns request handler serving static files from the given root folder.

stripSlashes indicates how many leading slashes must be stripped from requested path before searching requested file in the root folder. Examples:

  • stripSlashes = 0, original path: "/foo/bar", result: "/foo/bar"
  • stripSlashes = 1, original path: "/foo/bar", result: "/bar"
  • stripSlashes = 2, original path: "/foo/bar", result: ""

FSHandler caches requested file handles for FSHandlerCacheDuration. Make sure your program has enough 'max open files' limit aka 'ulimit -n' if root folder contains many files.

Do not create multiple FSHandler instances for the same (root, stripSlashes) arguments - just reuse a single instance. Otherwise goroutine leak will occur.

Example
package main

import (
	"bytes"
	"log"

	"github.com/valyala/fasthttp"
)

// Setup file handlers (aka 'file server config')
var (
	// Handler for serving images from /img/ path,
	// i.e. /img/foo/bar.jpg will be served from
	// /var/www/images/foo/bar.jpb .
	imgPrefix  = []byte("/img/")
	imgHandler = fasthttp.FSHandler("/var/www/images", 1)

	// Handler for serving css from /static/css/ path,
	// i.e. /static/css/foo/bar.css will be served from
	// /home/dev/css/foo/bar.css .
	cssPrefix  = []byte("/static/css/")
	cssHandler = fasthttp.FSHandler("/home/dev/css", 2)

	// Handler for serving the rest of requests,
	// i.e. /foo/bar/baz.html will be served from
	// /var/www/files/foo/bar/baz.html .
	filesHandler = fasthttp.FSHandler("/var/www/files", 0)
)

// Main request handler
func requestHandler(ctx *fasthttp.RequestCtx) {
	path := ctx.Path()
	switch {
	case bytes.HasPrefix(path, imgPrefix):
		imgHandler(ctx)
	case bytes.HasPrefix(path, cssPrefix):
		cssHandler(ctx)
	default:
		filesHandler(ctx)
	}
}

func main() {
	if err := fasthttp.ListenAndServe(":80", requestHandler); err != nil {
		log.Fatalf("Error in server: %s", err)
	}
}
Output:

func TimeoutHandler

func TimeoutHandler(h RequestHandler, timeout time.Duration, msg string) RequestHandler

TimeoutHandler creates RequestHandler, which returns StatusRequestTimeout error with the given msg to the client if h didn't return during the given duration.

type RequestHeader

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

RequestHeader represents HTTP request header.

It is forbidden copying RequestHeader instances. Create new instances instead and use CopyTo.

It is unsafe modifying/reading RequestHeader instance from concurrently running goroutines.

func (*RequestHeader) AppendBytes

func (h *RequestHeader) AppendBytes(dst []byte) []byte

AppendBytes appends request header representation to dst and returns dst (which may be newly allocated).

func (*RequestHeader) ConnectionClose

func (h *RequestHeader) ConnectionClose() bool

ConnectionClose returns true if 'Connection: close' header is set.

func (*RequestHeader) ConnectionCloseReal

func (h *RequestHeader) ConnectionCloseReal() bool

ConnectionCloseReal returns true if 'Connection: close' header is set.

This method triggers full (slow) request headers' parsing unlike ConnectionClose, so use it only if you really want determining whether 'Connection: close' header is really set on the wire.

func (*RequestHeader) ConnectionUpgrade

func (h *RequestHeader) ConnectionUpgrade() bool

ConnectionUpgrade returns true if 'Connection: Upgrade' header is set.

func (*RequestHeader) ContentLength

func (h *RequestHeader) ContentLength() int

ContentLength returns Content-Length header value.

It may be negative: -1 means Transfer-Encoding: chunked.

func (*RequestHeader) ContentType

func (h *RequestHeader) ContentType() []byte

ContentType returns Content-Type header value.

func (*RequestHeader) Cookie

func (h *RequestHeader) Cookie(key string) []byte

Cookie returns cookie for the given key.

func (*RequestHeader) CookieBytes

func (h *RequestHeader) CookieBytes(key []byte) []byte

CookieBytes returns cookie for the given key.

func (*RequestHeader) CopyTo

func (h *RequestHeader) CopyTo(dst *RequestHeader)

CopyTo copies all the headers to dst.

func (*RequestHeader) Del

func (h *RequestHeader) Del(key string)

Del deletes header with the given key.

func (*RequestHeader) DelBytes

func (h *RequestHeader) DelBytes(key []byte)

DelBytes deletes header with the given key.

func (*RequestHeader) Header

func (h *RequestHeader) Header() []byte

Header returns request header representation.

The returned representation is valid until the next call to RequestHeader methods.

func (*RequestHeader) Host

func (h *RequestHeader) Host() []byte

Host returns Host header value.

func (*RequestHeader) IsGet

func (h *RequestHeader) IsGet() bool

IsGet returns true if request method is GET.

func (*RequestHeader) IsHead

func (h *RequestHeader) IsHead() bool

IsHead returns true if request method is HEAD.

func (*RequestHeader) IsPost

func (h *RequestHeader) IsPost() bool

IsPost returns true if request methos is POST.

func (*RequestHeader) IsPut

func (h *RequestHeader) IsPut() bool

IsPut returns true if request method is PUT.

func (*RequestHeader) Len

func (h *RequestHeader) Len() int

Len returns the number of headers set, i.e. the number of times f is called in VisitAll.

func (*RequestHeader) Method

func (h *RequestHeader) Method() []byte

Method returns HTTP request method.

func (*RequestHeader) MultipartFormBoundary

func (h *RequestHeader) MultipartFormBoundary() []byte

MultipartFormBoundary returns boundary part from 'multipart/form-data; boundary=...'

func (*RequestHeader) Peek

func (h *RequestHeader) Peek(key string) []byte

Peek returns header value for the given key.

Returned value is valid until the next call to RequestHeader. Do not store references to returned value. Make copies instead.

func (*RequestHeader) PeekBytes

func (h *RequestHeader) PeekBytes(key []byte) []byte

PeekBytes returns header value for the given key.

Returned value is valid until the next call to RequestHeader. Do not store references to returned value. Make copies instead.

func (*RequestHeader) Read

func (h *RequestHeader) Read(r *bufio.Reader) error

Read reads request header from r.

func (*RequestHeader) Referer

func (h *RequestHeader) Referer() []byte

Referer returns Referer header value.

func (*RequestHeader) RequestURI

func (h *RequestHeader) RequestURI() []byte

RequestURI returns RequestURI from the first HTTP request line.

func (*RequestHeader) Reset

func (h *RequestHeader) Reset()

Reset clears request header.

func (*RequestHeader) Set

func (h *RequestHeader) Set(key, value string)

Set sets the given 'key: value' header.

func (*RequestHeader) SetBytesK

func (h *RequestHeader) SetBytesK(key []byte, value string)

SetBytesK sets the given 'key: value' header.

func (*RequestHeader) SetBytesKV

func (h *RequestHeader) SetBytesKV(key, value []byte)

SetBytesKV sets the given 'key: value' header.

func (*RequestHeader) SetBytesV

func (h *RequestHeader) SetBytesV(key string, value []byte)

SetBytesV sets the given 'key: value' header.

func (*RequestHeader) SetCanonical

func (h *RequestHeader) SetCanonical(key, value []byte)

SetCanonical sets the given 'key: value' header assuming that key is in canonical form.

func (*RequestHeader) SetConnectionClose

func (h *RequestHeader) SetConnectionClose()

SetConnectionClose sets 'Connection: close' header.

func (*RequestHeader) SetContentLength

func (h *RequestHeader) SetContentLength(contentLength int)

SetContentLength sets Content-Length header value.

Negative content-length sets 'Transfer-Encoding: chunked' header.

func (*RequestHeader) SetContentType

func (h *RequestHeader) SetContentType(contentType string)

SetContentType sets Content-Type header value.

func (*RequestHeader) SetContentTypeBytes

func (h *RequestHeader) SetContentTypeBytes(contentType []byte)

SetContentTypeBytes sets Content-Type header value.

func (*RequestHeader) SetCookie

func (h *RequestHeader) SetCookie(key, value string)

SetCookie sets 'key: value' cookies.

func (*RequestHeader) SetCookieBytesK

func (h *RequestHeader) SetCookieBytesK(key []byte, value string)

SetCookieBytesK sets 'key: value' cookies.

func (*RequestHeader) SetCookieBytesKV

func (h *RequestHeader) SetCookieBytesKV(key, value []byte)

SetCookieBytesKV sets 'key: value' cookies.

func (*RequestHeader) SetHost

func (h *RequestHeader) SetHost(host string)

SetHost sets Host header value.

func (*RequestHeader) SetHostBytes

func (h *RequestHeader) SetHostBytes(host []byte)

SetHostBytes sets Host header value.

func (*RequestHeader) SetMethod

func (h *RequestHeader) SetMethod(method string)

SetMethod sets HTTP request method.

func (*RequestHeader) SetMethodBytes

func (h *RequestHeader) SetMethodBytes(method []byte)

SetMethod sets HTTP request method.

func (*RequestHeader) SetReferer

func (h *RequestHeader) SetReferer(referer string)

SetReferer sets Referer header value.

func (*RequestHeader) SetRefererBytes

func (h *RequestHeader) SetRefererBytes(referer []byte)

SetRefererBytes sets Referer header value.

func (*RequestHeader) SetRequestURI

func (h *RequestHeader) SetRequestURI(requestURI string)

SetRequestURI sets RequestURI for the first HTTP request line. RequestURI must be properly encoded. Use URI.RequestURI for constructing proper RequestURI if unsure.

func (*RequestHeader) SetRequestURIBytes

func (h *RequestHeader) SetRequestURIBytes(requestURI []byte)

SetRequestURI sets RequestURI for the first HTTP request line. RequestURI must be properly encoded. Use URI.RequestURI for constructing proper RequestURI if unsure.

func (*RequestHeader) SetUserAgent

func (h *RequestHeader) SetUserAgent(userAgent string)

SetUserAgent sets User-Agent header value.

func (*RequestHeader) SetUserAgentBytes

func (h *RequestHeader) SetUserAgentBytes(userAgent []byte)

SetUserAgentBytes sets User-Agent header value.

func (*RequestHeader) String

func (h *RequestHeader) String() string

String returns request header representation.

func (*RequestHeader) UserAgent

func (h *RequestHeader) UserAgent() []byte

UserAgent returns User-Agent header value.

func (*RequestHeader) VisitAll

func (h *RequestHeader) VisitAll(f func(key, value []byte))

VisitAll calls f for each header.

f must not retain references to key and/or value after returning. Copy key and/or value contents before returning if you need retaining them.

func (*RequestHeader) VisitAllCookie

func (h *RequestHeader) VisitAllCookie(f func(key, value []byte))

VisitAllCookie calls f for each request cookie.

f must not retain references to key and/or value after returning.

func (*RequestHeader) Write

func (h *RequestHeader) Write(w *bufio.Writer) error

Write writes request header to w.

func (*RequestHeader) WriteTo

func (h *RequestHeader) WriteTo(w io.Writer) (int64, error)

WriteTo writes request header to w.

WriteTo implements io.WriterTo interface.

type Response

type Response struct {
	// Response header
	//
	// Copying Header by value is forbidden. Use pointer to Header instead.
	Header ResponseHeader

	// Response.Read() skips reading body if set to true.
	// Use it for HEAD requests.
	SkipBody bool
	// contains filtered or unexported fields
}

Response represents HTTP response.

It is forbidden copying Response instances. Create new instances and use CopyTo() instead.

It is unsafe modifying/reading Response instance from concurrently running goroutines.

func (*Response) Body

func (resp *Response) Body() []byte

Body returns response body.

func (*Response) BodyWriter

func (resp *Response) BodyWriter() io.Writer

BodyWriter returns writer for populating response body.

func (*Response) ConnectionClose

func (resp *Response) ConnectionClose() bool

ConnectionClose returns true if 'Connection: close' header is set.

func (*Response) CopyTo

func (resp *Response) CopyTo(dst *Response)

CopyTo copies resp contents to dst except of BodyStream.

func (*Response) Read

func (resp *Response) Read(r *bufio.Reader) error

Read reads response (including body) from the given r.

func (*Response) ReadLimitBody

func (resp *Response) ReadLimitBody(r *bufio.Reader, maxBodySize int) error

ReadLimitBody reads response from the given r, limiting the body size.

If maxBodySize > 0 and the body size exceeds maxBodySize, then ErrBodyTooLarge is returned.

func (*Response) Reset

func (resp *Response) Reset()

Reset clears response contents.

func (*Response) ResetBody

func (resp *Response) ResetBody()

ResetBody resets response body.

func (*Response) SetBody

func (resp *Response) SetBody(body []byte)

SetBody sets response body.

func (*Response) SetBodyStream

func (resp *Response) SetBodyStream(bodyStream io.Reader, bodySize int)

SetBodyStream sets response body stream and, optionally body size.

If bodySize is >= 0, then bodySize bytes are read from bodyStream and used as response body.

If bodySize < 0, then bodyStream is read until io.EOF.

bodyStream.Close() is called after finishing reading all body data if it implements io.Closer.

func (*Response) SetConnectionClose

func (resp *Response) SetConnectionClose()

SetConnectionClose sets 'Connection: close' header.

func (*Response) SetStatusCode

func (resp *Response) SetStatusCode(statusCode int)

SetStatusCode sets response status code.

func (*Response) StatusCode

func (resp *Response) StatusCode() int

StatusCode returns response status code.

func (*Response) String

func (resp *Response) String() string

String returns response representation.

Returns error message instead of response representation on error.

Use Write instead of String for performance-critical code.

func (*Response) Write

func (resp *Response) Write(w *bufio.Writer) error

Write writes response to w.

Write doesn't flush response to w for performance reasons.

type ResponseHeader

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

ResponseHeader represents HTTP response header.

It is forbidden copying ResponseHeader instances. Create new instances instead and use CopyTo.

It is unsafe modifying/reading ResponseHeader instance from concurrently running goroutines.

func (*ResponseHeader) AppendBytes

func (h *ResponseHeader) AppendBytes(dst []byte) []byte

AppendBytes appends response header representation to dst and returns dst (which may be newly allocated).

func (*ResponseHeader) ConnectionClose

func (h *ResponseHeader) ConnectionClose() bool

ConnectionClose returns true if 'Connection: close' header is set.

func (*ResponseHeader) ConnectionUpgrade

func (h *ResponseHeader) ConnectionUpgrade() bool

ConnectionUpgrade returns true if 'Connection: Upgrade' header is set.

func (*ResponseHeader) ContentLength

func (h *ResponseHeader) ContentLength() int

ContentLength returns Content-Length header value.

It may be negative: -1 means Transfer-Encoding: chunked. -2 means Transfer-Encoding: identity.

func (*ResponseHeader) ContentType

func (h *ResponseHeader) ContentType() []byte

ContentType returns Content-Type header value.

func (*ResponseHeader) Cookie

func (h *ResponseHeader) Cookie(cookie *Cookie) bool

Cookie fills cookie for the given cookie.Key.

Returns false if cookie with the given cookie.Key is missing.

func (*ResponseHeader) CopyTo

func (h *ResponseHeader) CopyTo(dst *ResponseHeader)

CopyTo copies all the headers to dst.

func (*ResponseHeader) Del

func (h *ResponseHeader) Del(key string)

Del deletes header with the given key.

func (*ResponseHeader) DelBytes

func (h *ResponseHeader) DelBytes(key []byte)

DelBytes deletes header with the given key.

func (*ResponseHeader) Header

func (h *ResponseHeader) Header() []byte

Header returns response header representation.

The returned value is valid until the next call to ResponseHeader methods.

func (*ResponseHeader) Len

func (h *ResponseHeader) Len() int

Len returns the number of headers set, i.e. the number of times f is called in VisitAll.

func (*ResponseHeader) Peek

func (h *ResponseHeader) Peek(key string) []byte

Peek returns header value for the given key.

Returned value is valid until the next call to ResponseHeader. Do not store references to returned value. Make copies instead.

func (*ResponseHeader) PeekBytes

func (h *ResponseHeader) PeekBytes(key []byte) []byte

PeekBytes returns header value for the given key.

Returned value is valid until the next call to ResponseHeader. Do not store references to returned value. Make copies instead.

func (*ResponseHeader) Read

func (h *ResponseHeader) Read(r *bufio.Reader) error

Read reads response header from r.

func (*ResponseHeader) Reset

func (h *ResponseHeader) Reset()

Reset clears response header.

func (*ResponseHeader) Server

func (h *ResponseHeader) Server() []byte

Server returns Server header value.

func (*ResponseHeader) Set

func (h *ResponseHeader) Set(key, value string)

Set sets the given 'key: value' header.

func (*ResponseHeader) SetBytesK

func (h *ResponseHeader) SetBytesK(key []byte, value string)

SetBytesK sets the given 'key: value' header.

func (*ResponseHeader) SetBytesKV

func (h *ResponseHeader) SetBytesKV(key, value []byte)

SetBytesKV sets the given 'key: value' header.

func (*ResponseHeader) SetBytesV

func (h *ResponseHeader) SetBytesV(key string, value []byte)

SetBytesV sets the given 'key: value' header.

func (*ResponseHeader) SetCanonical

func (h *ResponseHeader) SetCanonical(key, value []byte)

SetCanonical sets the given 'key: value' header assuming that key is in canonical form.

func (*ResponseHeader) SetConnectionClose

func (h *ResponseHeader) SetConnectionClose()

SetConnectionClose sets 'Connection: close' header.

func (*ResponseHeader) SetContentLength

func (h *ResponseHeader) SetContentLength(contentLength int)

SetContentLength sets Content-Length header value.

Content-Length may be negative: -1 means Transfer-Encoding: chunked. -2 means Transfer-Encoding: identity.

func (*ResponseHeader) SetContentType

func (h *ResponseHeader) SetContentType(contentType string)

SetContentType sets Content-Type header value.

func (*ResponseHeader) SetContentTypeBytes

func (h *ResponseHeader) SetContentTypeBytes(contentType []byte)

SetContentTypeBytes sets Content-Type header value.

func (*ResponseHeader) SetCookie

func (h *ResponseHeader) SetCookie(cookie *Cookie)

SetCookie sets the given response cookie.

func (*ResponseHeader) SetServer

func (h *ResponseHeader) SetServer(server string)

SetServer sets Server header value.

func (*ResponseHeader) SetServerBytes

func (h *ResponseHeader) SetServerBytes(server []byte)

SetServerBytes sets Server header value.

func (*ResponseHeader) SetStatusCode

func (h *ResponseHeader) SetStatusCode(statusCode int)

SetStatusCode sets response status code.

func (*ResponseHeader) StatusCode

func (h *ResponseHeader) StatusCode() int

StatusCode returns response status code.

func (*ResponseHeader) String

func (h *ResponseHeader) String() string

String returns response header representation.

func (*ResponseHeader) VisitAll

func (h *ResponseHeader) VisitAll(f func(key, value []byte))

VisitAll calls f for each header.

f must not retain references to key and/or value after returning. Copy key and/or value contents before returning if you need retaining them.

func (*ResponseHeader) VisitAllCookie

func (h *ResponseHeader) VisitAllCookie(f func(key, value []byte))

VisitAllCookie calls f for each response cookie.

Cookie name is passed in key and the whole Set-Cookie header value is passed in value on each f invocation. Value may be parsed with Cookie.ParseBytes().

f must not retain references to key and/or value after returning.

func (*ResponseHeader) Write

func (h *ResponseHeader) Write(w *bufio.Writer) error

Write writes response header to w.

func (*ResponseHeader) WriteTo

func (h *ResponseHeader) WriteTo(w io.Writer) (int64, error)

WriteTo writes response header to w.

WriteTo implements io.WriterTo interface.

type Server

type Server struct {
	// Handler for processing incoming requests.
	Handler RequestHandler

	// Server name for sending in response headers.
	//
	// Default server name is used if left blank.
	Name string

	// The maximum number of concurrent connections the server may serve.
	//
	// DefaultConcurrency is used if not set.
	Concurrency int

	// Per-connection buffer size for requests' reading.
	// This also limits the maximum header size.
	//
	// Default buffer size is used if 0.
	ReadBufferSize int

	// Per-connection buffer size for responses' writing.
	//
	// Default buffer size is used if 0.
	WriteBufferSize int

	// Maximum duration for full request reading (including body).
	//
	// By default request read timeout is unlimited.
	ReadTimeout time.Duration

	// Maximum duration for full response writing (including body).
	//
	// By default response write timeout is unlimited.
	WriteTimeout time.Duration

	// Maximum number of concurrent client connections allowed per IP.
	//
	// By default unlimited number of concurrent connections
	// may be established to the server from a single IP address.
	MaxConnsPerIP int

	// Maximum number of requests served per connection.
	//
	// The server closes connection after the last request.
	// 'Connection: close' header is added to the last request.
	//
	// By default unlimited number of requests served per connection.
	MaxRequestsPerConn int

	// Maximum keep-alive connection lifetime.
	//
	// The server closes keep-alive connection after its' lifetime
	// expiration.
	//
	// By default keep-alive connection lifetime is unlimited.
	MaxKeepaliveDuration time.Duration

	// Maximum request body size.
	//
	// The server closes incoming connection if this limit is greater than 0
	// and the request body size exceeds the limit.
	//
	// By default request body size is unlimited.
	MaxRequestBodySize int

	// Aggressively reduces memory usage at the cost of higher CPU usage
	// if set to true.
	//
	// Try enabling this option only if the server consumes too much memory
	// serving mostly idle keep-alive connections (more than 1M concurrent
	// connections). This may reduce memory usage by up to 50%.
	//
	// Aggressive memory usage reduction is disabled by default.
	ReduceMemoryUsage bool

	// Rejects all non-GET requests if set to true.
	//
	// This option is useful as anti-DoS protection for servers
	// accepting only GET requests. When set the request size is limited
	// by ReadBufferSize.
	//
	// Server accepts all the requests by default.
	GetOnly bool

	// Logger, which is used by RequestCtx.Logger().
	//
	// By default standard logger from log package is used.
	Logger Logger
	// contains filtered or unexported fields
}

Server implements HTTP server.

Default Server settings should satisfy the majority of Server users. Adjust Server settings only if you really understand the consequences.

It is forbidden copying Server instances. Create new Server instances instead.

It is safe to call Server methods from concurrently running goroutines.

Example
// This function will be called by the server for each incoming request.
//
// RequestCtx provides a lot of functionality related to http request
// processing. See RequestCtx docs for details.
requestHandler := func(ctx *RequestCtx) {
	fmt.Fprintf(ctx, "Hello, world! Requested path is %q", ctx.Path())
}

// Create custom server.
s := &Server{
	Handler: requestHandler,

	// Every response will contain 'Server: My super server' header.
	Name: "My super server",

	// Other Server settings may be set here.
}

// Start the server listening for incoming requests on the given address.
//
// ListenAndServe returns only on error, so usually it blocks forever.
if err := s.ListenAndServe("127.0.0.1:80"); err != nil {
	log.Fatalf("error in ListenAndServe: %s", err)
}
Output:

func (*Server) ListenAndServe

func (s *Server) ListenAndServe(addr string) error

ListenAndServe serves HTTP requests from the given TCP addr.

func (*Server) ListenAndServeTLS

func (s *Server) ListenAndServeTLS(addr, certFile, keyFile string) error

ListenAndServeTLS serves HTTPS requests from the given TCP addr.

certFile and keyFile are paths to TLS certificate and key files.

func (*Server) Serve

func (s *Server) Serve(ln net.Listener) error

Serve serves incoming connections from the given listener.

Serve blocks until the given listener returns permanent error.

func (*Server) ServeConn

func (s *Server) ServeConn(c net.Conn) error

ServeConn serves HTTP requests from the given connection.

ServeConn returns nil if all requests from the c are successfully served. It returns non-nil error otherwise.

Connection c must immediately propagate all the data passed to Write() to the client. Otherwise requests' processing may hang.

ServeConn closes c before returning.

type URI

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

URI represents URI :) .

It is forbidden copying URI instances. Create new instance and use CopyTo instead.

func (*URI) AppendBytes

func (x *URI) AppendBytes(dst []byte) []byte

AppendBytes appends full uri to dst and returns dst (which may be newly allocated).

func (*URI) CopyTo

func (x *URI) CopyTo(dst *URI)

CopyTo copies uri contents to dst.

func (*URI) FullURI

func (x *URI) FullURI() []byte

FullURI returns full uri in the form {Scheme}://{Host}{RequestURI}#{Hash}.

func (*URI) Hash

func (x *URI) Hash() []byte

Hash returns URI hash, i.e. qwe of http://aaa.com/foo/bar?baz=123#qwe .

The returned value is valid until the next URI method call.

func (*URI) Host

func (x *URI) Host() []byte

Host returns host part, i.e. aaa.com of http://aaa.com/foo/bar?baz=123#qwe .

Host is always lowercased.

func (*URI) Parse

func (x *URI) Parse(host, uri []byte)

Parse initializes URI from the given host and uri.

func (*URI) Path

func (x *URI) Path() []byte

Path returns URI path, i.e. /foo/bar of http://aaa.com/foo/bar?baz=123#qwe .

The returned path is always urldecoded and normalized, i.e. '//f%20obar/baz/../zzz' becomes '/f obar/zzz'.

The returned value is valid until the next URI method call.

func (*URI) PathOriginal

func (x *URI) PathOriginal() []byte

PathOriginal returns the original path from requestURI passed to URI.Parse().

The returned value is valid until the next URI method call.

func (*URI) QueryArgs

func (x *URI) QueryArgs() *Args

Returns query args.

func (*URI) QueryString

func (x *URI) QueryString() []byte

QueryString returns URI query string, i.e. baz=123 of http://aaa.com/foo/bar?baz=123#qwe .

The returned value is valid until the next URI method call.

func (*URI) RequestURI

func (x *URI) RequestURI() []byte

RequestURI returns RequestURI - i.e. URI without Scheme and Host.

func (*URI) Reset

func (x *URI) Reset()

Reset clears uri.

func (*URI) Scheme

func (x *URI) Scheme() []byte

Scheme returns URI scheme, i.e. http of http://aaa.com/foo/bar?baz=123#qwe .

Returned scheme is always lowercased.

The returned value is valid until the next URI method call.

func (*URI) SetHash

func (x *URI) SetHash(hash string)

SetHash sets URI hash.

func (*URI) SetHashBytes

func (x *URI) SetHashBytes(hash []byte)

SetHashBytes sets URI hash.

func (*URI) SetHost

func (x *URI) SetHost(host string)

SetHost sets host for the uri.

func (*URI) SetHostBytes

func (x *URI) SetHostBytes(host []byte)

SetHostBytes sets host for the uri.

func (*URI) SetPath

func (x *URI) SetPath(path string)

SetPath sets URI path.

func (*URI) SetPathBytes

func (x *URI) SetPathBytes(path []byte)

SetPathBytes sets URI path.

func (*URI) SetQueryString

func (x *URI) SetQueryString(queryString string)

SetQueryString sets URI query string.

func (*URI) SetQueryStringBytes

func (x *URI) SetQueryStringBytes(queryString []byte)

SetQueryStringBytes sets URI query string.

func (*URI) SetScheme

func (x *URI) SetScheme(scheme string)

SetScheme sets URI scheme, i.e. http, https, ftp, etc.

func (*URI) SetSchemeBytes

func (x *URI) SetSchemeBytes(scheme []byte)

SetScheme sets URI scheme, i.e. http, https, ftp, etc.

func (*URI) String

func (x *URI) String() string

String returns full uri.

func (*URI) Update

func (x *URI) Update(newURI string)

Update updates uri.

The following newURI types are accepted:

  • Absolute, i.e. http://foobar.com/aaa/bb?cc . In this case the original uri is replaced by newURI.
  • Missing host, i.e. /aaa/bb?cc . In this case only RequestURI part of the original uri is replaced.
  • Relative path, i.e. xx?yy=abc . In this case the original RequestURI is updated according to the new relative path.

func (*URI) UpdateBytes

func (x *URI) UpdateBytes(newURI []byte)

UpdateBytes updates uri.

The following newURI types are accepted:

  • Absolute, i.e. http://foobar.com/aaa/bb?cc . In this case the original uri is replaced by newURI.
  • Missing host, i.e. /aaa/bb?cc . In this case only RequestURI part of the original uri is replaced.
  • Relative path, i.e. xx?yy=abc . In this case the original RequestURI is updated according to the new relative path.

func (*URI) WriteTo

func (x *URI) WriteTo(w io.Writer) (int64, error)

WriteTo writes full uri to w.

WriteTo implements io.WriterTo interface.

Directories

Path Synopsis
examples
fileserver
Example static file server.
Example static file server.
Package reuseport provides TCP net.Listener with SO_REUSEPORT support.
Package reuseport provides TCP net.Listener with SO_REUSEPORT support.

Jump to

Keyboard shortcuts

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