methodoverride

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package methodoverride provides middleware that overrides the HTTP request method using either a request header or a query-string parameter. This lets HTML forms (which can only issue GET and POST) emulate verbs such as PUT, PATCH, and DELETE. It is the Go port of the Node method-override middleware (the method-override npm package used with connect/express), reproducing its core header- and query-based override behavior with only the standard library.

Use this middleware in front of a route table that is built around REST verbs but must be reachable from plain HTML forms or clients that can only send POST. By letting a form carry the intended verb in a hidden _method field or in the X-HTTP-Method-Override header, you can keep RESTful routes (app.Put, app.Delete, app.Patch) while the browser still submits an ordinary POST. It is equally useful for constrained HTTP clients or proxies that strip non-standard verbs.

Register it early — before the router matches — so the rewritten method is used for route dispatch. On each request the handler first checks whether the incoming method is POST; only then does it look for an override. It reads the configured header via req.Get, and if that is empty falls back to the configured query parameter via req.Query. If a value is found it upper-cases it and writes it back to req.Raw.Method, mutating the underlying *http.Request in place so every downstream handler and the router observe the new verb. In all cases the handler calls next() and never writes a response itself; it only rewrites request state.

Two options control the source names: Header (default DefaultHeader, "X-HTTP-Method-Override") and Query (default DefaultQuery, "_method"). The header takes precedence over the query parameter when both are present. The override is deliberately applied only to POST requests — matching the common convention that overrides ride on a form submission — so a GET carrying _method=delete is left untouched and keeps its original verb. Values are upper-cased but otherwise unvalidated, so a bogus override such as _method=foo will set the method to "FOO" and typically fall through to no matching route; callers that accept untrusted input should constrain the allowed verbs upstream.

The chief security consideration is that this middleware lets a client change the effective HTTP method, which can bypass method-based assumptions in later handlers or upstream access rules — only enable it where form-driven verb emulation is actually wanted, and be mindful that CSRF protections must account for the overridden verb. Compared with the Node original, this port keeps the header-then-query precedence and the POST-only rule while adopting Go idioms: exported DefaultHeader/DefaultQuery constants, a struct of Options instead of a callback-style getter, and a direct write to req.Raw.Method rather than stashing the original method on the request object.

Index

Examples

Constants

View Source
const DefaultHeader = "X-HTTP-Method-Override"

DefaultHeader is the header consulted for the overriding method.

View Source
const DefaultQuery = "_method"

DefaultQuery is the query-string parameter consulted for the overriding method.

Variables

This section is empty.

Functions

func New

func New(opts ...Options) express.Handler

New returns middleware that rewrites req.Raw.Method from the configured header or query parameter. The header takes precedence over the query parameter. The override is only applied to POST requests, matching the common convention that overrides ride on a form submission.

Example

ExampleNew demonstrates letting an HTML-form-style POST emulate a DELETE by carrying the intended verb in the X-HTTP-Method-Override header. The override middleware is registered first so the request method is rewritten before any downstream handler observes it, and a second handler captures req.Method() to show the effective verb after the rewrite. The example builds a POST request with the default override header set to "delete", then drives it through the express application with net/http/httptest. Because the middleware only acts on POST requests and upper-cases the override value, the downstream handler sees "DELETE", which the example prints deterministically.

package main

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

	"github.com/malcolmston/express"
	"github.com/malcolmston/express/middleware/methodoverride"
)

func main() {
	app := express.New()
	app.Use(methodoverride.New())
	app.Use(func(req *express.Request, res *express.Response, next express.Next) {
		fmt.Println("effective method:", req.Method())
		res.Send("ok")
	})

	req := httptest.NewRequest(http.MethodPost, "/", nil)
	req.Header.Set(methodoverride.DefaultHeader, "delete")
	app.ServeHTTP(httptest.NewRecorder(), req)

}
Output:
effective method: DELETE

Types

type Options

type Options struct {
	// Header is the request header inspected for an override. When empty,
	// DefaultHeader is used.
	Header string

	// Query is the query-string parameter inspected for an override. When
	// empty, DefaultQuery is used.
	Query string
}

Options configures the method-override middleware.

Jump to

Keyboard shortcuts

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