httputil

package module
v1.1.2 Latest Latest
Warning

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

Go to latest
Published: Jan 30, 2024 License: MIT Imports: 13 Imported by: 1

README

What is it?

Test

The httputil package is a set of opinionated HTTP-related helpers.

Helpers include e.g. extracting bearer tokens from HTTP headers, retrieving parameters from the query string or parsing the HTTP body into a JSON-based struct.

Prior art

The original code was taken from Camlistore, and was available in the camlistore.org/pkg/httputil package. Lately, Camlistore has been renamed to Perkeep.

License

MIT. See LICENSE file.

Documentation

Overview

Package httputil is a set of opinionated helpers for HTTP servers/handlers, working with HTTP requests and responses, and managing errors.

Helpers include e.g. extracting bearer tokens from HTTP headers, retrieving parameters from the query string or parsing the HTTP body into a JSON-based struct.

It is derived originally derived from Camlistore, which is now available at https://camlistore.org/pkg/httputil.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func BadRequestError

func BadRequestError(w http.ResponseWriter, errorMessage string, args ...interface{})

BadRequestError returns HTTP status 400 and an error message as HTML.

func BearerToken

func BearerToken(r *http.Request) (string, bool)

BearerToken extracts the Bearer token from the request.

func CloseBody

func CloseBody(rc io.ReadCloser)

CloseBody closes rc.

func DumpRequestOut

func DumpRequestOut(w io.Writer, r *http.Request)

DumpRequestOut prints the request to the given io.Writer.

func EqualJSON added in v1.0.2

func EqualJSON(a, b []byte) bool

EqualJSON compares the two serialized byte slices for equality.

Both a and b are expected to be JSON serialized byte slices. EqualJSON simply ensures that insiginificant white space is removed both from a and b before comparing for equality.

EqualJSON returns true in the following cases:

  1. a or b are both nil
  2. a or b have both a length of 0
  3. a or b are equal if all siginificant white space is removed, i.e. newlines, tabs, and space.

In all other cases, EqualJSON returns false. Notice that while the two JSON objects `{"a":1,"b":2}` and `{"b":2,"a":1}` may be semantically equal, EqualJSON will return false.

func ForbiddenError

func ForbiddenError(w http.ResponseWriter, errorMessage string, args ...interface{})

ForbiddenError returns HTTP status 403 and an error message as HTML.

func FormBool

func FormBool(r *http.Request, key string, defaultValue bool) bool

FormBool checks if the request r has a Form value with the specified key that can be converted to a bool. If is doesn't, it will return defaultValue.

func FormFloat64

func FormFloat64(r *http.Request, key string, defaultValue float64) float64

FormFloat64 checks if the request r has a Form value with the specified key that can be converted to a float64. If is doesn't, it will return defaultValue.

func FormInt

func FormInt(r *http.Request, key string, defaultValue int) int

FormInt checks if the request r has a Form value with the specified key that can be converted to an int. If is doesn't, it will return defaultValue.

func FormInt32

func FormInt32(r *http.Request, key string, defaultValue int32) int32

FormInt32 checks if the request r has a Form value with the specified key that can be converted to an int32. If is doesn't, it will return defaultValue.

func FormInt64

func FormInt64(r *http.Request, key string, defaultValue int64) int64

FormInt64 checks if the request r has a Form value with the specified key that can be converted to an int64. If is doesn't, it will return defaultValue.

func FormString

func FormString(r *http.Request, key string, defaultValue string) string

FormString checks if the request r has a Form value with the specified key. If is doesn't, it will return defaultValue.

func InternalServerError

func InternalServerError(w http.ResponseWriter, r *http.Request, err interface{})

InternalServerError returns HTTP status 500 and an error message as HTML.

func IsGetOrHead

func IsGetOrHead(r *http.Request) bool

IsGetOrHead returns true if r is a GET or HEAD request.

func IsWebsocketUpgrade

func IsWebsocketUpgrade(req *http.Request) bool

IsWebsocketUpgrade returns true if this is a WebSocket upgrade.

func IsXHR

func IsXHR(r *http.Request) bool

IsXHR returns true if r is an XHR request. It inspects the Content-Type header for that.

func MustFormBool

func MustFormBool(r *http.Request, key string) bool

MustFormBool checks if the request r has a Form value with the specified key that can be converted to a bool. If is doesn't, it will panic.

func MustFormFloat64

