Documentation ¶
Overview ¶
Package web is a HTTP server for Golang applications.
It is suitable for both front-end and back-end use, being able to deliver static content, act as a REST-ful JSON server, and as a WebSocket server.
It includes simple controls to allow for user authentication with contextual data being available in every request, and provides simple per-user rate-limiting.
Example (Authentication) ¶
package main import ( "net/http" "time" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") type User struct { Username string `json:"username"` } // Login loginHandle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { // Do any authentication logic here // Assuming the user authenticated successfully... return true, &web.APIResponse{ Cookies: []http.Cookie{ { Name: "session", Value: "1", Path: "/", Expires: time.Now().AddDate(0, 0, 1), }, }, }, nil } unauthenticatedOptions := web.HandleOptions{} server.API.GET("/login", loginHandle, unauthenticatedOptions) // Get User Info getUserHandle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { user := request.UserData.(User) return user, nil, nil } authenticatedOptions := web.HandleOptions{ // The authenticate method is where you validate that a request if from an authenticated, or simple "logged in" // user. In this example, we validate that a cookie is present. // Any data returned by this method is provided into the request handler as Request.UserData // Returning nil results in a HTTP 403 response AuthenticateMethod: func(request *http.Request) interface{} { cookie, err := request.Cookie("session") if err != nil || cookie == nil { return nil } if cookie.Value != "1" { return nil } return map[string]string{ "foo": "bar", } }, } // Notice that we used a different HandleOptions instance with our AuthenticateMethod // an options without any AuthenticateMethod is considered unauthenticated server.API.GET("/user", getUserHandle, authenticatedOptions) if err := server.Start(); err != nil { panic(err) } }
Output:
Example (File) ¶
package main import ( "os" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) web.HTTPResponse { f, err := os.Open("/foo/bar") if err != nil { return web.HTTPResponse{ Status: 500, } } return web.HTTPResponse{ Reader: f, } } options := web.HandleOptions{} server.HTTPEasy.GET("/file", handle, options) if err := server.Start(); err != nil { panic(err) } }
Output:
Example (Json) ¶
package main import ( "time" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { return time.Now().Unix(), nil, nil } options := web.HandleOptions{} server.API.GET("/time", handle, options) if err := server.Start(); err != nil { panic(err) } }
Output:
Example (Ratelimit) ¶
package main import ( "net/http" "time" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") // Restrict each connecting IP address to a maximum of 5 requests per second server.Options.MaxRequestsPerSecond = 5 // Handle called when a request is rejected due to rate limiting server.RateLimitedHandler = func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(429) w.Write([]byte("Too many requests")) } handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { return time.Now().Unix(), nil, nil } options := web.HandleOptions{} server.API.GET("/time", handle, options) if err := server.Start(); err != nil { panic(err) } }
Output:
Example (Unixsocket) ¶
package main import ( "net" "time" "github.com/ecnepsnai/web" ) func main() { l, err := net.Listen("unix", "/example.socket") if err != nil { panic(err) } server := web.NewListener(l) handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { return time.Now().Unix(), nil, nil } options := web.HandleOptions{} server.API.GET("/time", handle, options) if err := server.Start(); err != nil { panic(err) } }
Output:
Example (Websocket) ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") type questionType struct { Name string } type answerType struct { Reply string } handle := func(request web.Request, conn *web.WSConn) { question := questionType{} if err := conn.ReadJSON(&question); err != nil { return } reply := answerType{ Reply: "Hello, " + question.Name, } if err := conn.WriteJSON(&reply); err != nil { return } } options := web.HandleOptions{} server.Socket("/greeting", handle, options) if err := server.Start(); err != nil { panic(err) } }
Output:
Index ¶
- Variables
- type API
- func (a API) DELETE(path string, handle APIHandle, options HandleOptions)
- func (a API) GET(path string, handle APIHandle, options HandleOptions)
- func (a API) HEAD(path string, handle APIHandle, options HandleOptions)
- func (a API) OPTIONS(path string, handle APIHandle, options HandleOptions)
- func (a API) PATCH(path string, handle APIHandle, options HandleOptions)
- func (a API) POST(path string, handle APIHandle, options HandleOptions)
- func (a API) PUT(path string, handle APIHandle, options HandleOptions)
- type APIHandle
- type APIResponse
- type Error
- type HTTP
- func (h HTTP) DELETE(path string, handle HTTPHandle, options HandleOptions)
- func (h HTTP) GET(path string, handle HTTPHandle, options HandleOptions)
- func (h HTTP) HEAD(path string, handle HTTPHandle, options HandleOptions)
- func (h HTTP) OPTIONS(path string, handle HTTPHandle, options HandleOptions)
- func (h HTTP) PATCH(path string, handle HTTPHandle, options HandleOptions)
- func (h HTTP) POST(path string, handle HTTPHandle, options HandleOptions)
- func (h HTTP) PUT(path string, handle HTTPHandle, options HandleOptions)
- type HTTPEasy
- func (h HTTPEasy) DELETE(path string, handle HTTPEasyHandle, options HandleOptions)
- func (h HTTPEasy) GET(path string, handle HTTPEasyHandle, options HandleOptions)
- func (h HTTPEasy) GETHEAD(path string, handle HTTPEasyHandle, options HandleOptions)
- func (h HTTPEasy) HEAD(path string, handle HTTPEasyHandle, options HandleOptions)
- func (h HTTPEasy) OPTIONS(path string, handle HTTPEasyHandle, options HandleOptions)
- func (h HTTPEasy) PATCH(path string, handle HTTPEasyHandle, options HandleOptions)
- func (h HTTPEasy) POST(path string, handle HTTPEasyHandle, options HandleOptions)
- func (h HTTPEasy) PUT(path string, handle HTTPEasyHandle, options HandleOptions)
- func (h HTTPEasy) Static(path string, directory string)
- type HTTPEasyHandle
- type HTTPHandle
- type HTTPResponse
- type HandleOptions
- type JSONResponse
- type MockRequestParameters
- type Request
- type Server
- type ServerOptions
- type SocketHandle
- type WSConn
Examples ¶
- Package (Authentication)
- Package (File)
- Package (Json)
- Package (Ratelimit)
- Package (Unixsocket)
- Package (Websocket)
- API.DELETE
- API.GET
- API.HEAD
- API.OPTIONS
- API.PATCH
- API.POST
- API.PUT
- HTTP.DELETE
- HTTP.GET
- HTTP.HEAD
- HTTP.OPTIONS
- HTTP.PATCH
- HTTP.POST
- HTTP.PUT
- HTTPEasy.DELETE
- HTTPEasy.GET
- HTTPEasy.GETHEAD
- HTTPEasy.HEAD
- HTTPEasy.OPTIONS
- HTTPEasy.PATCH
- HTTPEasy.POST
- HTTPEasy.PUT
- HTTPEasy.Static
- Request.ClientIPAddress
- Request.DecodeJSON
- Server.Socket
- ValidationError
Constants ¶
This section is empty.
Variables ¶
var CommonErrors = struct { NotFound *Error BadRequest *Error Unauthorized *Error Forbidden *Error ServerError *Error TooManyRequests *Error }{ NotFound: &Error{ Code: 404, Message: "Not Found", }, BadRequest: &Error{ Code: 400, Message: "Bad Request", }, Unauthorized: &Error{ Code: 403, Message: "Unauthorized", }, Forbidden: &Error{ Code: 403, Message: "Forbidden", }, ServerError: &Error{ Code: 500, Message: "Server Error", }, TooManyRequests: &Error{ Code: 429, Message: "Too Many Requests", }, }
CommonErrors are common errors types suitable for API endpoints
Functions ¶
This section is empty.
Types ¶
type API ¶
type API struct {
// contains filtered or unexported fields
}
API describes a JSON API server. API handles return data or an error, and all responses are wrapped in a common response object.
func (API) DELETE ¶
func (a API) DELETE(path string, handle APIHandle, options HandleOptions)
DELETE register a new HTTP DELETE request handle
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { username := request.Parameters["username"] return map[string]string{ "username": username, }, nil, nil } server.API.DELETE("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
func (API) GET ¶
func (a API) GET(path string, handle APIHandle, options HandleOptions)
GET register a new HTTP GET request handle
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { username := request.Parameters["username"] return map[string]string{ "username": username, }, nil, nil } server.API.GET("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
func (API) HEAD ¶
func (a API) HEAD(path string, handle APIHandle, options HandleOptions)
HEAD register a new HTTP HEAD request handle
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { return nil, nil, nil } server.API.HEAD("/users/user/", handle, web.HandleOptions{}) server.Start() }
Output:
func (API) OPTIONS ¶
func (a API) OPTIONS(path string, handle APIHandle, options HandleOptions)
OPTIONS register a new HTTP OPTIONS request handle
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { return nil, nil, nil } server.API.OPTIONS("/users/user/", handle, web.HandleOptions{}) server.Start() }
Output:
func (API) PATCH ¶
func (a API) PATCH(path string, handle APIHandle, options HandleOptions)
PATCH register a new HTTP PATCH request handle
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") type userRequestType struct { FirstName string `json:"first_name"` } handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { username := request.Parameters["username"] params := userRequestType{} if err := request.DecodeJSON(¶ms); err != nil { return nil, nil, err } return map[string]string{ "first_name": params.FirstName, "username": username, }, nil, nil } server.API.PATCH("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
func (API) POST ¶
func (a API) POST(path string, handle APIHandle, options HandleOptions)
POST register a new HTTP POST request handle
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") type userRequestType struct { FirstName string `json:"first_name"` } handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { username := request.Parameters["username"] params := userRequestType{} if err := request.DecodeJSON(¶ms); err != nil { return nil, nil, err } return map[string]string{ "first_name": params.FirstName, "username": username, }, nil, nil } server.API.POST("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
func (API) PUT ¶
func (a API) PUT(path string, handle APIHandle, options HandleOptions)
PUT register a new HTTP PUT request handle
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") type userRequestType struct { FirstName string `json:"first_name"` } handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { username := request.Parameters["username"] params := userRequestType{} if err := request.DecodeJSON(¶ms); err != nil { return nil, nil, err } return map[string]string{ "first_name": params.FirstName, "username": username, }, nil, nil } server.API.PUT("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
type APIHandle ¶
type APIHandle func(request Request) (interface{}, *APIResponse, *Error)
APIHandle describes a method signature for handling an API request
type APIResponse ¶ added in v1.11.0
type APIResponse struct { // Additional headers to append to the response. Headers map[string]string // Cookies to set on the response. Cookies []http.Cookie }
APIResponse describes additional response properties for API handles
type Error ¶
Error describes an API error object
func ValidationError ¶
ValidationError convenience method to make a error object for validation errors
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { username := request.Parameters["username"] return nil, nil, web.ValidationError("No user with username %s", username) } server.API.GET("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
type HTTP ¶
type HTTP struct {
// contains filtered or unexported fields
}
HTTP describes a HTTP server. HTTP handles are exposed to the raw http request and response writers.
func (HTTP) DELETE ¶
func (h HTTP) DELETE(path string, handle HTTPHandle, options HandleOptions)
DELETE register a new HTTP DELETE request handle
Example ¶
package main import ( "net/http" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(w http.ResponseWriter, r web.Request) { username := r.Parameters["username"] w.Header().Set("X-Username", username) w.WriteHeader(200) } server.HTTP.DELETE("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTP) GET ¶
func (h HTTP) GET(path string, handle HTTPHandle, options HandleOptions)
GET register a new HTTP GET request handle
Example ¶
package main import ( "fmt" "io" "net/http" "os" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(w http.ResponseWriter, r web.Request) { f, _ := os.Open("/foo/bar") info, _ := f.Stat() w.Header().Set("Content-Type", "text/plain") w.Header().Set("Content-Length", fmt.Sprintf("%d", info.Size())) io.Copy(w, f) } server.HTTP.GET("/users/user", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTP) HEAD ¶
func (h HTTP) HEAD(path string, handle HTTPHandle, options HandleOptions)
HEAD register a new HTTP HEAD request handle
Example ¶
package main import ( "net/http" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(w http.ResponseWriter, r web.Request) { w.Header().Set("X-Fancy-Header", "Some value") w.WriteHeader(204) } server.HTTP.HEAD("/users/user", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTP) OPTIONS ¶
func (h HTTP) OPTIONS(path string, handle HTTPHandle, options HandleOptions)
OPTIONS register a new HTTP OPTIONS request handle
Example ¶
package main import ( "net/http" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(w http.ResponseWriter, r web.Request) { w.Header().Set("X-Fancy-Header", "Some value") w.WriteHeader(200) } server.HTTP.OPTIONS("/users/user", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTP) PATCH ¶
func (h HTTP) PATCH(path string, handle HTTPHandle, options HandleOptions)
PATCH register a new HTTP PATCH request handle
Example ¶
package main import ( "net/http" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(w http.ResponseWriter, r web.Request) { username := r.Parameters["username"] w.Header().Set("X-Username", username) w.WriteHeader(200) } server.HTTP.PATCH("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTP) POST ¶
func (h HTTP) POST(path string, handle HTTPHandle, options HandleOptions)
POST register a new HTTP POST request handle
Example ¶
package main import ( "net/http" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(w http.ResponseWriter, r web.Request) { username := r.Parameters["username"] w.Header().Set("X-Username", username) w.WriteHeader(200) } server.HTTP.POST("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTP) PUT ¶
func (h HTTP) PUT(path string, handle HTTPHandle, options HandleOptions)
PUT register a new HTTP PUT request handle
Example ¶
package main import ( "net/http" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(w http.ResponseWriter, r web.Request) { username := r.Parameters["username"] w.Header().Set("X-Username", username) w.WriteHeader(200) } server.HTTP.PUT("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
type HTTPEasy ¶ added in v1.11.0
type HTTPEasy struct {
// contains filtered or unexported fields
}
HTTPEasy describes a HTTPEasy server. HTTPEasy handles are expected to return a reader and specify the content type and length themselves.
The HTTPEasy server supports HTTPEasy range requests, should the client request it and the application provide a supported Reader (io.ReadSeekCloser).
func (HTTPEasy) DELETE ¶ added in v1.11.0
func (h HTTPEasy) DELETE(path string, handle HTTPEasyHandle, options HandleOptions)
DELETE register a new HTTP DELETE request handle
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) web.HTTPResponse { username := request.Parameters["username"] return web.HTTPResponse{ Headers: map[string]string{ "X-Username": username, }, } } server.HTTPEasy.DELETE("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTPEasy) GET ¶ added in v1.11.0
func (h HTTPEasy) GET(path string, handle HTTPEasyHandle, options HandleOptions)
GET register a new HTTP GET request handle
Example ¶
package main import ( "os" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) web.HTTPResponse { f, err := os.Open("/foo/bar") info, ierr := f.Stat() if err != nil || ierr != nil { return web.HTTPResponse{ Status: 500, } } return web.HTTPResponse{ Reader: f, // The file will be closed automatically ContentType: "text/plain", ContentLength: uint64(info.Size()), } } server.HTTPEasy.GET("/users/user", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTPEasy) GETHEAD ¶ added in v1.11.0
func (h HTTPEasy) GETHEAD(path string, handle HTTPEasyHandle, options HandleOptions)
GETHEAD registers both a HTTP GET and HTTP HEAD request handle. Equal to calling HTTPEasy.GET and HTTPEasy.HEAD.
Handle responses can always return a reader, it will automatically be ignored for HEAD requests.
Example ¶
package main import ( "os" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) web.HTTPResponse { f, err := os.Open("/foo/bar") info, ierr := f.Stat() if err != nil || ierr != nil { return web.HTTPResponse{ Status: 500, } } return web.HTTPResponse{ Reader: f, // the file will not be read for HTTP HEAD requests, but it will be closed. ContentType: "text/plain", ContentLength: uint64(info.Size()), } } server.HTTPEasy.GETHEAD("/users/user", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTPEasy) HEAD ¶ added in v1.11.0
func (h HTTPEasy) HEAD(path string, handle HTTPEasyHandle, options HandleOptions)
HEAD register a new HTTP HEAD request handle
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) web.HTTPResponse { return web.HTTPResponse{ Headers: map[string]string{ "X-Fancy-Header": "some value", }, } } server.HTTPEasy.HEAD("/users/user", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTPEasy) OPTIONS ¶ added in v1.11.0
func (h HTTPEasy) OPTIONS(path string, handle HTTPEasyHandle, options HandleOptions)
OPTIONS register a new HTTP OPTIONS request handle
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) web.HTTPResponse { return web.HTTPResponse{ Headers: map[string]string{ "X-Fancy-Header": "some value", }, } } server.HTTPEasy.OPTIONS("/users/user", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTPEasy) PATCH ¶ added in v1.11.0
func (h HTTPEasy) PATCH(path string, handle HTTPEasyHandle, options HandleOptions)
PATCH register a new HTTP PATCH request handle
Example ¶
package main import ( "os" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) web.HTTPResponse { username := request.Parameters["username"] f, err := os.Open("/foo/bar") if err != nil { return web.HTTPResponse{ Status: 500, } } return web.HTTPResponse{ Headers: map[string]string{ "X-Username": username, }, Reader: f, } } server.HTTPEasy.PATCH("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTPEasy) POST ¶ added in v1.11.0
func (h HTTPEasy) POST(path string, handle HTTPEasyHandle, options HandleOptions)
POST register a new HTTP POST request handle
Example ¶
package main import ( "os" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) web.HTTPResponse { username := request.Parameters["username"] f, err := os.Open("/foo/bar") if err != nil { return web.HTTPResponse{ Status: 500, } } return web.HTTPResponse{ Headers: map[string]string{ "X-Username": username, }, Reader: f, } } server.HTTPEasy.POST("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTPEasy) PUT ¶ added in v1.11.0
func (h HTTPEasy) PUT(path string, handle HTTPEasyHandle, options HandleOptions)
PUT register a new HTTP PUT request handle
Example ¶
package main import ( "os" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) web.HTTPResponse { username := request.Parameters["username"] f, err := os.Open("/foo/bar") if err != nil { return web.HTTPResponse{ Status: 500, } } return web.HTTPResponse{ Headers: map[string]string{ "X-Username": username, }, Reader: f, } } server.HTTPEasy.PUT("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
func (HTTPEasy) Static ¶ added in v1.11.0
Static registers a GET and HEAD handle for all requests under path to serve any files matching the directory.
For example:
directory = /usr/share/www/ path = /static/ Request for '/static/image.jpg' would read file '/usr/share/www/image.jpg'
Will panic if any handle is registered under path. Attempting to register a new handle under path after calling Static will panic.
Caching will be enabled by default for all files served by this router. The mtime of the file will be used for the Last-Modified date.
By default, the server will use the file extension (if any) to determine the MIME type for the response.
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") server.HTTPEasy.Static("/static/*", "/path/to/static/files") server.Start() }
Output:
type HTTPEasyHandle ¶ added in v1.11.0
type HTTPEasyHandle func(request Request) HTTPResponse
HTTPEasyHandle describes a method signature for handling an HTTP request
type HTTPHandle ¶
type HTTPHandle func(w http.ResponseWriter, r Request)
HTTPHandle describes a method signature for handling an HTTP request
type HTTPResponse ¶ added in v1.9.0
type HTTPResponse struct { // The reader for the response. Will be closed when the HTTP response is finished. Can be nil. // // If a io.ReadSeekCloser is provided then ranged data may be provided for a HTTP range request. Reader io.ReadCloser // The status code for the response. If 0 then 200 is implied. Status int // Additional headers to append to the response. Headers map[string]string // Cookies to set on the response. Cookies []http.Cookie // The content type of the response. Will overwrite any 'content-type' header in Headers. ContentType string // The length of the content. ContentLength uint64 }
HTTPResponse describes a HTTP response
type HandleOptions ¶
type HandleOptions struct { // AuthenticateMethod method called to determine if a request is properly authenticated or not. // Optional - Omit this entirely if no authentication is needed for the request. // Return nil to signal an unauthenticated request, which will be rejected. // Objects returned will be passed to the handle as the UserData object. AuthenticateMethod func(request *http.Request) interface{} // to customize the response seen by the user. // Optional - Omit this to have a default response. UnauthorizedMethod func(w http.ResponseWriter, request *http.Request) // MaxBodyLength defines the maximum length accepted for any HTTP request body. Requests that // exceed this limit will receive a 413 Payload Too Large response. // The default value of 0 will not reject requests with large bodies. MaxBodyLength uint64 // DontLogRequests if true then requests to this handle are not logged DontLogRequests bool }
HandleOptions describes options for a route
type JSONResponse ¶
type JSONResponse struct { // The actual data of the response Data interface{} `json:"data,omitempty"` // If an error occured, details about the error Error *Error `json:"error,omitempty"` // The HTTP status code for the response // // Deprecated: will be removed in the next breaking update Code int `json:"code"` }
JSONResponse describes an API response object
type MockRequestParameters ¶ added in v1.11.2
type MockRequestParameters struct { // User data to be passed into the handler. May be nil. UserData interface{} // URL parameters (not query parameters) to be populated into the request.Params object in the handler. May be nil. Parameters map[string]string // Object to be encoded with JSON as the body. May be nil. Exclusive to Body. JSONBody interface{} // Body data. May be nil. Exclusive to JSONBody. Body io.ReadCloser // Optional HTTP request to pass to the handler. Request *http.Request }
Parameters for creating a mock request for uses in tests
type Request ¶
Request describes an API request
func MockRequest ¶
func MockRequest(parameters MockRequestParameters) Request
MockRequest will generate a mock request for testing your handlers. Will panic for invalid parameters.
func (Request) ClientIPAddress ¶ added in v1.7.0
ClientIPAddress returns the IP address of the client. It supports the 'X-Real-IP' and 'X-Forwarded-For' headers.
Example ¶
package main import ( "fmt" "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { clientAddr := request.ClientIPAddress().String() fmt.Printf("%s\n", clientAddr) return clientAddr, nil, nil } server.API.POST("/ip/my_ip", handle, web.HandleOptions{}) server.Start() }
Output:
func (Request) DecodeJSON ¶ added in v1.7.0
DecodeJSON unmarshal the JSON body to the provided interface
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") type userRequestType struct { FirstName string `json:"first_name"` } handle := func(request web.Request) (interface{}, *web.APIResponse, *web.Error) { username := request.Parameters["username"] params := userRequestType{} if err := request.DecodeJSON(¶ms); err != nil { return nil, nil, err } return map[string]string{ "first_name": params.FirstName, "username": username, }, nil, nil } server.API.POST("/users/user/:username", handle, web.HandleOptions{}) server.Start() }
Output:
type Server ¶
type Server struct { // The socket address that the server is listening on. Only populated if the server was created with web.New(). BindAddress string // The port that this server is listening on. Only populated if the server was created with web.New(). ListenPort uint16 // The JSON API server. API handles return data or an error, and all responses are wrapped in a common // response object. API API // HTTPEasy describes a easy HTTP server. HTTPEasy handles are expected to return a reader and specify the content // type and length themselves. // // The HTTPEasy server supports HTTP range requests, should the client request it and the application provide a // supported Reader (io.ReadSeekCloser). HTTPEasy HTTPEasy // The HTTP server. HTTP handles are exposed to the raw http request and response writers. HTTP HTTP // The handler called when a request that does not match a registered path occurs. Defaults to a plain // HTTP 404 with "Not found" as the body. NotFoundHandler func(w http.ResponseWriter, r *http.Request) // The handler called when a request that did match a router but with the incorrect method occurs. Defaults to a // plain HTTP 405 with "Method not allowed" as the body. MethodNotAllowedHandler func(w http.ResponseWriter, r *http.Request) // The handler called when a request exceed the configured maximum per second limit. Defaults to a plain HTTP 429 // with "Too many requests" as the body. RateLimitedHandler func(w http.ResponseWriter, r *http.Request) // Additional options for the server Options ServerOptions // contains filtered or unexported fields }
Server describes an web server
func New ¶
New create a new server object that will bind to the provided address. Does not accept incoming connections until the server is started. Bind address must be in the format of "address:port", such as "localhost:8080" or "0.0.0.0:8080".
func NewListener ¶ added in v1.10.0
NewListener creates a new server object that will use the given listener. Does not accept incoming connections until the server is started.
func (*Server) Socket ¶ added in v1.4.0
func (s *Server) Socket(path string, handle SocketHandle, options HandleOptions)
Socket register a new websocket server at the given path
Example ¶
package main import ( "github.com/ecnepsnai/web" ) func main() { server := web.New("127.0.0.1:8080") type questionType struct { Name string } type answerType struct { Reply string } handle := func(request web.Request, conn *web.WSConn) { question := questionType{} if err := conn.ReadJSON(&question); err != nil { return } reply := answerType{ Reply: "Hello, " + question.Name, } if err := conn.WriteJSON(&reply); err != nil { return } } options := web.HandleOptions{} server.Socket("/greeting", handle, options) server.Start() }
Output:
type ServerOptions ¶ added in v1.9.0
type ServerOptions struct { // Specify the maximum number of requests any given client IP address can make per second. Requests that are rate // limited will call the RateLimitedHandler, which you can override to customize the response. // Setting this to 0 disables rate limiting. MaxRequestsPerSecond int // The level to use when logging out HTTP requests. Maps to github.com/ecnepsnai/logtic levels. Defaults to Debug. RequestLogLevel int // If true then the server will not try to reply with chunked data for a HTTP range request IgnoreHTTPRangeRequests bool }
type SocketHandle ¶ added in v1.4.0
SocketHandle describes a method signature for handling a HTTP websocket request