Proposal Details

right now it's very inefficient to have wrappers that uses Handler because for some reason it refuses to set the pattern matches and items on the request itself

we should change it so ServeHTTP calls handler, and for people who want to use Handler directly for their own middleware building, they don't need to basically force the server to run pathmatching twice

e.g. Example code that adds a top level middleware around requests (where m is a ServeMux`)

h, matchedPattern := m.ServeMux.Handler(r)
if m.notFoundHandler != nil && (h == nil || matchedPattern == "") {
    m.notFoundHandler.ServeHTTP(w, r)
} else {
    if m.httpHandler != nil {
        h = m.httpHandler(h)
    }

    h.ServeHTTP(w, r)
}

This will fail because r doesn't have any of the pattern match data and we can't call it or set it ourselves because findMatch is private, and even if findMatch wasn't private r.pat and r.matches are private.

Honestly I don't see why any of these are private. if it's about foot-guns, my response would be it's not the packages responsibility to stop me from breaking things if I want to touch the low levels.

IMO we should have a public method that calls findMatch and does exactly what ServeHTTP does for assigning request data.

if changing Handler is out of the question because it would break something to assign the data, then maybe a new function PrepareHandler that does and ServeHTTP can also use that method so it's DRY

// PrepareHandler finds the handler that most closely matches
// the request and prepares the request with PathData
// then returns the handler
func (mux *ServeMux) PrepareHandler(r *Request) h Handler {
    if use121 {
        h, _ = mux.mux121.findHandler(r)
    } else {
        h, r.Pattern, r.pat, r.matches = mux.findHandler(r)
    }
    return h
}

// ServeHTTP dispatches the request to the handler whose
// pattern most closely matches the request URL.
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
    if r.RequestURI == "*" {
        if r.ProtoAtLeast(1, 1) {
            w.Header().Set("Connection", "close")
        }
        w.WriteHeader(StatusBadRequest)
        return
    }
    h := PrepareHandler(r)
    h.ServeHTTP(w, r)
}

Comment From: gabyhelp

Related Issues

Related Documentation

Related Discussions

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)