server

package module
v1.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 16, 2023 License: MIT Imports: 26 Imported by: 0

Documentation

Index

Constants

View Source
const (
	LOG_LEVEL_INFO    = 4
	LOG_LEVEL_DEBUG   = 3
	LOG_LEVEL_WARNING = 2
	LOG_LEVEL_ERROR   = 1
	LOG_LEVEL_FATAL   = 0
)
View Source
const (
	ErrNoErr = iota
	ErrBadURL
	ErrServerOffline
	ErrWebsiteOffline
	ErrDomainNotFound
	ErrSubdomainNotFound
)
View Source
const LogFormat string = "02/Jan/2006:15:04:05"

Variables

View Source
var (
	HashKeyString  = "NixPare Server"
	BlockKeyString = "github.com/alessio-pareto/server"
)

Functions

func GenerateHashString added in v1.1.1

func GenerateHashString(data []byte) string

GenerateHashString generate an hash with sha256 from data

func ParseCommandArgs

func ParseCommandArgs(args ...string) []string

func RandStr

func RandStr(strSize int, randType string) string

func ReadJSON added in v1.5.0

func ReadJSON[T any](route *Route) (value T, err error)

func WriteLogClosure added in v1.1.1

func WriteLogClosure(t time.Time) string

func WriteLogStart added in v1.1.1

func WriteLogStart(t time.Time) string

Types

type BGTimer

type BGTimer int

BGTimer is the time unit that specify how often the task will be called, defining its interval

const (
	BGTimerMinute    BGTimer = 1  // 1 minute
	BGTimer10Minutes BGTimer = 10 // 10 minutes
	BGTimer30Minutes BGTimer = 30 // 30 minutes
	BGTimerHour      BGTimer = 60 // 1 hour
	BGTimerInactive  BGTimer = -1 // The task will never be called (until this is changed)
)

type Certificate

type Certificate struct {
	CertPemPath string
	KeyPemPath  string
}

type Config

type Config struct {
	Port   int
	Secure bool
	Certs  []Certificate
}

type Domain

type Domain struct {
	Name string
	// contains filtered or unexported fields
}

Domain rapresents a website domain with all its subdomains. It's possible to set:

  • global headers, that will be applied in every connection
  • an error template, that will be used in case your logic will throw any error, so you will have a constant look

func (*Domain) DefaultSubdomain

func (d *Domain) DefaultSubdomain() *Subdomain

Subdomain returns the default subdomain, if set

func (*Domain) DisableSubdomain

func (d *Domain) DisableSubdomain(name string) *Domain

DisableSubdomain disables a subdomain

func (*Domain) EnableSubdomain

func (d *Domain) EnableSubdomain(name string) *Domain

EnableSubdomain enables a subdomain

func (*Domain) Header

func (d *Domain) Header() http.Header

Header returns the default headers

func (*Domain) RegisterDefaultSubdomain

func (d *Domain) RegisterDefaultSubdomain(c SubdomainConfig) *Subdomain

RegisterDefaultSubdomain registers a subdomain that is called if no other one matches perfectly the incoming connection for the same domain

func (*Domain) RegisterSubdomain

func (d *Domain) RegisterSubdomain(subdomain string, c SubdomainConfig) *Subdomain

RegisterSubdomain registers a subdomain in the domain. It's asked to specify the subdomain name (with or without trailing dot) and its configuration. It the Website Dir field is empty it will be used the default value of "<srv.ServerPath>/public", instead if it's not absolute it will be relative to the srv.ServerPath

func (*Domain) RemoveHeader

func (d *Domain) RemoveHeader(name string) *Domain

RemoveHeader removes a header with the given name

func (*Domain) RemoveSubdomain

func (d *Domain) RemoveSubdomain(name string) *Domain

RemoveSubdomain unregisters a subdomain

func (*Domain) SetErrorTemplate

func (d *Domain) SetErrorTemplate(content string) error

SetErrorTemplate sets the error template used server-wise. It's required an html that contains two specific fields, a .Code one and a .Message one, for example like so:

<h2>Error {{ .Code }}</h2>
<p>{{ .Message }}</p>

func (*Domain) SetHeader

func (d *Domain) SetHeader(name, value string) *Domain

SetHeader adds a header to the collection of headers used in every connection

func (*Domain) SetHeaders

func (d *Domain) SetHeaders(headers [][2]string) *Domain

SetHeaders adds headers to the collection of headers used in every connection. This is a faster way to set multiple headers at the same time, instead of using domain.SetHeader. The headers must be provided in this way:

headers := [][2]string {
	{ "name1", "value1" },
	{ "name2", "value2" },
}
d.SetHeaders(headers)

func (*Domain) Subdomain

func (d *Domain) Subdomain(subdomain string) *Subdomain

Subdomain returns the subdomain with the given name, if found

type InitCloseFunction

type InitCloseFunction func(srv *Server, domain *Domain, subdomain *Subdomain, website *Website)

type LogLevel added in v1.1.0

type LogLevel int

type Mutex

type Mutex struct {
	// contains filtered or unexported fields
}

func NewMutex

func NewMutex() *Mutex

func (*Mutex) CreateJobs

func (m *Mutex) CreateJobs(nJobs int)

func (*Mutex) Done

func (m *Mutex) Done()

func (*Mutex) ListenForSignal

func (m *Mutex) ListenForSignal()

func (*Mutex) SendSignal

func (m *Mutex) SendSignal()

func (*Mutex) Wait

func (m *Mutex) Wait()

type Process

type Process struct {
	// contains filtered or unexported fields
}

func NewProcess

func NewProcess(name string, args ...string) *Process

func (*Process) Kill

func (p *Process) Kill() (int, error)

func (*Process) Start

func (p *Process) Start() (err error)

func (*Process) Stop

func (p *Process) Stop() (int, error)

type ResponseWriter

type ResponseWriter struct {
	// contains filtered or unexported fields
}

func (*ResponseWriter) Header

func (w *ResponseWriter) Header() http.Header

func (*ResponseWriter) Write

func (w *ResponseWriter) Write(data []byte) (int, error)

func (*ResponseWriter) WriteHeader

func (w *ResponseWriter) WriteHeader(statusCode int)

type Route

type Route struct {
	W             *ResponseWriter
	R             *http.Request
	Srv           *Server
	Router        *Router
	Secure        bool
	Host          string
	RemoteAddress string
	Website       *Website
	DomainName    string
	SubdomainName string
	Domain        *Domain
	Subdomain     *Subdomain
	RequestURI    string
	Method        string

	QueryMap       map[string]string
	ConnectionTime time.Time
	AvoidLogging   bool
	// contains filtered or unexported fields
}

func (*Route) DecodeCookie

func (route *Route) DecodeCookie(name string, value interface{}) (bool, error)

func (*Route) DecodeCookiePerm

func (route *Route) DecodeCookiePerm(name string, value interface{}) (bool, error)

func (*Route) DeleteCookie

func (route *Route) DeleteCookie(name string)

func (*Route) Error

func (route *Route) Error(statusCode int, message string, a ...any)

func (*Route) IsInternalConn

func (route *Route) IsInternalConn() bool

IsInternalConn tells wheather the incoming connection should be treated as a local connection. The user can add a filter that can extend this selection to match their needs

func (*Route) Log added in v1.1.0

func (route *Route) Log(level LogLevel, a ...any)

func (*Route) Logf added in v1.3.0

func (route *Route) Logf(level LogLevel, format string, a ...any)

func (*Route) Logln added in v1.3.0

func (route *Route) Logln(level LogLevel, a ...any)

func (*Route) Print added in v1.1.0

func (route *Route) Print(a ...any)

func (*Route) Printf added in v1.1.0

func (route *Route) Printf(format string, a ...any)

func (*Route) Println added in v1.1.0

func (route *Route) Println(a ...any)

func (*Route) ReverseProxy

func (route *Route) ReverseProxy(URL string) error

func (*Route) ServeCustomFile added in v1.5.0

func (route *Route) ServeCustomFile(name string, data []byte)