func MustFormFloat64(r *http.Request, key string) float64

MustFormFloat64 checks if the request r has a Form value with the specified key that can be converted to a float64. If is doesn't, it will panic.

func MustFormInt

func MustFormInt(r *http.Request, key string) int

MustFormInt checks if the request r has a Form value with the specified key that can be converted to an int. If is doesn't, it will panic.

func MustFormInt32

func MustFormInt32(r *http.Request, key string) int32

MustFormInt32 checks if the request r has a Form value with the specified key that can be converted to an int32. If is doesn't, it will panic.

func MustFormInt64

func MustFormInt64(r *http.Request, key string) int64

MustFormInt64 checks if the request r has a Form value with the specified key that can be converted to an int64. If is doesn't, it will panic.

func MustFormString

func MustFormString(r *http.Request, key string) string

MustFormString checks if the request r has a Form value with the specified key of type string. If is doesn't, it will panic.

func MustParamsBool

func MustParamsBool(r *http.Request, key string) bool

MustParamsBool checks if the request r has a routing component with the specified key that can be converted to a bool. If is doesn't, it will panic.

func MustParamsFloat64

func MustParamsFloat64(r *http.Request, key string) float64

MustParamsFloat64 checks if the request r has a routing component with the specified key that can be converted to a float64. If is doesn't, it will panic.

func MustParamsInt

func MustParamsInt(r *http.Request, key string) int

MustParamsInt checks if the request r has a routing component with the specified key that can be converted to an int. If is doesn't, it will panic.

func MustParamsInt32

func MustParamsInt32(r *http.Request, key string) int32

MustParamsInt32 checks if the request r has a routing component with the specified key that can be converted to an int32. If is doesn't, it will panic.

func MustParamsInt64

func MustParamsInt64(r *http.Request, key string) int64

MustParamsInt64 checks if the request r has a routing component with the specified key that can be converted to an int64. If is doesn't, it will panic.

func MustParamsString

func MustParamsString(r *http.Request, key string) string

MustParamsString checks if the request r has a routing component with the specified key. If is doesn't, it will panic.

func MustQueryBool

func MustQueryBool(r *http.Request, key string) bool

MustQueryBool checks if the request r has a query string with the specified key that can be converted to a bool. If is doesn't, it will panic.

func MustQueryDuration added in v1.0.1

func MustQueryDuration(r *http.Request, key string) time.Duration

MustQueryDuration checks if the request r has a query string with the specified key that can be converted to a time.Duration. If is doesn't, it will return defaultValue or a zero time.

func MustQueryDurationWithDefault added in v1.0.1

func MustQueryDurationWithDefault(r *http.Request, key string, defaultValue time.Duration) time.Duration

MustQueryDurationWithDefault checks if the request r has a query string with the specified key that can be converted to a time.Duration. If is doesn't, it will return defaultValue or a zero time.

func MustQueryFloat64

func MustQueryFloat64(r *http.Request, key string) float64

MustQueryFloat64 checks if the request r has a query string with the specified key that can be converted to a float64. If is doesn't, it will panic.

func MustQueryInt

func MustQueryInt(r *http.Request, key string) int

MustQueryInt checks if the request r has a query string with the specified key that can be converted to an int. If is doesn't, it will panic.

func MustQueryInt32

func MustQueryInt32(r *http.Request, key string) int32

MustQueryInt32 checks if the request r has a query string with the specified key that can be converted to an int32. If is doesn't, it will panic.

func MustQueryInt64

func MustQueryInt64(r *http.Request, key string) int64

MustQueryInt64 checks if the request r has a query string with the specified key that can be converted to an int64. If is doesn't, it will panic.

func MustQueryString

func MustQueryString(r *http.Request, key string) string

MustQueryString checks if the request r has a query string with the specified key. If is doesn't, it will panic.

Example
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"

	"net/http/httptest"

	"github.com/olivere/httputil"
)

func main() {
	handler := func(w http.ResponseWriter, r *http.Request) {
		defer httputil.RecoverJSON(w, r)

		name := httputil.MustQueryString(r, "name")
		fmt.Fprintf(w, "Hello %s", name)
	}

	req := httptest.NewRequest("GET", "http://example.com/hello?name=Oliver", nil)
	w := httptest.NewRecorder()
	handler(w, req)

	resp := w.Result()
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)

	fmt.Println(string(body))
}
Output:

Hello Oliver

