replaceresponse

package module
v0.0.0-...-f13df32 Latest Latest
Warning

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

Go to latest
Published: Jan 29, 2024 License: Apache-2.0 Imports: 13 Imported by: 0

README

Caddy replace_response handler module

This Caddy module performs substring and regular expression replacements on response bodies, hence the name replace_response.

By default, this module operates in "buffer" mode. This is not very memory-efficient, but it guarantees we can always set the correct Content-Length header because we can buffer the output to know the resulting length before writing the response. If you need higher efficiency, you can enable "streaming" mode. When performing replacements on a stream, the Content-Length header may be removed because it is not always possible to know the correct value, since the results are streamed directly to the client and headers must be written before the body.

Note: This handler cannot perform replacements on compressed content. If your response comes from a proxied backend that supports compression, you will either have to decompress it in a response handler chain before this handler runs, or disable from the backend. One easy way to ask the backend to not compress the response is to set the Accept-Encoding header to identity, for example: header_up Accept-Encoding identity (in your Caddyfile, in the reverse_proxy block).

This module supports the use of placeholders in the search and replace arguments (but not regexes).

Module name: http.handlers.replace_response

JSON examples

Substring substitution:

{
	"handler": "replace_response",
	"replacements": [
		{
			"search": "Foo",
			"replace": "Bar"
		}
	]
}

Regular expression replacement:

{
	"handler": "replace_response",
	"replacements": [
		{
			"search_regexp": "\\s+foo(bar|baz)\\s+",
			"replace": " foo $1 "
		}
	]
}

Same, but with streaming mode (we just set "stream": true in the handler):

{
	"handler": "replace_response",
	"replacements": [
		{
			"search_regexp": "\\s+foo(bar|baz)\\s+",
			"replace": " foo $1 "
		}
	],
	"stream": true
}

Caddyfile

This module has Caddyfile support. It registers the replace directive. Make sure to order the handler directive in the correct place in the middleware chain; usually this works well:

{
	order replace after encode
}

Syntax:

replace [stream | [re] <search> <replace>] {
	stream
	[re] <search> <replace>
}
  • re indicates a regular expression instead of substring.
  • stream enables streaming mode.

Simple substring substitution:

replace Foo Bar

Regex replacement:

replace re "\s+foo(bar|baz)\s+" " foo $1 "

Streaming mode:

replace stream {
	Foo Bar
}

Multiple replacements:

replace {
	Foo Bar
	re "\s+foo(bar|baz)\s+" " foo $1 "
	A B
}

Limitations:

  • Regex matches longer than 2kb will not be replaced.

  • Compressed responses (e.g. from an upstream proxy which gzipped the response body) will not be decoded before attempting to replace. To work around this, you may send the Accept-Encoding: identity request header to the upstream to tell it not to compress the response. For example:

    reverse_proxy localhost:8080 {
        header_up Accept-Encoding identity
    }
    

Documentation

Overview

Package replaceresponse registers a Caddy HTTP handler module that performs replacements on response bodies.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Handler

type Handler struct {
	// The list of replacements to make on the response body.
	Replacements []*Replacement `json:"replacements,omitempty"`

	// If true, perform replacements in a streaming fashion.
	// This is more memory-efficient but can remove the
	// Content-Length header since knowing the correct length
	// is impossible without buffering, and getting it wrong
	// can break HTTP/2 streams.
	Stream bool `json:"stream,omitempty"`
	// contains filtered or unexported fields
}

Handler manipulates response bodies by performing substring or regex replacements.

func (Handler) CaddyModule

func (Handler) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information.

func (*Handler) Provision

func (h *Handler) Provision(ctx caddy.Context) error

Provision implements caddy.Provisioner.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error

ServeHTTP implements caddyhttp.MiddlewareHandler.

func (*Handler) UnmarshalCaddyfile

func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile implements caddyfile.Unmarshaler. Syntax:

replace [stream | [re] <search> <replace>] {
     stream
     [re] <search> <replace>
}

If 're' is specified, the search string will be treated as a regular expression. If 'stream' is specified, the replacement will happen without buffering the whole response body; this might remove the Content-Length header.

type Replacement

type Replacement struct {
	// A substring to search for. Mutually exclusive with search_regexp.
	Search string `json:"search,omitempty"`

	// A regular expression to search for. Mutually exclusive with search.
	SearchRegexp string `json:"search_regexp,omitempty"`

	// The replacement string/value. Required.
	Replace string `json:"replace"`
	// contains filtered or unexported fields
}

Replacement is either a substring or regular expression replacement to perform; precisely one must be specified, not both.

Jump to

Keyboard shortcuts

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