94 lines
2.1 KiB
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
|
||
|
}
|