func MustQueryTime

func MustQueryTime(r *http.Request, key, layout string) time.Time

MustQueryTime checks if the request r has a query string with the specified key that can be converted to a time.Time, based on the given layout format. If is doesn't, it will return defaultValue or a zero time.

func MustQueryTimeWithDefault

func MustQueryTimeWithDefault(r *http.Request, key, layout string, defaultValue time.Time) time.Time

MustQueryTimeWithDefault checks if the request r has a query string with the specified key that can be converted to a time.Time, based on the given layout format. If is doesn't, it will return defaultValue or a zero time.

func MustReadJSON

func MustReadJSON(r *http.Request, dst interface{})

MustReadJSON is like ReadJSON, but panics on errors.

func ParamsBool added in v1.0.3

func ParamsBool(r *http.Request, key string, defaultValue bool) bool

ParamsBool checks if the request r has a routing component with the specified key. If is doesn't, it will return defaultValue.

func ParamsFloat64

func ParamsFloat64(r *http.Request, key string, defaultValue float64) float64

ParamsFloat64 checks if the request r has a routing component with the specified key that can be converted to a float64. If is doesn't, it will return defaultValue.

func ParamsInt

func ParamsInt(r *http.Request, key string, defaultValue int) int

ParamsInt checks if the request r has a routing component with the specified key that can be converted to an int. If is doesn't, it will return defaultValue.

func ParamsInt32

func ParamsInt32(r *http.Request, key string, defaultValue int32) int32

ParamsInt32 checks if the request r has a routing component with the specified key that can be converted to an int32. If is doesn't, it will return defaultValue.

func ParamsInt64

func ParamsInt64(r *http.Request, key string, defaultValue int64) int64

ParamsInt64 checks if the request r has a routing component with the specified key that can be converted to an int64. If is doesn't, it will return defaultValue.

func ParamsString

func ParamsString(r *http.Request, key string, defaultValue string) string

ParamsString checks if the request r has a routing component with the specified key. If is doesn't, it will return defaultValue.

func QueryBool

func QueryBool(r *http.Request, key string, defaultValue bool) bool

QueryBool checks if the request r has a query string with the specified key that can be converted to a bool. If is doesn't, it will return defaultValue.

func QueryDuration added in v1.0.1

func QueryDuration(r *http.Request, key string) time.Duration

QueryDuration checks if the request r has a query string with the specified key that can be converted to a time.Duration. If is doesn't, it will return defaultValue or a zero duration.

func QueryDurationWithDefault added in v1.0.1

func QueryDurationWithDefault(r *http.Request, key string, defaultValue time.Duration) time.Duration

QueryDurationWithDefault checks if the request r has a query string with the specified key that can be converted to a time.Duration. If is doesn't, it will return defaultValue or a zero duration.

func QueryFloat64

func QueryFloat64(r *http.Request, key string, defaultValue float64) float64

QueryFloat64 checks if the request r has a query string with the specified key that can be converted to a float64. If is doesn't, it will return defaultValue.

func QueryInt

func QueryInt(r *http.Request, key string, defaultValue int) int

QueryInt checks if the request r has a query string with the specified key that can be converted to an int. If is doesn't, it will return defaultValue.

func QueryInt32

func QueryInt32(r *http.Request, key string, defaultValue int32) int32

QueryInt32 checks if the request r has a query string with the specified key that can be converted to an int32. If is doesn't, it will return defaultValue.

func QueryInt64

func QueryInt64(r *http.Request, key string, defaultValue int64) int64

QueryInt64 checks if the request r has a query string with the specified key that can be converted to an int64. If is doesn't, it will return defaultValue.

func QueryString

func QueryString(r *http.Request, key string, defaultValue string) string

QueryString checks if the request r has a query string with the specified key. If is doesn't, it will return defaultValue.

func QueryStringArray

func QueryStringArray(r *http.Request, key string, defaultValue []string) []string

QueryStringArray checks if the request r has a query string with the specified key. If is doesn't, it will return defaultValue. Otherwise it'll split the string by a comma and return the resulting array.

func QueryTime

func QueryTime(r *http.Request, key, layout string) time.Time

QueryTime checks if the request r has a query string with the specified key that can be converted to a time.Time, based on the given layout format. If is doesn't, it will return defaultValue or a zero time.

func QueryTimeWithDefault

func QueryTimeWithDefault(r *http.Request, key, layout string, defaultValue time.Time) time.Time