func (*Route) ServeCustomFileWithTime added in v1.5.0

func (route *Route) ServeCustomFileWithTime(name string, data []byte, t time.Time)

func (*Route) ServeData added in v1.5.0

func (route *Route) ServeData(data []byte)

func (*Route) ServeFile

func (route *Route) ServeFile(path string)

func (*Route) ServeHTTP

func (route *Route) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*Route) ServeRootedFile

func (route *Route) ServeRootedFile(path string)

func (*Route) ServeText added in v1.5.0

func (route *Route) ServeText(text string)

func (*Route) SetCookie

func (route *Route) SetCookie(name string, value interface{}, maxAge int) error

func (*Route) SetCookiePerm

func (route *Route) SetCookiePerm(name string, value interface{}, maxAge int) error

func (*Route) StaticServe

func (route *Route) StaticServe(serveHTML bool)

type Router added in v1.1.1

type Router struct {
	CleanupF   func() error
	ServerPath string
	// contains filtered or unexported fields
}

func NewRouter added in v1.1.1

func NewRouter(logFile *os.File, serverPath string) (router *Router, err error)

func (*Router) ClearLogs added in v1.2.0

func (router *Router) ClearLogs()

func (*Router) ExecIsRunning added in v1.1.1

func (router *Router) ExecIsRunning(name string) (bool, error)

func (*Router) Log added in v1.1.1

func (router *Router) Log(level LogLevel, a ...any)

func (*Router) Logf added in v1.1.1

func (router *Router) Logf(level LogLevel, format string, a ...any)

func (*Router) Logln added in v1.1.1

func (router *Router) Logln(level LogLevel, a ...any)

func (*Router) NewServer added in v1.3.0

func (router *Router) NewServer(cfg Config) (srv *Server, err error)

func (*Router) PlainPrintf added in v1.3.0

func (router *Router) PlainPrintf(format string, a ...any)

func (*Router) Print added in v1.1.1

func (router *Router) Print(a ...any)

func (*Router) Printf added in v1.1.1

func (router *Router) Printf(format string, a ...any)

func (*Router) Println added in v1.1.1

func (router *Router) Println(a ...any)

func (*Router) RegisterBackgroundTask added in v1.1.1

func (router *Router) RegisterBackgroundTask(task *Task, timer BGTimer) error

RegisterBackgroundTask registers the task with the timer. The timer however can be changed (only by the user) and its not dependent only on the task, but it belongs to the server, so it might happen that the first execution can happen as soon as the Task is registered

func (*Router) RegisterExec added in v1.1.1

func (router *Router) RegisterExec(name, dir string, redirect bool, execName string, args ...string) error

func (*Router) RegisterExecAndStart added in v1.1.1

func (router *Router) RegisterExecAndStart(name, dir string, redirect bool, execName string, args ...string) error

func (*Router) RestartExec added in v1.1.1

func (router *Router) RestartExec(name string) error

func (*Router) Server added in v1.2.0

func (router *Router) Server(port int) *Server

func (*Router) SetBackgroundTaskState added in v1.1.1

func (router *Router) SetBackgroundTaskState(name string, timer BGTimer) error

SetBackgroundTaskState changes the timer of a task with the given name, if found

func (*Router) SetInternalConnFilter added in v1.1.1

func (router *Router) SetInternalConnFilter(f func(remoteAddress string) bool) *Router

func (*Router) Start added in v1.1.1

func (router *Router) Start()

func (*Router) StartExec added in v1.1.1

func (router *Router) StartExec(name string) error

func (*Router) StartProgram added in v1.1.1

func (router *Router) StartProgram(name string, args []string, dir string, wait bool, stdin, stdout, stderr string) (exitCode int, err error)

StartProgram executes a program with the given args and working directory. It's possible to specify if to wait for the process to exit or not: in the latter case you should not consider the exitCode result. For the input, output and error files, theese are the cases:

  • if you pass an empty string, you will have a null file
  • if you pass the string "INHERIT", it will inherit the log file of the server (for stdin it will be a null file)
  • otherwise, it will open the file specified, if found

