...

Source file src/github.com/go-kivik/kivik/v4/x/server/middleware.go

Documentation: github.com/go-kivik/kivik/v4/x/server

     1  // Licensed under the Apache License, Version 2.0 (the "License"); you may not
     2  // use this file except in compliance with the License. You may obtain a copy of
     3  // the License at
     4  //
     5  //  http://www.apache.org/licenses/LICENSE-2.0
     6  //
     7  // Unless required by applicable law or agreed to in writing, software
     8  // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     9  // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    10  // License for the specific language governing permissions and limitations under
    11  // the License.
    12  
    13  //go:build !js
    14  
    15  package server
    16  
    17  import (
    18  	"io"
    19  	"net/http"
    20  
    21  	"github.com/go-chi/chi/v5"
    22  )
    23  
    24  // GetHead automatically route undefined HEAD requests to GET handlers, and
    25  // discards the response body for such requests.
    26  //
    27  // Forked from chi middleware package.
    28  func GetHead(next http.Handler) http.Handler {
    29  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    30  		if r.Method == "HEAD" {
    31  			rctx := chi.RouteContext(r.Context())
    32  			routePath := rctx.RoutePath
    33  			if routePath == "" {
    34  				if r.URL.RawPath != "" {
    35  					routePath = r.URL.RawPath
    36  				} else {
    37  					routePath = r.URL.Path
    38  				}
    39  			}
    40  
    41  			// Temporary routing context to look-ahead before routing the request
    42  			tctx := chi.NewRouteContext()
    43  
    44  			// Attempt to find a HEAD handler for the routing path, if not found, traverse
    45  			// the router as through its a GET route, but proceed with the request
    46  			// with the HEAD method.
    47  			if !rctx.Routes.Match(tctx, "HEAD", routePath) {
    48  				type httpWriter interface { // Just the methods unique to http.ResponseWriter
    49  					Header() http.Header
    50  					WriteHeader(statusCode int)
    51  				}
    52  				discardWriter := struct {
    53  					httpWriter
    54  					io.Writer
    55  				}{
    56  					httpWriter: w,
    57  					Writer:     io.Discard,
    58  				}
    59  				rctx.RouteMethod = "GET"
    60  				rctx.RoutePath = routePath
    61  				next.ServeHTTP(discardWriter, r)
    62  				return
    63  			}
    64  		}
    65  
    66  		next.ServeHTTP(w, r)
    67  	})
    68  }
    69  

View as plain text