handlers.go raw

   1  package cleanhttp
   2  
   3  import (
   4  	"net/http"
   5  	"strings"
   6  	"unicode"
   7  )
   8  
   9  // HandlerInput provides input options to cleanhttp's handlers
  10  type HandlerInput struct {
  11  	ErrStatus int
  12  }
  13  
  14  // PrintablePathCheckHandler is a middleware that ensures the request path
  15  // contains only printable runes.
  16  func PrintablePathCheckHandler(next http.Handler, input *HandlerInput) http.Handler {
  17  	// Nil-check on input to make it optional
  18  	if input == nil {
  19  		input = &HandlerInput{
  20  			ErrStatus: http.StatusBadRequest,
  21  		}
  22  	}
  23  
  24  	// Default to http.StatusBadRequest on error
  25  	if input.ErrStatus == 0 {
  26  		input.ErrStatus = http.StatusBadRequest
  27  	}
  28  
  29  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  30  		if r != nil {
  31  			// Check URL path for non-printable characters
  32  			idx := strings.IndexFunc(r.URL.Path, func(c rune) bool {
  33  				return !unicode.IsPrint(c)
  34  			})
  35  
  36  			if idx != -1 {
  37  				w.WriteHeader(input.ErrStatus)
  38  				return
  39  			}
  40  
  41  			if next != nil {
  42  				next.ServeHTTP(w, r)
  43  			}
  44  		}
  45  
  46  		return
  47  	})
  48  }
  49