Proposal: Middleware Config (#908)

* Prototype middleware Config

* Refactors

* Minor refactors
This commit is contained in:
Abiola Ibrahim
2016-07-09 01:12:52 +01:00
committed by Matt Holt
parent cf03c9a6c8
commit 87c389f73d
6 changed files with 127 additions and 69 deletions

View File

@@ -5,7 +5,6 @@ import (
"net/http"
"os"
"path"
"strings"
"time"
)
@@ -48,13 +47,23 @@ type (
// RequestMatcher checks to see if current request should be handled
// by underlying handler.
//
// TODO The long term plan is to get all middleware implement this
// interface and have validation done before requests are dispatched
// to each middleware.
RequestMatcher interface {
Match(r *http.Request) bool
}
// HandlerConfig is a middleware configuration.
// This makes it possible for middlewares to have a common
// configuration interface.
//
// TODO The long term plan is to get all middleware implement this
// interface for configurations.
HandlerConfig interface {
RequestMatcher
BasePath() string
}
// ConfigSelector selects a configuration.
ConfigSelector []HandlerConfig
)
// ServeHTTP implements the Handler interface.
@@ -62,6 +71,20 @@ func (f HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, err
return f(w, r)
}
// Select selects a Config.
// This chooses the config with the longest length.
func (c ConfigSelector) Select(r *http.Request) (config HandlerConfig) {
for i := range c {
if !c[i].Match(r) {
continue
}
if config == nil || len(c[i].BasePath()) > len(config.BasePath()) {
config = c[i]
}
}
return config
}
// IndexFile looks for a file in /root/fpath/indexFile for each string
// in indexFiles. If an index file is found, it returns the root-relative
// path to the file and true. If no index file is found, empty string
@@ -130,21 +153,6 @@ func initCaseSettings() {
}
}
// Path represents a URI path.
type Path string
// Matches checks to see if other matches p.
//
// Path matching will probably not always be a direct
// comparison; this method assures that paths can be
// easily and consistently matched.
func (p Path) Matches(other string) bool {
if CaseSensitivePath {
return strings.HasPrefix(string(p), other)
}
return strings.HasPrefix(strings.ToLower(string(p)), strings.ToLower(other))
}
// MergeRequestMatchers merges multiple RequestMatchers into one.
// This allows a middleware to use multiple RequestMatchers.
func MergeRequestMatchers(matchers ...RequestMatcher) RequestMatcher {

View File

@@ -0,0 +1,29 @@
package httpserver
import (
"net/http"
"strings"
)
// Path represents a URI path.
type Path string
// Matches checks to see if other matches p.
//
// Path matching will probably not always be a direct
// comparison; this method assures that paths can be
// easily and consistently matched.
func (p Path) Matches(other string) bool {
if CaseSensitivePath {
return strings.HasPrefix(string(p), other)
}
return strings.HasPrefix(strings.ToLower(string(p)), strings.ToLower(other))
}
// PathMatcher is a Path RequestMatcher.
type PathMatcher string
// Match satisfies RequestMatcher.
func (p PathMatcher) Match(r *http.Request) bool {
return Path(r.URL.Path).Matches(string(p))
}