aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoradnano <[email protected]>2020-09-25 11:27:26 -0400
committeradnano <[email protected]>2020-09-25 11:27:26 -0400
commitec68ab8609b0096a33e49aa9ba05d8b69b4691b8 (patch)
treec28553e19567a02d1c95f5b267e61bad02b4525a
parentSort ServeMux entries by length (diff)
downloadgo-gemini-ec68ab8609b0096a33e49aa9ba05d8b69b4691b8.tar.xz
go-gemini-ec68ab8609b0096a33e49aa9ba05d8b69b4691b8.zip
Add test
-rw-r--r--examples/server/server.go19
-rw-r--r--gemini.go21
-rw-r--r--gemini_test.go41
3 files changed, 54 insertions, 27 deletions
diff --git a/examples/server/server.go b/examples/server/server.go
index 3d1145d..c587c69 100644
--- a/examples/server/server.go
+++ b/examples/server/server.go
@@ -30,20 +30,11 @@ func main() {
}
mux := &gemini.ServeMux{}
- // mux.HandleFunc("/", func(rw *gemini.ResponseWriter, req *gemini.Request) {
- // log.Printf("Request from %s for %s with certificates %v", req.RemoteAddr.String(), req.URL.String(), req.TLS.PeerCertificates)
- // rw.WriteHeader(gemini.StatusSuccess, "text/gemini")
- // rw.Write([]byte("You requested " + req.URL.String()))
- // })
- // mux.HandleFunc("/cert", func(rw *gemini.ResponseWriter, req *gemini.Request) {
- // rw.WriteHeader(gemini.StatusClientCertificateRequired, "Certificate required")
- // })
-
- mux.HandleFunc("https://example.com/path", nil)
- mux.HandleFunc("http://example.com/path", nil)
- mux.HandleFunc("example.com/path", nil)
- mux.HandleFunc("/path", nil)
- mux.HandleFunc("/longpath", nil)
+ mux.HandleFunc("/", func(rw *gemini.ResponseWriter, req *gemini.Request) {
+ log.Printf("Request from %s for %s with certificates %v", req.RemoteAddr.String(), req.URL.String(), req.TLS.PeerCertificates)
+ rw.WriteHeader(gemini.StatusSuccess, "text/gemini")
+ rw.Write([]byte("You requested " + req.URL.String()))
+ })
server := gemini.Server{
TLSConfig: config,
diff --git a/gemini.go b/gemini.go
index 514fc36..76b0098 100644
--- a/gemini.go
+++ b/gemini.go
@@ -415,17 +415,15 @@ type ServeMux struct {
}
type muxEntry struct {
- scheme string
- host string
- path string
+ u *url.URL
handler Handler
}
func (m *ServeMux) match(url *url.URL) Handler {
for _, e := range m.entries {
- if (e.scheme == "" || url.Scheme == e.scheme) &&
- (e.host == "" || url.Host == e.host) &&
- strings.HasPrefix(url.Path, e.path) {
+ if (e.u.Scheme == "" || url.Scheme == e.u.Scheme) &&
+ (e.u.Host == "" || url.Host == e.u.Host) &&
+ strings.HasPrefix(url.Path, e.u.Path) {
return e.handler
}
}
@@ -439,13 +437,10 @@ func (m *ServeMux) Handle(pattern string, handler Handler) {
panic(err)
}
e := muxEntry{
- url.Scheme,
- url.Host,
- url.Path,
+ url,
handler,
}
m.entries = appendSorted(m.entries, e)
- log.Print(m.entries)
}
// HandleFunc registers a HandlerFunc for the given pattern.
@@ -490,9 +485,9 @@ func appendSorted(es []muxEntry, e muxEntry) []muxEntry {
// return len(es[i].path) < len(e.path)
// Condensed version:
- return (es[i].scheme == "" || (e.scheme != "" && len(es[i].scheme) < len(e.scheme))) &&
- (es[i].host == "" || (e.host != "" && len(es[i].host) < len(e.host))) &&
- len(es[i].path) < len(e.path)
+ return (es[i].u.Scheme == "" || (e.u.Scheme != "" && len(es[i].u.Scheme) < len(e.u.Scheme))) &&
+ (es[i].u.Host == "" || (e.u.Host != "" && len(es[i].u.Host) < len(e.u.Host))) &&
+ len(es[i].u.Path) < len(e.u.Path)
})
if i == n {
return append(es, e)
diff --git a/gemini_test.go b/gemini_test.go
new file mode 100644
index 0000000..b118640
--- /dev/null
+++ b/gemini_test.go
@@ -0,0 +1,41 @@
+package gemini
+
+import (
+ "math/rand"
+ "testing"
+ "time"
+)
+
+func TestServeMuxEntryOrder(t *testing.T) {
+ expected := []string{
+ "https://example.com/longpath",
+ "https://example.com/path",
+ "https://example.com",
+ "http://example.com/longpath",
+ "http://example.com/path",
+ "http://example.com",
+ "example.com/longpath",
+ "example.com/path",
+ "example.com",
+ "/longpath",
+ "/path",
+ "/",
+ }
+
+ // Shuffle input
+ a := make([]string, len(expected))
+ copy(expected, a)
+ rand.Seed(time.Now().UnixNano())
+ rand.Shuffle(len(a), func(i, j int) { a[i], a[j] = a[j], a[i] })
+
+ mux := &ServeMux{}
+ for _, s := range a {
+ mux.Handle(s, nil)
+ }
+ for i, e := range mux.entries {
+ s := e.u.String()
+ if s != expected[i] {
+ t.Errorf("wrong order of mux entries: expected %s, got %s", expected[i], s)
+ }
+ }
+}