content

package
v0.0.0-...-9392aba Latest Latest
Warning

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

Go to latest
Published: Nov 25, 2024 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package content provides handlers for common http server content.

Handlers in this package return an error, and handle panic()s in such a way that they are not passed to the parent.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func WriteHTML

func WriteHTML[C any](context C, err error, template *template.Template, w http.ResponseWriter, r *http.Request) error

WriteHTML writes an html response to r into w.

The response to be written is generated by rendering the template with the given context. The response is automatically minified.

If err is not nil, an error response is rendered instead, see httpx.HTMLInterceptor.

func WriteHTMLI

func WriteHTMLI[C any](context C, err error, template *template.Template, interceptor httpx.ErrInterceptor, w http.ResponseWriter, r *http.Request) error

WriteHTMLI is like WriteHTML, but uses a custom error interceptor.

func WriteJSON

func WriteJSON[T any](result T, err error, w http.ResponseWriter, r *http.Request) error

WriteJSON writes a JSON response of type T to w. If an error occurred, httpx.JSONInterceptor is used instead.

func WriteJSONI

func WriteJSONI[T any](result T, err error, interceptor httpx.ErrInterceptor, w http.ResponseWriter, r *http.Request) error

WriteJSONI is like WriteJSON but uses a custom interceptor.

Types

type HTMLHandler

type HTMLHandler[C any] struct {
	Handler func(r *http.Request) (C, error)

	Template *template.Template // Template is the template to be rendered into responses

	Interceptor             httpx.ErrInterceptor
	LogTemplateExecuteError httpx.ErrorLogger
}

HTMLHandler is a http.Handler that responds to requests with html.

C is the type of the context to be passed to the Template

func (HTMLHandler[T]) ServeHTTP

func (h HTMLHandler[T]) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP calls the handler, and then passes it and the template to WriteHTML.

type JSONHandler

type JSONHandler[T any] struct {
	Handler func(r *http.Request) (T, error)

	Interceptor        httpx.ErrInterceptor
	LogJSONEncodeError httpx.ErrorLogger
}

JSONHandler implements http.Handler by marshaling values as json to the caller. In case of an error, a generic "internal server error" message is returned.

func JSON

func JSON[T any](f func(r *http.Request) (T, error)) JSONHandler[T]

JSON creates a new JSONHandler based on the given function. The Interceptor will be httpx.JSONInterceptor.

Example
// create a redirect based on the url
handler := content.JSON(func(r *http.Request) (any, error) {
	switch r.URL.Path {
	case "/value":
		return 69, nil
	case "/slice":
		return []any{"hello", 42}, nil
	case "/notfound":
		return nil, httpx.ErrNotFound
	case "/broken_marshal":
		return BrokenMarshalJSON{}, nil
	}
	panic("other error")
})
// invoke the handler a bunch of times
fmt.Println(makeRequest(handler, "/value"))
fmt.Println(makeRequest(handler, "/slice"))
fmt.Println(makeRequest(handler, "/notfound"))
fmt.Println(makeRequest(handler, "/other"))
fmt.Println(makeRequest(handler, "/broken_marshal"))
Output:

/value returned code 200 with location header "" and body "69\n"
/slice returned code 200 with location header "" and body "[\"hello\",42]\n"
/notfound returned code 404 with location header "" and body "{\"code\":404,\"status\":\"Not Found\"}"
/other returned code 500 with location header "" and body "{\"code\":500,\"status\":\"Internal Server Error\"}"
/broken_marshal returned code 500 with location header "" and body ""

func (JSONHandler[T]) ServeHTTP

func (j JSONHandler[T]) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP calls j(r) and returns json

type RedirectFunc

type RedirectFunc func(r *http.Request) (location string, code int, err error)

RedirectFunc is invoked with an http.Request to determine the redirect behavior for a specific function.

location should be the destination of the redirect. code should indicate the type of redirect, typically one of http.StatusFound, http.StatusTemporaryRedirect or http.StatusPermanentRedirect. error indicates any error that occurred.

If error is non-nil it is intercepted by an appropriate httpx.ErrInterceptor.

type RedirectHandler

type RedirectHandler struct {
	Handler     RedirectFunc
	Interceptor httpx.ErrInterceptor
}

RedirectHandler is a http.Handler that redirects every request based on the result of invoking Handler.

func Redirect

func Redirect(Handler RedirectFunc) RedirectHandler

Redirect creates a new RedirectHandler based on the given function. The Interceptor will be httpx.TextInterceptor.

Example
package main

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

	"github.com/tkw1536/pkglib/httpx"
	"github.com/tkw1536/pkglib/httpx/content"
)

func main() {

	// create a redirect based on the url
	handler := content.Redirect(func(r *http.Request) (string, int, error) {
		switch r.URL.Path {
		case "/temporary.example":
			return "https://example.com/", http.StatusTemporaryRedirect, nil
		case "/permanent.example":
			return "https://example.com/", http.StatusPermanentRedirect, nil
		case "/notfound":
			return "", 0, httpx.ErrNotFound
		}
		panic("never reached")
	})

	makeRequest := func(path string) {
		req, err := http.NewRequest(http.MethodGet, path, nil)
		if err != nil {
			panic(err)
		}

		rr := httptest.NewRecorder()
		handler.ServeHTTP(rr, req)

		rrr := rr.Result()
		body, _ := io.ReadAll(rrr.Body)
		fmt.Printf("%s returned code %d with location header %q and body %q\n", path, rrr.StatusCode, rrr.Header.Get("Location"), string(body))
	}

	// invoke the handler a bunch of times
	makeRequest("/temporary.example")
	makeRequest("/permanent.example")
	makeRequest("/notfound")
}
Output:

/temporary.example returned code 307 with location header "https://example.com/" and body "<a href=\"https://example.com/\">Temporary Redirect</a>.\n\n"
/permanent.example returned code 308 with location header "https://example.com/" and body "<a href=\"https://example.com/\">Permanent Redirect</a>.\n\n"
/notfound returned code 404 with location header "" and body "Not Found"

func (RedirectHandler) ServeHTTP

func (rh RedirectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP calls r(r) and returns json

Jump to

Keyboard shortcuts

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