add a pattern argument to Mux

This commit is contained in:
Patricio Whittingslow
2026-07-26 22:55:50 -03:00
parent e46e45238d
commit 75d2c0c46d
3 changed files with 19 additions and 5 deletions
+8
View File
@@ -38,6 +38,8 @@ type Exchange struct {
hijacked bool
rw conn
matchedPattern string
respRemains int
respErr error // Sticky: response is unrecoverable once a write fails.
headerWritten bool
@@ -97,6 +99,7 @@ func (exch *Exchange) Acquire(conn conn) bool {
if !exch.used.CompareAndSwap(false, true) {
return false
}
exch.matchedPattern = ""
exch.gen.Add(1)
exch.readErr = nil
exch.respErr = nil
@@ -366,6 +369,11 @@ func (exch *Exchange) remainingSurplusBody() ([]byte, error) {
return toRead, nil
}
// MuxPattern returns the pattern [Mux] matched to the request.
func (exch *Exchange) MuxPattern() string {
return exch.matchedPattern
}
// RequestHeaderRaw returns the parsed request header for access beyond the
// Request* methods, such as [httpraw.Header.ForEach]. Valid until the exchange
// is released, and writing to it corrupts the response.
+3
View File
@@ -4,7 +4,9 @@ import (
"context"
"errors"
"io"
"net/http"
"strings"
"unsafe"
"testing"
"time"
@@ -792,6 +794,7 @@ func serveMultipart(t *testing.T, request string, bufSize int, skip string, segm
}
parts, gotErr = exch.ReadMultiparts(parts, make([]byte, bufSize), newSink)
})
const x = unsafe.Sizeof(http.Request{})
exch := newExchange(t, conn, 1024, false)
if err := Handle(exch, &sm, nopBackoff); err != nil {
t.Fatal(err)
+8 -5
View File
@@ -49,8 +49,9 @@ func Handle(exch *Exchange, mux Mux, backoff lneto.BackoffStrategy) error {
// Mux on the request path: the query string is the handler's business.
path := reqhdr.RequestPath()
meth := reqhdr.Method()
handler := mux.LookupHandler(MethodFromBytes(meth), b2s(path))
matchedPattern, handler := mux.LookupHandler(MethodFromBytes(meth), b2s(path))
if handler != nil {
exch.matchedPattern = matchedPattern
handler(exch)
exch.FlushHeader()
} else {
@@ -70,7 +71,9 @@ type HandlerFunc func(ex *Exchange)
// LookupHandler with the request-target's path, not the whole target, and
// replies 404 when it returns nil.
type Mux interface {
LookupHandler(get Method, requestPath string) HandlerFunc
// LookupHandler matches the requestPath and method to a handler and returns it and the
// pattern it matched.
LookupHandler(get Method, requestPath string) (matchedPattern string, handler HandlerFunc)
}
// MuxSlice is a [Mux] backed by a slice of registered endpoints, matched by
@@ -92,17 +95,17 @@ func (sm *MuxSlice) Reset(capacity int) {
// LookupHandler returns the handler registered for request path, or nil if none matches.
// The first registration matching both method and uri wins.
func (sm *MuxSlice) LookupHandler(method Method, path string) HandlerFunc {
func (sm *MuxSlice) LookupHandler(method Method, path string) (matched string, _ HandlerFunc) {
for _, endpoint := range sm._handlers {
if endpoint.method != MethUndefined && endpoint.method != method {
continue
}
// Method matches.
if path == endpoint.path {
return endpoint.handler
return endpoint.path, endpoint.handler
}
}
return nil
return "", nil
}
// Handle registers handler for reg, either a bare path matching any method or a