Reorganized package tree and added doc comments
This commit is contained in:
		
							parent
							
								
									c300567c0c
								
							
						
					
					
						commit
						60e5a1c729
					
				@ -1,7 +1,9 @@
 | 
			
		||||
// Config provides a configuration system for routers.
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
import "crypto/tls"
 | 
			
		||||
 | 
			
		||||
// Config is an interface that configuration objects must fulfill.
 | 
			
		||||
type Config interface {
 | 
			
		||||
	User          (name string) User
 | 
			
		||||
	OverUsers     (func (name string, user User) bool)
 | 
			
		||||
@ -22,6 +24,7 @@ type Config interface {
 | 
			
		||||
	OverAliases   (func (alias, target string) bool)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// User represents a Hnakra user.
 | 
			
		||||
type User interface {
 | 
			
		||||
	Validate     (key []byte) bool
 | 
			
		||||
	RconAllow    () bool
 | 
			
		||||
@ -3,10 +3,12 @@ package mux
 | 
			
		||||
import "net/url"
 | 
			
		||||
import "net/http"
 | 
			
		||||
 | 
			
		||||
// HTTP is an HTTP request multiplexer.
 | 
			
		||||
type HTTP struct {
 | 
			
		||||
	Mux[http.Handler]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewHTTP creates a new HTTP request multiplexer.
 | 
			
		||||
func NewHTTP (resolver Resolver) *HTTP {
 | 
			
		||||
	mux := &HTTP { }
 | 
			
		||||
	mux.Mux.Redirect = mux.newRedirect
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,4 @@
 | 
			
		||||
// Package mux provides request multiplexers for all protocols Hnakra supports.
 | 
			
		||||
package mux
 | 
			
		||||
 | 
			
		||||
import "net"
 | 
			
		||||
@ -8,6 +9,8 @@ import "errors"
 | 
			
		||||
import "strings"
 | 
			
		||||
import "net/url"
 | 
			
		||||
 | 
			
		||||
// Resolver represents an object capable of transforming a hosname alias into
 | 
			
		||||
// another hostname.
 | 
			
		||||
type Resolver interface {
 | 
			
		||||
	ResolveAlias (alias string) string
 | 
			
		||||
}
 | 
			
		||||
@ -68,6 +71,7 @@ func stripHostPort (h string) string {
 | 
			
		||||
	return host
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Handler returns the handler for a particular URL.
 | 
			
		||||
func (mux *Mux[HANDLER]) Handler (where *url.URL) (h HANDLER, pattern string) {
 | 
			
		||||
	// All other requests have any port stripped and path cleaned
 | 
			
		||||
	// before passing to mux.handler.
 | 
			
		||||
@ -144,6 +148,10 @@ func (mux *Mux[HANDLER]) match (path string, original *url.URL) (h HANDLER, patt
 | 
			
		||||
	return mux.NotFound(original), ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Handle registers a handler on the specified pattern. If a pattern ends in
 | 
			
		||||
// '/', all requests for URLS under the pattern will be directed to the handler,
 | 
			
		||||
// as well as the pattern itself. Additionally, requests for the pattern without
 | 
			
		||||
// the trailing slash will be redirected to the pattern with the trailing slash.
 | 
			
		||||
func (mux *Mux[HANDLER]) Handle (pattern string, handler HANDLER) error {
 | 
			
		||||
	mux.mutex.Lock()
 | 
			
		||||
	defer mux.mutex.Unlock()
 | 
			
		||||
@ -176,6 +184,7 @@ func (mux *Mux[HANDLER]) Handle (pattern string, handler HANDLER) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unhandler removes the handler that was registered on the specified pattern.
 | 
			
		||||
func (mux *Mux[HANDLER]) Unhandle (pattern string) error {
 | 
			
		||||
	mux.mutex.Lock()
 | 
			
		||||
	defer mux.mutex.Unlock()
 | 
			
		||||
@ -199,6 +208,7 @@ func (mux *Mux[HANDLER]) Unhandle (pattern string) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OverHandlers calls a function for each registered handler.
 | 
			
		||||
func (mux *Mux[HANDLER]) OverHandlers (callback func (pattern string, handler HANDLER) bool) {
 | 
			
		||||
	overSorted (mux.exactEntries, func (pattern string, entry muxEntry[HANDLER]) bool {
 | 
			
		||||
		return callback(pattern, entry.handler)
 | 
			
		||||
 | 
			
		||||
@ -8,10 +8,10 @@ import "io"
 | 
			
		||||
import "fmt"
 | 
			
		||||
import "net/url"
 | 
			
		||||
import "net/http"
 | 
			
		||||
import "hnakra/config"
 | 
			
		||||
import "hnakra/router"
 | 
			
		||||
import "hnakra/rotate"
 | 
			
		||||
import "hnakra/protocol"
 | 
			
		||||
import "hnakra/router/config"
 | 
			
		||||
 | 
			
		||||
const css = `
 | 
			
		||||
body { background-color: #161815; color: #aea894; margin: 3em; }
 | 
			
		||||
@ -200,7 +200,7 @@ func (rcon *Rcon) serveServices (res http.ResponseWriter, req *http.Request) {
 | 
			
		||||
			service.Name(),
 | 
			
		||||
			service.Name(),
 | 
			
		||||
			service.Description(),
 | 
			
		||||
			service.Pattern())))
 | 
			
		||||
			router.FormatPattern(service.Pattern()))))
 | 
			
		||||
		return true
 | 
			
		||||
	})
 | 
			
		||||
	
 | 
			
		||||
@ -1,32 +1,13 @@
 | 
			
		||||
// Package router provides a reusable router implementation.
 | 
			
		||||
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   = "/"     }
 | 
			
		||||
}
 | 
			
		||||
import "hnakra/router/config"
 | 
			
		||||
 | 
			
		||||
type Router struct {
 | 
			
		||||
	config   config.Config
 | 
			
		||||
@ -81,13 +62,17 @@ func (router *Router) unlist (service *Service) {
 | 
			
		||||
	delete(router.services, service)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (router *Router) Validate (name string, key []byte, pattern Pattern) protocol.Status {
 | 
			
		||||
func (router *Router) Validate (name string, key []byte, scheme, host, path string) 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) {
 | 
			
		||||
	if !user.CanMountOn(scheme, host, path) {
 | 
			
		||||
		return protocol.StatusBadMount
 | 
			
		||||
	}
 | 
			
		||||
	return protocol.StatusOk
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func FormatPattern (scheme, host, path string) string {
 | 
			
		||||
	return scheme + "://" + host + path
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -38,8 +38,7 @@ func (request *activeRequest) ensureHeader () {
 | 
			
		||||
 | 
			
		||||
type Service struct {
 | 
			
		||||
	router *Router
 | 
			
		||||
	validate func (user string, key []byte, pattern Pattern) protocol.Status
 | 
			
		||||
	pattern Pattern
 | 
			
		||||
	scheme, host, path string
 | 
			
		||||
 | 
			
		||||
	user, name, description string
 | 
			
		||||
 | 
			
		||||
@ -57,7 +56,6 @@ func (router *Router) newService (conn net.Conn) (service *Service) {
 | 
			
		||||
	service = &Service {
 | 
			
		||||
		idFactory: protocol.NewRouterIDFactory(),
 | 
			
		||||
		router:    router,
 | 
			
		||||
		validate:  router.Validate,
 | 
			
		||||
		conn:      conn,
 | 
			
		||||
		requests:  make(map[protocol.ID] *activeRequest),
 | 
			
		||||
		connReadWriter: bufio.NewReadWriter (
 | 
			
		||||
@ -88,8 +86,8 @@ func (service *Service) Description () string {
 | 
			
		||||
	return service.description
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (service *Service) Pattern () Pattern {
 | 
			
		||||
	return service.pattern
 | 
			
		||||
func (service *Service) Pattern () (user, name, description string) {
 | 
			
		||||
	return service.user, service.name, service.description
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (service *Service) Close () error {
 | 
			
		||||
@ -104,9 +102,9 @@ func (service *Service) Shutdown () error {
 | 
			
		||||
func (service *Service) ServeHTTP (res http.ResponseWriter, req *http.Request) {
 | 
			
		||||
	// if we are only accepting https requests and we recieve an http one,
 | 
			
		||||
	// redirect to the https version
 | 
			
		||||
	if req.TLS == nil && service.pattern.Scheme == "https" {
 | 
			
		||||
	if req.TLS == nil && service.scheme == "https" {
 | 
			
		||||
		newURL := req.URL
 | 
			
		||||
		newURL.Scheme = service.pattern.Scheme
 | 
			
		||||
		newURL.Scheme = service.scheme
 | 
			
		||||
		http.Redirect(res, req, newURL.String(), http.StatusPermanentRedirect)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
@ -326,15 +324,17 @@ func (service *Service) authenticate () (func(), bool) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// create pattern
 | 
			
		||||
	service.pattern = Pattern {
 | 
			
		||||
		Scheme: login.Scheme,
 | 
			
		||||
		Host:   login.Host,
 | 
			
		||||
		Path:   login.Path,
 | 
			
		||||
	}
 | 
			
		||||
	service.pattern.FillDefaults()
 | 
			
		||||
	service.scheme = login.Scheme
 | 
			
		||||
	service.host   = login.Host
 | 
			
		||||
	service.path   = login.Path
 | 
			
		||||
	if service.scheme == "" { service.scheme = "https://" }
 | 
			
		||||
	if service.host   == "" { service.host   = "@"        }
 | 
			
		||||
	if service.path   == "" { service.path   = "/"        }
 | 
			
		||||
 | 
			
		||||
	// validate credentials
 | 
			
		||||
	status := service.validate(login.User, login.Key, service.pattern)
 | 
			
		||||
	status := service.router.Validate (
 | 
			
		||||
		login.User, login.Key,
 | 
			
		||||
		service.scheme, service.host, service.path)
 | 
			
		||||
	service.send(protocol.MessageStatus { Status: status })
 | 
			
		||||
	if status == protocol.StatusOk {
 | 
			
		||||
		service.user        = login.User
 | 
			
		||||
@ -343,19 +343,21 @@ func (service *Service) authenticate () (func(), bool) {
 | 
			
		||||
		
 | 
			
		||||
		log.Println (
 | 
			
		||||
			"-->", service.conn.RemoteAddr(),
 | 
			
		||||
			"logged in as", login.User, "on", service.pattern)
 | 
			
		||||
			"logged in as", login.User, "on",
 | 
			
		||||
			FormatPattern(service.scheme, service.host, service.path))
 | 
			
		||||
	} else {
 | 
			
		||||
		log.Println (
 | 
			
		||||
			"ERR", service.conn.RemoteAddr(),
 | 
			
		||||
			"failed login as", login.User, "on", service.pattern)
 | 
			
		||||
			"failed login as", login.User, "on",
 | 
			
		||||
			FormatPattern(service.scheme, service.host, service.path))
 | 
			
		||||
		service.conn.Close()
 | 
			
		||||
		return nil, false	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// mount service on the mux.
 | 
			
		||||
	var unhandle func ()
 | 
			
		||||
	muxPattern := service.pattern.MuxPattern()
 | 
			
		||||
	switch service.pattern.Scheme {
 | 
			
		||||
	muxPattern := service.host + service.path 
 | 
			
		||||
	switch service.scheme {
 | 
			
		||||
	case "http", "https":
 | 
			
		||||
		err = service.router.HTTPMux().Handle(muxPattern, service)
 | 
			
		||||
		unhandle = func () {
 | 
			
		||||
@ -367,7 +369,8 @@ func (service *Service) authenticate () (func(), bool) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Println (
 | 
			
		||||
			"ERR", service.name,
 | 
			
		||||
			"sent bad mount pattern:", service.pattern)
 | 
			
		||||
			"sent bad mount pattern:",
 | 
			
		||||
			FormatPattern(service.scheme, service.host, service.path))
 | 
			
		||||
		service.send(protocol.MessageStatus {
 | 
			
		||||
			Status: protocol.StatusBadMount,
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,4 @@
 | 
			
		||||
// Package service provides a toolkit for creating Hnakra services.
 | 
			
		||||
package service
 | 
			
		||||
 | 
			
		||||
import "os"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user