aboutsummaryrefslogtreecommitdiff
path: root/server.go
diff options
context:
space:
mode:
authorAdnan Maolood <[email protected]>2020-10-21 13:22:26 -0400
committerAdnan Maolood <[email protected]>2020-10-21 13:22:26 -0400
commit9daf84a1217acb24c6c5160efcca411c39e59c32 (patch)
treefe087ed4e5a9e584a5ee6ef9ee82e785f9ac9b2a /server.go
parentexamples/server: Create certificates if they does not exist (diff)
downloadgo-gemini-9daf84a1217acb24c6c5160efcca411c39e59c32.tar.xz
go-gemini-9daf84a1217acb24c6c5160efcca411c39e59c32.zip
Add support for wildcard hostnames
Diffstat (limited to 'server.go')
-rw-r--r--server.go54
1 files changed, 36 insertions, 18 deletions
diff --git a/server.go b/server.go
index 08b1308..1cd8edc 100644
--- a/server.go
+++ b/server.go
@@ -34,15 +34,18 @@ type Server struct {
}
type handlerKey struct {
- Scheme string
- Host string
+ scheme string
+ hostname string
+ wildcard bool
}
-// Handle registers a handler for the given hostname.
-// A default scheme of gemini:// is assumed.
-func (s *Server) Handle(hostname string, handler Handler) {
- if hostname == "" {
- panic("gmi: invalid hostname")
+// Handle registers a handler for the given pattern.
+// Patterns must be in the form of scheme://hostname (e.g. gemini://example.com).
+// If no scheme is specified, a default scheme of gemini:// is assumed.
+// Wildcard patterns are supported (e.g. *.example.com).
+func (s *Server) Handle(pattern string, handler Handler) {
+ if pattern == "" {
+ panic("gmi: invalid pattern")
}
if handler == nil {
panic("gmi: nil handler")
@@ -50,20 +53,29 @@ func (s *Server) Handle(hostname string, handler Handler) {
if s.handlers == nil {
s.handlers = map[handlerKey]Handler{}
}
- s.HandleScheme("gemini", hostname, handler)
-}
-func (s *Server) HandleFunc(hostname string, handler func(*ResponseWriter, *Request)) {
- s.Handle(hostname, HandlerFunc(handler))
-}
+ split := strings.SplitN(pattern, "://", 2)
+ var key handlerKey
+ if len(split) == 2 {
+ key.scheme = split[0]
+ key.hostname = split[1]
+ } else {
+ key.scheme = "gemini"
+ key.hostname = split[0]
+ }
+ split = strings.SplitN(key.hostname, ".", 2)
+ if len(split) == 2 {
+ if split[0] == "*" {
+ key.hostname = split[1]
+ key.wildcard = true
+ }
+ }
-// HandleScheme registers a handler for the given scheme and hostname.
-func (s *Server) HandleScheme(scheme string, hostname string, handler Handler) {
- s.handlers[handlerKey{scheme, hostname}] = handler
+ s.handlers[key] = handler
}
-func (s *Server) HandleSchemeFunc(scheme string, hostname string, handler func(*ResponseWriter, *Request)) {
- s.HandleScheme(scheme, hostname, HandlerFunc(handler))
+func (s *Server) HandleFunc(pattern string, handler func(*ResponseWriter, *Request)) {
+ s.Handle(pattern, HandlerFunc(handler))
}
type handlerEntry struct {
@@ -233,9 +245,15 @@ func (s *Server) respond(conn net.Conn) {
}
func (s *Server) handler(r *Request) Handler {
- if h, ok := s.handlers[handlerKey{r.URL.Scheme, r.URL.Hostname()}]; ok {
+ if h, ok := s.handlers[handlerKey{r.URL.Scheme, r.URL.Hostname(), false}]; ok {
return h
}
+ wildcard := strings.SplitN(r.URL.Hostname(), ".", 2)
+ if len(wildcard) == 2 {
+ if h, ok := s.handlers[handlerKey{r.URL.Scheme, wildcard[1], true}]; ok {
+ return h
+ }
+ }
return NotFoundHandler()
}