QueryTimeWithDefault checks if the request r has a query string with the specified key that can be converted to a time.Time, based on the given layout format. If is doesn't, it will return defaultValue or a zero time.

func ReadJSON

func ReadJSON(r *http.Request, dst interface{}) error

ReadJSON deserializes the body of the request into dst as JSON. A maximum size of 8 MB of JSON are permitted.

Example
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"

	"github.com/olivere/httputil"
)

func main() {
	req := &http.Request{
		Body: ioutil.NopCloser(strings.NewReader(`{"name":"Oliver"}`)),
	}

	var person struct {
		Name string `json:"name"`
	}
	httputil.MustReadJSON(req, &person)

	fmt.Println(person.Name)
}
Output:

Oliver

func Recover

func Recover(w http.ResponseWriter, r *http.Request)

Recover can be used as a deferred func to catch panics in an HTTP handler.

func RecoverJSON

func RecoverJSON(w http.ResponseWriter, r *http.Request)

RecoverJSON can be used as a deferred func to catch panics in an HTTP handler and print a JSON error.

Example:

func Handler(w http.ResponseWriter, r *http.Request) {
  defer httputil.RecoverJSON(w, r)
  ...
  panic(errors.New("kaboom"))
}

func WriteError

func WriteError(w http.ResponseWriter, err interface{})

WriteError writes an error message for display in a HTML page.

func WriteJSON

func WriteJSON(w http.ResponseWriter, data interface{})

WriteJSON writes data as JSON into w with HTTP status code 200.

Example
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"

	"net/http/httptest"

	"github.com/olivere/httputil"
)

func main() {
	handler := func(w http.ResponseWriter, r *http.Request) {
		person := struct {
			Name string `json:"name"`
		}{
			Name: "Oliver",
		}
		httputil.WriteJSON(w, person)
	}

	req := httptest.NewRequest("GET", "http://example.com/", nil)
	w := httptest.NewRecorder()
	handler(w, req)

	resp := w.Result()
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)

	fmt.Println(string(body))
}
Output:

{
  "name": "Oliver"
}

func WriteJSONCode

func WriteJSONCode(w http.ResponseWriter, code int, data interface{})

WriteJSONCode writes data as JSON into w and sets the HTTP status code.

Example
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"

	"net/http/httptest"

	"github.com/olivere/httputil"
)

func main() {
	handler := func(w http.ResponseWriter, r *http.Request) {
		person := struct {
			Name string `json:"name"`
		}{
			Name: "Oliver",
		}
		httputil.WriteJSONCode(w, http.StatusCreated, person)
	}

	req := httptest.NewRequest("GET", "http://example.com/", nil)
	w := httptest.NewRecorder()
	handler(w, req)

	resp := w.Result()
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)

	fmt.Printf("Status: %d\n", resp.StatusCode)
	fmt.Println(string(body))
}
Output:

Status: 201
{
  "name": "Oliver"
}

func WriteJSONError

func WriteJSONError(w http.ResponseWriter, err interface{})

WriteJSONError writes error information, serialized in a JSON structure. Example:

{
  "error":{
    "code":    500,
    "message": "Something went wrong",
    "details": ["A was bad", "B is missing"]
  }
}

If err implements the httpCoder interface, it can specify the HTTP code to return. If err implements the httpErrorDetails interface, its ErrorDetails func is used to collect the error details; otherwise, the "details" field is missing in the error returned.

Types

type GrpcError

type GrpcError struct {
	Err error
}

GrpcError is a placeholder for a gRPC error, and will turn it into a HTTP error.

func (GrpcError) Error

func (e GrpcError) Error() string

Error returns the error message.

func (GrpcError) HTTPCode

func (e GrpcError) HTTPCode() int

HTTPCode returns the HTTP status code of the gRPC error.

type InvalidJSONError

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

InvalidJSONError indicates that the JSON data are invalid.

func (InvalidJSONError) HTTPCode

func (InvalidJSONError) HTTPCode() int

HTTPCode returns the HTTP status code of the error.

type InvalidMethodError

type InvalidMethodError struct{}

InvalidMethodError indicates that an invalid HTTP method is being used.

func (InvalidMethodError) Error

func (InvalidMethodError) Error() string

Error returns the error in text form.

func (InvalidMethodError) HTTPCode

func (InvalidMethodError) HTTPCode() int

