hnakra/router/router.go

94 lines
2.1 KiB
Go

package router
import "log"
import "net"
// import "errors"
import "net/http"
import "hnakra/config"
import "hnakra/protocol"
import "hnakra/router/mux"
type Pattern struct {
Scheme string
Host string
Path string
}
func (pattern Pattern) MuxPattern () string {
return pattern.Host + pattern.Path
}
func (pattern Pattern) String () string {
return pattern.Scheme + "://" + pattern.Host + pattern.Path
}
func (pattern *Pattern) FillDefaults () {
if pattern.Scheme == "" { pattern.Scheme = "https" }
if pattern.Host == "" { pattern.Host = "@" }
if pattern.Path == "" { pattern.Path = "/" }
}
type Router struct {
config config.Config
http *mux.HTTP
services map[*Service] struct { }
}
func New (config config.Config) *Router {
router := &Router {
config: config,
http: mux.NewHTTP(config),
services: make(map[*Service] struct { }),
}
return router
}
func (router *Router) HTTPMux () *mux.HTTP {
return router.http
}
func (router *Router) Accept (conn net.Conn) {
router.newService(conn)
}
func (router *Router) ServeHTTP (res http.ResponseWriter, req *http.Request) {
log.Println("->?", req.RemoteAddr, "requests", req.URL.String())
router.http.ServeHTTP(res, req)
}
// TODO: uniquely identify connected services by an ID
func (router *Router) Service (name string) *Service {
for service := range router.services {
if service.Name() == name {
return service
}
}
return nil
}
func (router *Router) OverServices (callback func (service *Service) bool) {
for service := range router.services {
if !callback(service) { break }
}
}
func (router *Router) list (service *Service) {
router.services[service] = struct { } { }
}
func (router *Router) unlist (service *Service) {
delete(router.services, service)
}
func (router *Router) Validate (name string, key []byte, pattern Pattern) protocol.Status {
user := router.config.User(name)
if user == nil || !user.Validate(key) {
return protocol.StatusBadCredentials
}
if !user.CanMountOn(pattern.Scheme, pattern.Host, pattern.Path) {
return protocol.StatusBadMount
}
return protocol.StatusOk
}