xhttp

package module
v0.0.0-...-891d2fd Latest Latest
Warning

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

Go to latest
Published: Feb 18, 2022 License: BSD-3-Clause Imports: 6 Imported by: 1

README

xhttp

GoDoc

Description

This package defines a wrapper around the *http.ServeMux that can be found in Go's Standard library. The goal is to provide convenience methods to register request handlers and facilitate the usage of an execution context per goroutine spawned (which should be the norm).

What are the main additions compared to net/http?

The ServeMux wrapper allows to define a deadline for the completion of subtasks that would be launched on behalf of the request handling goroutine.

Convenience methods for request handler registration are also provided.

Lastly, two new interfaces are defined:

  • xhttp.Handler
  • xhttp.HandlerLinker

An xhttp.Handler differs from the traditional http.Handler by the signature of its ServeHTTP method: it demands to be provided with one more argument which is an execution.Context.

An xhttp.HandlerLinker enables the linking of two Handler objects so that one can call the other. By recursion, it allows to create a linked list (chain) of handlers.


 // Handler ServeHTTP signature from the standard library.
ServeHTTP(w http.ResponseWriter, r *http.Request)

// Handler ServeHTTP signature from the xhttp package.
ServeHTTP(ctx execution.Context, w http.ResponseWriter, r *http.Request)

// HandlerLinker ServeHTTP and Link signatures from the xhttp package.
ServeHTTP(ctx execution.Context, w http.ResponseWriter, r *http.Request)
Link(h Handler) HandlerLinker

Convenience methods

As a wrapper around *http.ServeMux, we have defined several methods that should render the task of registering request handlers per route and verb easier.

Registration consists in defining a handler and using it as argument.

s := xhttp.NewServeMux()

s.GET("/foo",someHandler)
s.PUT("/bar/", someOtherHandler)

where someHandler and someOtherHandler implement the Handler interface.

To register handlers that apply regardless of the request verb, the USE variadic method, which accepts linkable handlers as arguments, exists :


s.USE(handlerlinkerA, handlerlinkerB, handlerlinkerC)
// Calling it again will queue another handler to the previous list
// For instance here, handlerlinkerD will be called right after
// handlerlinkerC
s.USE(handlerlinkerD)

More about chaining/linking Handler objects

If a given route & request.Method requires a response to be processed by a chain of handlers, the xhttp.Chain function can be used to create such a chain.

postHandler := xhttp.Chain(hlinkerA, hlinkerB, hlinkerC).Link(Handler)
s.POST("/foobar", postHandler)

Basic Handlers

The /handler/ subfolder contains some general use request handlers for response compression, CSRF protection, session management,...

License

BSD 3-clause

Documentation

Overview

Package xhttp provides a convenience wrapper around a net/http multiplexer. Its main goal is to provide an easier configuration of the multiplexer.

Example
package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"

	"github.com/atdiar/xhttp"
)

const (
	A = "A rainbow "
	B = "Be very "
	C = "Colorful "
)

func main() {
	s := xhttp.NewServeMux()
	m := xhttp.Chain(middlewareExample{A, nil}, middlewareExample{B, nil}, middlewareExample{C, nil})
	s.USE(m)

	s.GET("/go/14", xhttp.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
		a := req.Context().Value(A)
		if a == nil {
			fmt.Fprint(res, "Couldn't find a value in the context object for A") // shall make the test fail
		}
		fmt.Fprint(res, a)

		b := req.Context().Value(B)
		if b == nil {
			fmt.Fprint(res, "Couldn't find a value in the context object for B") // shall make the test fail
		}
		fmt.Fprint(res, b)

		c := req.Context().Value(C)
		if c == nil {
			fmt.Fprint(res, "Couldn't find a value in the context object for C") // shall make the test fail
		}
		fmt.Fprint(res, c)
	}))

	s.GET("/test", xhttp.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "test")
	}))

	s.GET("/test/3564", xhttp.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "ok")
	}))

	s.POST("/test/3564", xhttp.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "this is a post request")
	}))

	req, err := http.NewRequest("GET", "http://example.com/go/14", nil)
	if err != nil {
		log.Fatal(err)
	}

	w := httptest.NewRecorder()
	s.ServeHTTP(w, req)

	fmt.Printf("%d - %s", w.Code, w.Body.String())
}

// Let's create a catchAll Handler i.e. an object implementing HandlerLinker.
// It's also what people may call a catchall middleware.
// This should illustrate one of the form a HandlerLinker can take.
type middlewareExample struct {
	string
	next xhttp.Handler
}

func (m middlewareExample) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "OK ")
	c := context.WithValue(r.Context(), m.string, m.string)
	r = r.WithContext(c)
	if m.next != nil {
		m.next.ServeHTTP(w, r)
	}
}

func (m middlewareExample) Link(h xhttp.Handler) xhttp.HandlerLinker {
	m.next = h
	return m
}
Output:

200 - OK OK OK A rainbow Be very Colorful

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func PathMatch

func PathMatch(req *http.Request, pattern string, vars map[string]string) bool