HTTPCode returns the HTTP status code of the error.

type InvalidParameterError

type InvalidParameterError string

InvalidParameterError indicates that a parameter is invalid.

func (InvalidParameterError) Error

func (p InvalidParameterError) Error() string

Error returns the error in text form.

func (InvalidParameterError) HTTPCode

func (InvalidParameterError) HTTPCode() int

HTTPCode returns the HTTP status code of the error.

type InvalidXSRFToken

type InvalidXSRFToken struct{}

InvalidXSRFToken indicates that the user has not provided a valid XSRF token.

func (InvalidXSRFToken) Error

func (InvalidXSRFToken) Error() string

Error returns the error in text form.

func (InvalidXSRFToken) HTTPCode

func (InvalidXSRFToken) HTTPCode() int

HTTPCode returns the HTTP status code of the error.

type MissingParameterError

type MissingParameterError string

MissingParameterError indicates that a required parameter is missing or blank.

Example
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"

	"net/http/httptest"

	"github.com/olivere/httputil"
)

func main() {
	handler := func(w http.ResponseWriter, r *http.Request) {
		defer httputil.RecoverJSON(w, r)

		name := httputil.QueryString(r, "name", "")
		if name == "" {
			panic(httputil.MissingParameterError("name"))
		}

		httputil.WriteJSONCode(w, http.StatusOK, struct {
			Message string `json:"name"`
		}{
			Message: fmt.Sprintf("Hello %s", name),
		})
	}

	req := httptest.NewRequest("GET", "http://example.com/hello?name=", nil)
	w := httptest.NewRecorder()
	handler(w, req)

	resp := w.Result()
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)

	fmt.Printf("Status: %d\n", resp.StatusCode)
	fmt.Println(string(body))
}
Output:

Status: 400
{
  "error": {
    "code": 400,
    "message": "Missing parameter \"name\""
  }
}

func (MissingParameterError) Error

func (p MissingParameterError) Error() string

Error returns the error in text form.

func (MissingParameterError) HTTPCode

func (MissingParameterError) HTTPCode() int

HTTPCode returns the HTTP status code of the error.

type NotFoundError

type NotFoundError struct{}

NotFoundError indicates that a record or resource does not exist.

func (NotFoundError) Error

func (NotFoundError) Error() string

Error returns the error in text form.

func (NotFoundError) HTTPCode

func (NotFoundError) HTTPCode() int

HTTPCode returns the HTTP status code of the error.

type NotImplementedError

type NotImplementedError struct{}

NotImplementedError indicates that an endpoint has yet to be implemented.

func (NotImplementedError) Error

func (NotImplementedError) Error() string

Error returns the error in text form.

func (NotImplementedError) HTTPCode

func (NotImplementedError) HTTPCode() int

HTTPCode returns the HTTP status code of the error.

type ServerError

type ServerError string

ServerError indicates any kind of internal server problem.

func (ServerError) Error

func (e ServerError) Error() string

Error returns the error in text form.

func (ServerError) HTTPCode

func (ServerError) HTTPCode() int

HTTPCode returns the HTTP status code of the error.

type TimeoutError

type TimeoutError struct{}

TimeoutError indicates that the request has timed out.

func (TimeoutError) Error

func (TimeoutError) Error() string

Error returns the error in text form.

func (TimeoutError) HTTPCode

func (TimeoutError) HTTPCode() int

HTTPCode returns the HTTP status code of the error.

type UnauthorizedError

type UnauthorizedError struct{}

UnauthorizedError indicates that credentials are either missing or invalid.

func (UnauthorizedError) Error

func (UnauthorizedError) Error() string

Error returns the error in text form.

func (UnauthorizedError) HTTPCode

func (UnauthorizedError) HTTPCode() int

HTTPCode returns the HTTP status code of the error.

type UnprocessableEntityError

type UnprocessableEntityError struct {
	Errors []string
}

UnprocessableEntityError indicates that there was a semantic error in parsing a request, e.g. a record with validation errors.

func (UnprocessableEntityError) Error

Error returns the error in text form.

func (UnprocessableEntityError) ErrorDetails

func (p UnprocessableEntityError) ErrorDetails() []string

ErrorDetails returns additional information about the error.

func (UnprocessableEntityError) HTTPCode

func (UnprocessableEntityError) HTTPCode() int

HTTPCode returns the HTTP status code of the error.

Jump to

Keyboard shortcuts

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