rewrite

package
v3.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2025 License: BSD-3-Clause Imports: 10 Imported by: 0

README

go-http/v3/rewrite

Go package for creating net/http middleware handlers to alter the contents of other (net/http) handlers.

Example

Error handler omitted for brevity.

AppendResourcesHandler

Middleware handler to append custom JavaScript and CSS tags or data attributes to the HTML output of a previous handler.

package main

import (
	"io"
	"log"
	"net/http"
	"testing"
)

func baseAppendHandler() http.Handler {

	fn := func(rsp http.ResponseWriter, req *http.Request) {
		rsp.Header().Set("Content-type", "text/html")
		rsp.Write([]byte(`<html><head><title>Test</title></head><body>Hello world</body><html>`))
	}

	h := http.HandlerFunc(fn)
	return h
}

func main() {

	append_opts := &AppendResourcesOptions{
		JavaScript:     []string{"test.js"},
		Stylesheets:    []string{"test.css"},
		DataAttributes: map[string]string{"example": "example"},
	}

	append_handler := baseAppendHandler()

	append_handler = AppendResourcesHandler(append_handler, append_opts)

	s := &http.Server{
		Addr:    ":8080",
		Handler: append_handler,
	}

	defer s.Close()

	go s.ListenAndServe()

	rsp, _ := http.Get("http://localhost:8080")

	defer rsp.Body.Close()

	body, _ := io.ReadAll(rsp.Body)
	fmt.Println(string(body))

	// Prints:
	// <html><head><title>Test</title><script type="text/javascript" src="test.js"></script><link type="text/css" rel="stylesheet" href="test.css"/></head><body data-example="example">Hello world</body></html>
	
}
RewriteHTMLHandler

Middleware handler to rewrite the HTML output of a previous handler.

package main

import (
	"golang.org/x/net/html"
	"io"
	"log"
	"net/http"
	"testing"
)

func baseRewriteHandler() http.Handler {

	fn := func(rsp http.ResponseWriter, req *http.Request) {
		rsp.Header().Set("Content-type", "text/html")
		rsp.Write([]byte(`<html><head><title>Test</title></head><body><p>hello world</p></body></html>`))
	}

	h := http.HandlerFunc(fn)
	return h
}

func main() {

	var rewrite_func RewriteHTMLFunc

	rewrite_func = func(n *html.Node, wr io.Writer) {

		if n.Type == html.ElementNode && n.Data == "p" {
			n.FirstChild.Data = "HELLO WORLD"
		}

		for c := n.FirstChild; c != nil; c = c.NextSibling {
			rewrite_func(c, wr)
		}

	}

	rewrite_handler := baseRewriteHandler()

	rewrite_handler = RewriteHTMLHandler(rewrite_handler, rewrite_func)

	s := &http.Server{
		Addr:    ":9434",
		Handler: rewrite_handler,
	}

	defer s.Close()

	go s.ListenAndServe()

	rsp, _ := http.Get("http://localhost:9434")

	defer rsp.Body.Close()

	body, _ := io.ReadAll(rsp.Body)
	log.Println(string(body))
	
	// Prints
	// <html><head><title>Test</title></head><body><p>HELLO WORLD</p></body></html>
}
RewriteRequestHandler

Middleware handler to modify the http.Request instance passed to another handler before invoking it.

package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"testing"
)

func baseRequestHandler() http.Handler {

	fn := func(rsp http.ResponseWriter, req *http.Request) {

		msg := req.Header.Get("X-Message")

		// See the way there is no input validation on msg? Don't do this in production...
		
		body := fmt.Sprintf("<html><head><title>Test</title></head><body><p>%s</p></body></html>", msg)
		rsp.Header().Set("Content-type", "text/html")
		rsp.Write([]byte(body))
	}

	h := http.HandlerFunc(fn)
	return h
}

func TestRewriteRequestHandler(t *testing.T) {

	rewrite_func := func(req *http.Request) (*http.Request, error) {
		req.Header.Set("X-Message", "hello world")
		return req, nil
	}

	request_handler := baseRequestHandler()

	request_handler = RewriteRequestHandler(request_handler, rewrite_func)

	s := &http.Server{
		Addr:    ":9664",
		Handler: request_handler,
	}

	defer s.Close()

	go s.ListenAndServe()

	rsp, _ := http.Get("http://localhost:9664")

	defer rsp.Body.Close()

	body, _ := io.ReadAll(rsp.Body)
	log.Println(string(body))

	// Prints:
	// <html><head><title>Test</title></head><body><p>hello world</p></body></html>
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AppendResourcesHandler

func AppendResourcesHandler(previous_handler http.Handler, opts *AppendResourcesOptions) http.Handler

AppendResourcesHandler() creates a `RewriteHTMLFunc` callback function, configured by 'opts', and uses that callback function and 'previous_handler' to invoke the `RewriteHTMLHandler` function. All of this will cause the output of 'previous_handler' to be rewritten to append headers and data attributes defined in 'opts'.

func RewriteHTMLHandler

func RewriteHTMLHandler(previous_handler go_http.Handler, rewrite_func RewriteHTMLFunc) go_http.Handler

RewriteHTMLHandler return a `net/http` middleware handle to alter the body of 'previous_handler' using 'rewrite_func'. Content is only altered if and when the "Content-Type" header (returned by 'previous_handler') is "text/html". If not the unaltered body is returned as-is.

func RewriteRequestHandler

func RewriteRequestHandler(next go_http.Handler, rewrite_func RewriteRequestFunc) go_http.Handler

RewriteRequestHandler() creates a `net/http` middleware handler that invokes 'rewrite_func' with the current request to create a new or updated `http.Request` instance used to serve 'next'.

Types

type AppendResourcesOptions

type AppendResourcesOptions struct {
	// A list of JavaScript URIs to append to an HTML document's `<head>` element as `<script>` tags.
	JavaScript []string
	// A list of CSS URIs to append to an HTML document's `<head>` element as `<link rel="stylesheet">` tags.
	Stylesheets []string
	// A dictionary of key and value pairs to append to an HTML document's <body> element as `data-{KEY}="{VALUE}` attributes.
	DataAttributes map[string]string
	// AppendJavaScriptAtEOF is a boolean flag to append JavaScript markup at the end of an HTML document
	// rather than in the <head> HTML element. Default is false
	AppendJavaScriptAtEOF bool
}

AppendResourcesOptions is a struct containing configuration options for the `AppendResourcesHandler` method.

type RewriteHTMLFunc

type RewriteHTMLFunc func(node *html.Node, writer io.Writer)

RewriteHTMLFunc is custom callback function for altering the HTML content of 'node'

type RewriteRequestFunc

type RewriteRequestFunc func(req *go_http.Request) (*go_http.Request, error)

RewriteRequestFunc is a custom callback function for creating a new `http.Request` instance derived from 'req'.

Jump to

Keyboard shortcuts

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