func (*Router) Stop added in v1.1.1

func (router *Router) Stop()

func (*Router) StopAllExecs added in v1.1.1

func (router *Router) StopAllExecs()

func (*Router) StopExec added in v1.1.1

func (router *Router) StopExec(name string) error

func (*Router) StopServer added in v1.1.1

func (router *Router) StopServer(port int) error

type ServeFunction

type ServeFunction func(route *Route)

type Server

type Server struct {
	Secure     bool
	Running    bool
	Online     bool
	OnlineTime time.Time

	Server *http.Server

	Router *Router

	ServerPath string
	// contains filtered or unexported fields
}

func (*Server) DefaultDomain

func (srv *Server) DefaultDomain() *Domain

DefaultDomain returns the default domain, if set

func (*Server) Domain

func (srv *Server) Domain(domain string) *Domain

Domain returns the domain with the given name registered in the server, if found

func (*Server) Header

func (srv *Server) Header() http.Header

func (*Server) Log added in v1.1.0

func (srv *Server) Log(level LogLevel, a ...any)

func (*Server) Logf added in v1.1.1

func (srv *Server) Logf(level LogLevel, format string, a ...any)

func (*Server) Logln added in v1.1.1

func (srv *Server) Logln(level LogLevel, a ...any)

func (*Server) Print added in v1.1.0

func (srv *Server) Print(a ...any)

func (*Server) Printf added in v1.1.0

func (srv *Server) Printf(format string, a ...any)

func (*Server) Println added in v1.1.0

func (srv *Server) Println(a ...any)

func (*Server) ReadFileConcurrent

func (srv *Server) ReadFileConcurrent(filePath string) ([]byte, error)

func (*Server) RegisterDefaultDomain

func (srv *Server) RegisterDefaultDomain(displayName string) *Domain

RegisterDefaultDomain registers a domain that is called if no other domain matches perfectly the incoming connection

func (*Server) RegisterDefaultRoute

func (srv *Server) RegisterDefaultRoute(displayName string, c SubdomainConfig) (*Domain, *Subdomain)

This is a shortcut for registering the default logic applied for every connection not matching any other specific domain and subdomain. It's the combination of srv.RegisterDefaultDomain(displayName).RegisterDefaultSubdomain(c)

func (*Server) RegisterDomain

func (srv *Server) RegisterDomain(displayName, domain string) *Domain

RegisterDomain registers a domain in the server. It's asked to specify a display name used in the logs and the effective URL of the domain (do not specify any protocol or port). If the domain name is an empy string it will be treated as the default domain (see srv.RegisterDefaultDomain)

func (*Server) RemoveHeader

func (srv *Server) RemoveHeader(name string) *Server

func (*Server) SetErrorTemplate

func (srv *Server) SetErrorTemplate(content string) error

SetErrorTemplate sets the error template used server-wise. It's required an html that contains two specific fields, a .Code one and a .Message one, for example like so:

<h2>Error {{ .Code }}</h2>
<p>{{ .Message }}</p>

func (*Server) SetHeader

func (srv *Server) SetHeader(name, value string) *Server

func (*Server) SetHeaders

func (srv *Server) SetHeaders(headers [][2]string) *Server

func (*Server) Shutdown added in v1.3.0

func (srv *Server) Shutdown()

func (*Server) Start

func (srv *Server) Start()

type Subdomain

type Subdomain struct {
	Name string
	// contains filtered or unexported fields
}

Subdomain rapresents a particular subdomain in a domain with all the logic. It's required a serve function, which will determine the logic of the website, and a Website, with all its options. It's possible to set:

  • default headers, that will be applied in every connection
  • an error template, that will be used in case your logic will throw any error, so you will have a constant look
  • the subdomain to be offline, can be reverted
  • an initializer function, called when the server is starting up
  • a cleanup function, called when the server is shutting down

func (*Subdomain) Disable

func (sd *Subdomain) Disable() *Subdomain

Disable sets the subdomain to be offline

func (*Subdomain) Enable

func (sd *Subdomain) Enable() *Subdomain