PathMatch allows for the retrieval of URL parameters by name when an URL matches a given pattern. For instance https://example.com/track/2589556/comments/1879545 will match the following pattern https://example.com/track/:tracknumber/comments/:commentnumber In the vars map, we will have the following key/value pairs entered: ("tracknumber","2589556") and ("commentnumber","1879545") NB Everything remains stored as strings. This function should be used on a path registered in the muxer as /track/

func WriteJSON

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

WriteJSON can be used to write a json encoded response

Types

type Handler

type Handler = http.Handler

Handler is the interface implemented by a request servicing object. If Handler is not also a HandlerLinker, it means that it can not call for further processing.

type HandlerFunc

type HandlerFunc = http.HandlerFunc

HandlerFunc defines a type of functions implementing the Handler interface.

type HandlerLinker

type HandlerLinker interface {
	ServeHTTP(w http.ResponseWriter, r *http.Request)
	Link(Handler) HandlerLinker
}

HandlerLinker is the interface of a request Handler to which we can attach another Handler. It enables the ServeHTTP method of the attached handler to be called from the ServeHTTP method of the first handler, if needed. The Link method returns the fully linked HandlerLinker.

func Chain

func Chain(handlers ...HandlerLinker) HandlerLinker

Chain is a function that is used to create a chain of Handlers when provided with linkable Handlers (they must implement HandlerLinker). It returns the first link of the chain.

func LinkableHandler

func LinkableHandler(h Handler) HandlerLinker

LinkableHandler is a function that tunr an Handler into a HandlerLinker suitable for further chaining. If the Handler happens to modify the context object, it should make sure to swap the *http.Request internal context for the new updated context via the WithContext method. A LinkableHandler always uses a cancelable context whose cancellation function can be retrieved by using the xhttp.CancelingKey.

type ServeMux

type ServeMux struct {
	Once *sync.Once

	ServeMux *http.ServeMux
	// contains filtered or unexported fields
}

ServeMux holds the multiplexing logic of incoming http requests. It wraps around a net/http multiplexer. It facilitates the registration of request handlers.

func NewServeMux

func NewServeMux() ServeMux

NewServeMux creates a new multiplexer wrapper which holds the request servicing logic. The mux wrapped by default is http.DefaultServeMux. That can be changed by using the ChangeMux configuration option.

func (*ServeMux) CONNECT

func (sm *ServeMux) CONNECT(pattern string, h Handler)

CONNECT registers the request Handler for the servicing of http CONNECT requests.

func (*ServeMux) DELETE

func (sm *ServeMux) DELETE(pattern string, h Handler)

DELETE registers the request Handler for the servicing of http DELETE requests.

func (*ServeMux) GET

func (sm *ServeMux) GET(pattern string, h Handler)

GET registers the request Handler for the servicing of http GET requests. It also handles HEAD requests wby creating an identical response to GET requests without the request body.

func (*ServeMux) OPTIONS

func (sm *ServeMux) OPTIONS(pattern string, h Handler)

OPTIONS registers the request Handler for the servicing of http OPTIONS requests.

func (*ServeMux) PATCH

func (sm *ServeMux) PATCH(pattern string, h Handler)

PATCH registers the request Handler for the servicing of http PATCH requests.

func (*ServeMux) POST

func (sm *ServeMux) POST(pattern string, h Handler)

POST registers the request Handler for the servicing of http POST requests.

func (*ServeMux) PUT

func (sm *ServeMux) PUT(pattern string, h Handler)

PUT registers the request Handler for the servicing of http PUT requests.

func (ServeMux) ServeHTTP

func (sm ServeMux) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP is the request-servicing function for an object of type ServeMux.

func (*ServeMux) TRACE

func (sm *ServeMux) TRACE(pattern string, h Handler)

TRACE registers the request Handler for the servicing of http TRACE requests.

func (*ServeMux) USE

func (sm *ServeMux) USE(handlers ...HandlerLinker)

USE registers linkable request Handlers (i.e. implementing HandlerLinker) which shall be servicing any path, regardless of the request method. This function should only be called once.

Directories

Path Synopsis
handlers
compression
Package compression defines a response compressing Handler.
Package compression defines a response compressing Handler.
content
Package content enables one to serve a data range out of a http requested file.
Package content enables one to serve a data range out of a http requested file.
cors
Package cors implements the server-side logic that is employed in response to a Cross Origin request.
Package cors implements the server-side logic that is employed in response to a Cross Origin request.
csrf
Package csrf implements a request handler which generates a token to protect against Cross-Site Request Forgery.
Package csrf implements a request handler which generates a token to protect against Cross-Site Request Forgery.
dynamux
Package dynamux defines a multiplexing helper for url generated at runtime.
Package dynamux defines a multiplexing helper for url generated at runtime.
fileserve
Package fileserve enables the serving of a static file or an entire directory.
Package fileserve enables the serving of a static file or an entire directory.
hsts
Package hsts is used to enforce a Strict Transport Security.
Package hsts is used to enforce a Strict Transport Security.
panic
Package panic defiens a panic handler that deals with panics occuring during the handling of a http request.
Package panic defiens a panic handler that deals with panics occuring during the handling of a http request.
session
Package session defines a request handler that helps for the instantiation of client/server sessions.
Package session defines a request handler that helps for the instantiation of client/server sessions.
sse

Jump to

Keyboard shortcuts

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