Enable sets the subdomain to be online and working

func (*Subdomain) Header

func (sd *Subdomain) Header() http.Header

Header returns the default headers

func (*Subdomain) RemoveHeader

func (sd *Subdomain) RemoveHeader(name string) *Subdomain

RemoveHeader removes a header with the given name

func (*Subdomain) SetErrorTemplate

func (sd *Subdomain) SetErrorTemplate(content string) error

SetErrorTemplate sets the error template used server-wise. It's required an html that contains two specific fields, a .Code one and a .Message one, for example like so:

<h2>Error {{ .Code }}</h2>
<p>{{ .Message }}</p>

func (*Subdomain) SetHeader

func (sd *Subdomain) SetHeader(name, value string) *Subdomain

SetHeader adds a header to the collection of headers used in every connection

func (*Subdomain) SetHeaders

func (sd *Subdomain) SetHeaders(headers [][2]string) *Subdomain

SetHeaders adds headers to the collection of headers used in every connection. This is a faster way to set multiple headers at the same time, instead of using subdomain.SetHeader. The headers must be provided in this way:

headers := [][2]string {
	{ "name1", "value1" },
	{ "name2", "value2" },
}
d.SetHeaders(headers)

type SubdomainConfig

type SubdomainConfig struct {
	Website Website
	ServeF  ServeFunction
	InitF   InitCloseFunction
	CloseF  InitCloseFunction
}

SubdomainConfig is used to create a Subdomain. The Website and ServeF fields must not be nil, instead InitF and CloseF are optional

type Task

type Task struct {
	StartupF TaskFunc
	ExecF    TaskFunc
	CleanupF TaskFunc
	// contains filtered or unexported fields
}

Task is composed of a name set upon creation and of 3 functions necessary of the correct execution of a kind of program. Every function is panic-protected, this means that the entire server will not crash when some parts of the task fails badly; this does not mean that you can't handle panics by yourself, but if they are not handled its like catching them and returning their message as an error. If a function returns an error, this will be logged, providing the task name and which function called it automatically (the task will be disabled if the one failing is the startup one or but you can do it manually, see router.SetBackgroundTaskState)

func NewTask added in v1.1.0

func NewTask(name string, f TaskInitFunc) *Task

NewTask creates a new task with the given name. The name is immutable. Creating a new Task is not enough for making it executable and active: for that you have to call router.RegisterBackgroundTask function

func (Task) ListenForExit added in v1.1.1

func (t Task) ListenForExit()

ListenForExit waits until the exit signal is received from the manager. This signal is sent when the server is shutting down: the manager will wait for 10 seconds and then it will call the cleanup function

func (Task) Name added in v1.1.0

func (t Task) Name() string

Name returns the name of the function

type TaskFunc

type TaskFunc func(router *Router, t *Task) error

TaskFunc is the executable part of the program. The manager will provide, upon call, the router (and thus the server) and the task itself; changed to the task are allowed (exept for the name): you can modify through the router the timer of the task and also the functions themself! See TaskInitFunc, NewTask and router.RegisterBackgroundTask for the creation of a Task

type TaskInitFunc added in v1.1.0

type TaskInitFunc func() (startupF, execF, cleanupF TaskFunc)

TaskInitFunc is called when creating a task and its provided by the user. This function need to return 3 TaskFunc (they can be nil) and they will be set to the created task. The kind of functions are:

  • the startup function: called only upon creation, if it fails (panics or returns an error) the task will be disabled automatically
  • the exec function: called every time, could be interrupted if the server is shutting down; in this case, you will receive a signal on Task.ListenForExit, after that you will have 10 seconds before the server will call the cleanup function and exit
  • the cleanup function: called when the server is shutting down, this must not be potentially blocking (must end in a reasonable time)

type Website

type Website struct {
	Name                   string
	Dir                    string
	MainPages              []string
	NoLogPages             []string
	AllFolders             []string
	HiddenFolders          []string
	PageHeaders            map[string][][2]string
	EnableCSSX             bool
	AvoidMetricsAndLogging bool
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL