smallnetinformationservices

package module
v0.0.0-...-5f3da21 Latest Latest
Warning

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

Go to latest
Published: Feb 20, 2025 License: BSD-3-Clause Imports: 54 Imported by: 2

README

Smallnet Information Services (SIS)

Static Badge Contributor Covenant GitLab License GitLab Tag GitLab Issues

Smallnet Information Services (SIS) is a server software suite that plays a similar role to Microsoft's Internet Information Services (IIS), but for protocols in the small internet ecosystem. SIS provides integrated server support for Gemini, Gopher, Nex/NPS, Spartan, Misfin, Scroll, and Titan protocols. Using the built-in SIS Manager interface (accessed via Gemini), administrators can configure and manage multiple virtual servers across different protocols, defining their hostnames, certificates, and protocol-specific settings from a single administrative console.

SIS Manager gemini interface

Request Multiplexing

Incoming connections are multiplexed to each server based on the request's protocol, SNI and ALPN information, and any information provided within the protocol's request syntax. Multiplexing allows dynamic server configuration to take effect immediately without server restarts.

SIS uses port listeners to route incoming requests to the appropriate server. This allows for virtual hosting and multiple protocols on one port. However, some protocols have specific restrictions:

  • Nex and Gopher don't support virtual hosting, so they need dedicated ports
  • Misfin servers on shared ports must use unique hostnames and their own root CA certificates

Since most protocols either use different ports or support virtual hosting, the above restrictions are easily avoided.

Security

SIS implements features that ensure the security of your system:

  • All servers by default rate-limit incoming connections based on IP addresses.
  • There is a global max concurrent connection limit.
  • File permissions are taken into account when serving directories, files, and CGI scripts.
Permissions Under Unix Systems (unimplemented)

SIS will only serve world-readable content; all files and directories must be world-readable. If they are not, they are not served and are hidden from directory listings.

CGI scripts must be world-executable and world-readable to function properly.

Windows Systems (unimplemented)

Like Apache, when SIS is installed as a Windows service, it is ran under a particular user account created for the server. SIS will only serve content readable by this user. CGI scripts must also be executable by this user.

Installing and Using

View installation and usage documentation here.

Client Library

SIS can be used as a Golang library to: extend an existing server, build a custom server from scratch, create CGI applications, or implement SCGI application servers. See the section on Using SIS as a Library for more information.

SCGI Application Server Example
package main

import sis "gitlab.com/sis-suite/smallnetinformationservices"

func main() {
    // Start SCGI Application Server, in configless mode, meaning there will not be a SIS manager or configuration files.
    context, err := sis.InitConfiglessMode()
    if err != nil {
        panic(err)
    }

    // For SCGI application servers, the Hostname is the expected hostname given from the main gemini server (aka. REQUEST_DOMAIN
    // or SERVER_NAME), and the Port is the expected serve port given from the main gemini server (aka. SERVER_PORT).
    hosts := [...]sis.HostConfig{
        {BindAddress: "localhost", BindPort: "5001", Hostname: "localhost", Port: "1995", Upload: false, SCGI: true},
        {BindAddress: "localhost", BindPort: "5001", Hostname: "localhost", Port: "1995", Upload: true, SCGI: true},
    }
    scgi_gemini_server := context.AddServer(sis.Server{Name: "AuraMuse", Type: sis.ServerType_Gemini}, hosts[:]...)
    scgi_gemini_server.AddRoute("/", func(request sis.Request {
        request.Gemini("# SCGI Application Server Homepage\n")
        request.Link("/test", "Test Link") // This makes sure the link is prepended with the SERVER_NAME, SERVER_PORT, and SCRIPT_NAME given to the SCGI application server.
        request.Gemini("=> /test Another Test Link\n") // request.Gemini() also converts all links in the given gemtext to their correct version by prepending SCRIPT_NAME to absolute links.
    })
    scgi_gemini_server.AddRoute("/test", func(request sis.Request {
        request.Gemini("Hello World!\n")
    })

    context.Start()
}

Documentation

Index

Constants

View Source
const (
	ScrollResponseUDC_Class4 ScrollResponseUDC = iota
	ScrollResponseUDC_Class0                   // Knowledge, General Science, Docs, RFCs, Software, Data
	ScrollResponseUDC_Class1
	ScrollResponseUDC_Class2
	ScrollResponseUDC_Class3
	ScrollResponseUDC_Class5
	ScrollResponseUDC_Class6
	ScrollResponseUDC_Class7
	ScrollResponseUDC_Class8
	ScrollResponseUDC_Class9

	ScrollResponseUDC_GeneralKnowledge   = ScrollResponseUDC_Class0
	ScrollResponseUDC_Docs               = ScrollResponseUDC_Class0
	ScrollResponseUDC_Data               = ScrollResponseUDC_Class0
	ScrollResponseUDC_GeneralScience     = ScrollResponseUDC_Class0
	ScrollResponseUDC_Reference          = ScrollResponseUDC_Class0
	ScrollResponseUDC_CompSci            = ScrollResponseUDC_Class0
	ScrollResponseUDC_News               = ScrollResponseUDC_Class0
	ScrollResponseUDC_ComputerTechnology = ScrollResponseUDC_Class0

	ScrollResponseUDC_Philosophy = ScrollResponseUDC_Class1
	ScrollResponseUDC_Psychology = ScrollResponseUDC_Class1

	ScrollResponseUDC_Religion  = ScrollResponseUDC_Class2
	ScrollResponseUDC_Theology  = ScrollResponseUDC_Class2
	ScrollResponseUDC_Scripture = ScrollResponseUDC_Class2

	ScrollResponseUDC_SocialScience = ScrollResponseUDC_Class3
	ScrollResponseUDC_Politics      = ScrollResponseUDC_Class3

	ScrollResponseUDC_Unclassed  = ScrollResponseUDC_Class4
	ScrollResponseUDC_Aggregator = ScrollResponseUDC_Class4
	ScrollResponseUDC_Directory  = ScrollResponseUDC_Class4
	ScrollResponseUDC_Index_Menu = ScrollResponseUDC_Class4
	ScrollResponseUDC_Misc       = ScrollResponseUDC_Class4

	ScrollResponseUDC_Mathematics    = ScrollResponseUDC_Class5
	ScrollResponseUDC_NaturalScience = ScrollResponseUDC_Class5

	ScrollResponseUDC_AppliedScience    = ScrollResponseUDC_Class6
	ScrollResponseUDC_Medicine          = ScrollResponseUDC_Class6
	ScrollResponseUDC_Health            = ScrollResponseUDC_Class6
	ScrollResponseUDC_GeneralTechnology = ScrollResponseUDC_Class6
	ScrollResponseUDC_Engineering       = ScrollResponseUDC_Class6
	ScrollResponseUDC_Business          = ScrollResponseUDC_Class6
	ScrollResponseUDC_Accountancy       = ScrollResponseUDC_Class6

	ScrollResponseUDC_Art                = ScrollResponseUDC_Class7
	ScrollResponseUDC_Fashion            = ScrollResponseUDC_Class7
	ScrollResponseUDC_Entertainment      = ScrollResponseUDC_Class7
	ScrollResponseUDC_Music              = ScrollResponseUDC_Class7
	ScrollResponseUDC_GamingVideos       = ScrollResponseUDC_Class7
	ScrollResponseUDC_FictionalMovies    = ScrollResponseUDC_Class7
	ScrollResponseUDC_FictionalAnimation = ScrollResponseUDC_Class7
	ScrollResponseUDC_FictionalTVShows   = ScrollResponseUDC_Class7
	ScrollResponseUDC_Sport              = ScrollResponseUDC_Class7
	ScrollResponseUDC_Fitness            = ScrollResponseUDC_Class7
	ScrollResponseUDC_Recreation         = ScrollResponseUDC_Class7

	ScrollResponseUDC_Linguistics       = ScrollResponseUDC_Class8
	ScrollResponseUDC_Literature        = ScrollResponseUDC_Class8
	ScrollResponseUDC_LiteraryCriticism = ScrollResponseUDC_Class8
	ScrollResponseUDC_Memoir            = ScrollResponseUDC_Class8
	ScrollResponseUDC_PersonalLog       = ScrollResponseUDC_Class8
	ScrollResponseUDC_BookReview        = ScrollResponseUDC_Class8
	ScrollResponseUDC_MovieReview       = ScrollResponseUDC_Class8
	ScrollResponseUDC_VideoReview       = ScrollResponseUDC_Class8
	ScrollResponseUDC_MusicReview       = ScrollResponseUDC_Class8

	ScrollResponseUDC_History   = ScrollResponseUDC_Class9
	ScrollResponseUDC_Geography = ScrollResponseUDC_Class9
	ScrollResponseUDC_Biography = ScrollResponseUDC_Class9
)

Variables

View Source
var OID_CN = asn1.ObjectIdentifier{2, 5, 4, 3}

OID_CN represents the Object Identifier for the Common Name (CN) attribute in X.500 directory services. It is commonly used to store the name of an entity (e.g., a person, organization, or domain) in X.509 certificates.

View Source
var OID_MISFIN = "2.25.276466666638671594291857646440529523315.0" // 2.25.276466666638671594291857646440529523315.0
View Source
var OID_USER_ID = asn1.ObjectIdentifier{0, 9, 2342, 19200300, 100, 1, 1}

OID_USER_ID represents the Object Identifier for the userId attribute in X.500 directory services. It is commonly used to store a user's login name or username in X.509 certificates.

View Source
var TOFUMap map[string]string

Maps address to fingerprint. Shared between all servers

View Source
var Version string = "0.1"

Functions

func ArchiveMimetype

func ArchiveMimetype(mimetype string) bool

func AudioMimetype

func AudioMimetype(mimetype string) bool

func CalendarMimetype

func CalendarMimetype(mimetype string) bool

func CertFilename

func CertFilename(filename string) bool

func CertMimetype

func CertMimetype(mimetype string) bool

func ContainsCensorWords

func ContainsCensorWords(str string) bool

func CutAny

func CutAny(s string, chars string) (before string, after string, found bool)

CutAny slices s around any Unicode code point from chars, returning the text before and after it. The found result reports whether any Unicode code point was appears in s. If it does not appear in s, CutAny returns s, "", false.

func DirFS

func DirFS(name string) fs.FS

func DocumentMimetype

func DocumentMimetype(mimetype string) bool

Where do markup language files get placed?

func DotFilename

func DotFilename(filename string) bool

func FilenameToGopherItemtype

func FilenameToGopherItemtype(filename string) rune

Use when you cannot get the file's mimetype, like if converting URLs

func GenerateSelfSignedCertificateAndPrivateKey

func GenerateSelfSignedCertificateAndPrivateKey(keyType KeyType, common_name string, hosts []string, user_id string, not_after time.Time, pemBuffer *bytes.Buffer) (*x509.Certificate, error)

func InsertParamsIntoRouteString

func InsertParamsIntoRouteString(route string, params map[string]string, globString string, reverse bool) string

Reverse will insert params into components starting with ":". Otherwise, params will be inserted into components starting with "$"

func MimetypeGetsLangParam

func MimetypeGetsLangParam(mt_string string) bool

func MimetypeToGopherItemtype

func MimetypeToGopherItemtype(mt_string string, mt_parent_string string) rune

func PrintRoute

func PrintRoute(node *RouteNode, indent int)

func PrivacySensitiveFilename

func PrivacySensitiveFilename(filename string) bool

func PrivacySensitiveMimetype

func PrivacySensitiveMimetype(mimetype string) bool

func ProtocolHasDownload

func ProtocolHasDownload(protocol ProtocolType) bool

func ProtocolHasUpload

func ProtocolHasUpload(protocol ProtocolType) bool

func ProtocolIsTLS

func ProtocolIsTLS(protocol ProtocolType) bool

func ProtocolToName

func ProtocolToName(protocol ProtocolType) string

func ScanUpToTitle

func ScanUpToTitle(reader io.ReadSeeker) string

Returns the header data (everything up to but excluding the first title of the document)

func UDCToSuccessResponse

func UDCToSuccessResponse(value ScrollResponseUDC) int

func VideoMimetype

func VideoMimetype(mimetype string) bool

Types

type BindPortHostnameCertificate

type BindPortHostnameCertificate struct {
	CertFilepath       CertID
	Certificate        *x509.Certificate
	PrivateKey         crypto.PrivateKey
	PrivateKeyPemBytes []byte
}

A certificate for a given BindAddr+Port+Hostname Pair

func (*BindPortHostnameCertificate) GetInfo

TODO: Return empty CertInfo if cannot load cert file and cert is empty.

func (*BindPortHostnameCertificate) GetTLSCertificate

func (c *BindPortHostnameCertificate) GetTLSCertificate() *tls.Certificate

TODO: Return nil if cannot load cert file and cert is empty.

func (*BindPortHostnameCertificate) IsEmpty

func (c *BindPortHostnameCertificate) IsEmpty() bool

type CertConnection

type CertConnection struct {
	BindAddress string
	BindPort    string
	Hostname    string // TODO: Empty for default/none
}

type CertID

type CertID string // Absolute Filepath

type CertInfo

type CertInfo struct {
	CN      string
	Domains []string
	UserID  string

	IsCA    bool
	Expired bool
	// contains filtered or unexported fields
}

type CertificateManager

type CertificateManager struct {
	CertIDs                map[CertID]*BindPortHostnameCertificate
	CertConnections        map[CertConnection]*BindPortHostnameCertificate
	ServerHostMappings     map[ServerHost]ServerHostMapping
	PortListenerProperties map[PortListenerID]PortListenerProperties // TODO: Deal with this map when port listeners and server handles are deleted.

}

Manages Certificates, their connections to BindPortHostnames, as well as Server Routes.

func NewCertManager

func NewCertManager() *CertificateManager

func (*CertificateManager) AddCertificateConnection

func (m *CertificateManager) AddCertificateConnection(filepath string, bindaddress string, bindport string, hostname string) CertID

func (*CertificateManager) AddServerHostMapping

func (m *CertificateManager) AddServerHostMapping(bindaddress string, bindport string, hostname string, port string, upload bool, scgi bool, handle VirtualServerHandle)

func (*CertificateManager) GetCertificate

func (m *CertificateManager) GetCertificate(bindaddress string, bindport string, hostname string) (*BindPortHostnameCertificate, bool)

func (*CertificateManager) GetCertificateFromID

func (m *CertificateManager) GetCertificateFromID(id CertID) (*BindPortHostnameCertificate, bool)

GetCertificateFromID gets the certificate given the certificate ID. Use GetOrAddCertificate() to get a certificate and add it if it hasn't already been added.

func (*CertificateManager) GetCertificateFromServerHost

func (m *CertificateManager) GetCertificateFromServerHost(key ServerHost) (*BindPortHostnameCertificate, bool)

func (*CertificateManager) GetCertificatesForPortListener

func (m *CertificateManager) GetCertificatesForPortListener(bindaddress string, bindport string) map[string]*BindPortHostnameCertificate

func (*CertificateManager) GetCertificatesWithNoConnections

func (m *CertificateManager) GetCertificatesWithNoConnections() []*BindPortHostnameCertificate

GetCertificatesWithNoConnections gets orphaned certificates that have no connectins to hostnames.

func (*CertificateManager) GetDefaultCertForPortListener

func (m *CertificateManager) GetDefaultCertForPortListener(l *PortListener) *BindPortHostnameCertificate

func (*CertificateManager) GetHostsOfHostname

func (m *CertificateManager) GetHostsOfHostname(hostname string) []ServerHost

GetHostsOfHostname gets all Hosts of a hostname attached to any bind address and bind port.

func (*CertificateManager) GetHostsOfHostnameAndPort

func (m *CertificateManager) GetHostsOfHostnameAndPort(hostname string, port string) []ServerHost

GetHostsOfHostnameAndPort gets all Hosts of a hostname and port attached to any bind address and bind port.

func (*CertificateManager) GetHostsOfHostnameOnPortListener

func (m *CertificateManager) GetHostsOfHostnameOnPortListener(bindaddress string, bindport string, hostname string) []ServerHost

GetHostsOfHostname gets all Hosts of a hostname attached to any bind address and bind port.

func (*CertificateManager) GetHostsOnPortListener

func (m *CertificateManager) GetHostsOnPortListener(bindaddress string, bindport string) []ServerHost

func (*CertificateManager) GetNonTLSHostsOnPortListener

func (m *CertificateManager) GetNonTLSHostsOnPortListener(bindaddress string, bindport string) []ServerHost

func (*CertificateManager) GetOrAddCertificate

func (m *CertificateManager) GetOrAddCertificate(id CertID) *BindPortHostnameCertificate

func (*CertificateManager) GetServerCertificates

func (m *CertificateManager) GetServerCertificates(handle VirtualServerHandle) []*BindPortHostnameCertificate

GetServerCertificates gets the certificates of the server's hosts.

func (*CertificateManager) GetServerFromHostMapping

func (m *CertificateManager) GetServerFromHostMapping(bindaddress string, bindport string, hostname string, port string, upload bool, scgi bool) (ServerHostMapping, bool)

func (*CertificateManager) GetServerHosts

func (m *CertificateManager) GetServerHosts(handle VirtualServerHandle) []ServerHost

GetServerHosts gets all Hosts of a particular server.

func (*CertificateManager) GetServerHostsOnPortListener

func (m *CertificateManager) GetServerHostsOnPortListener(bindaddress string, bindport string, handle VirtualServerHandle) []ServerHost

GetServerHosts gets all Hosts of a particular server.

func (*CertificateManager) GetServerHostsWithServePortOnPortListener

func (m *CertificateManager) GetServerHostsWithServePortOnPortListener(bindaddress string, bindport string, serveport string, handle VirtualServerHandle) []ServerHost

GetServerHosts gets all Hosts of a particular server.

func (*CertificateManager) PortListenerHasServerHostNotOfProtocol

func (m *CertificateManager) PortListenerHasServerHostNotOfProtocol(bindaddress string, bindport string, protocol ProtocolType) bool

func (*CertificateManager) PortListenerHasServerHostOfProtocol

func (m *CertificateManager) PortListenerHasServerHostOfProtocol(bindaddress string, bindport string, protocol ProtocolType) bool

func (*CertificateManager) RemoveCertificate

func (m *CertificateManager) RemoveCertificate(id CertID)

func (*CertificateManager) RemoveCertificateConnection

func (m *CertificateManager) RemoveCertificateConnection(bindaddress string, bindport string, hostname string)

func (*CertificateManager) RemoveCertificateConnections

func (m *CertificateManager) RemoveCertificateConnections(id CertID)

func (*CertificateManager) RemoveCertificatesWithNoConnections

func (m *CertificateManager) RemoveCertificatesWithNoConnections()

RemoveCertificatesWithNoConnections removes orphaned certificates that have no connections to hostnames.

func (*CertificateManager) RemoveHostname

func (m *CertificateManager) RemoveHostname(bindaddress string, bindport string, hostname string)

RemoveHostname removes the server routes of the given hostname and its certificate connections.

func (*CertificateManager) RemoveHostnameAndPort

func (m *CertificateManager) RemoveHostnameAndPort(bindaddress string, bindport string, hostname string, port string)

RemoveHostname removes the server routes of the given hostname and port on a given bind address and bind port, as well as the certificate connections if no server routes of the hostname exist with other ports.

func (*CertificateManager) RemoveServer

func (m *CertificateManager) RemoveServer(handle VirtualServerHandle)

TODO: RemoveServer removes the certificate connections and server routes of the given server handle. Does not remove the certificates or cert connections of hostnames used on other servers.

func (*CertificateManager) RemoveServerHostMapping

func (m *CertificateManager) RemoveServerHostMapping(bindaddress string, bindport string, hostname string, port string, upload bool, scgi bool)

func (*CertificateManager) RemoveServerHosts

func (m *CertificateManager) RemoveServerHosts(handle VirtualServerHandle)

RemoveServerRoutes removes just the routes of the given server handle. Will not remove any certificates or certificate connections associated with the server's hosts. For that, use RemoveServer().

func (*CertificateManager) RemoveServerHostsOfHostname

func (m *CertificateManager) RemoveServerHostsOfHostname(bindaddress string, bindport string, hostname string)

RemoveServerHostsOfHostnameAndPort removes all Hosts of a given Hostname on a given PortListener.

func (*CertificateManager) RemoveServerHostsOfHostnameAndPort

func (m *CertificateManager) RemoveServerHostsOfHostnameAndPort(bindaddress string, bindport string, hostname string, port string)

RemoveServerHostsOfHostnameAndPort removes all Hosts of a given Hostname and Port on a given PortListener.

type ClientCertificate

type ClientCertificate struct {
	SerialNumber  string // Certificate Serial Number
	Hash          string
	HashType      string // Usually SHA256 if Hash given from SIS itself. Could be empty if hash was given to SCGI Application Server by different server software.
	MD5Hash       string // NOTE: Added as a workaround to upgrade AuraGem's database user hashes to SHA256. Empty if not available.
	NotBefore     time.Time
	NotAfter      time.Time
	Subject       string // Subject CN
	Issuer        string // Issuer CN
	SubjectUserID string // OID_USER_ID

}

func ClientCertificateFromCertificate

func ClientCertificateFromCertificate(cert *x509.Certificate) ClientCertificate

type HostConfig

type HostConfig struct {
	BindAddress string
	BindPort    string
	Hostname    string
	Port        string
	Upload      bool
	CertPath    string
	SCGI        bool // Whether the host should only use SCGI or not. SCGI hosts don't require a hostname, serve port, or certificate, since these are all managed by the SCGI "client".
}

type KeyType

type KeyType int
const (
	KeyType_ECDSA KeyType = iota
	KeyType_ED25519
	KeyType_RSA
)

type Log

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

type MaybeTLSListener

type MaybeTLSListener struct {
	net.Listener
	// contains filtered or unexported fields
}

func (MaybeTLSListener) Accept

func (l MaybeTLSListener) Accept() (net.Conn, error)

type MisfinCertInfo

type MisfinCertInfo struct {
	IsCA bool
	// contains filtered or unexported fields
}

type PortListener

type PortListener struct {
	SIS                      *SISContext
	BindAddress              string
	BindPort                 string
	MaxConcurrentConnections int

	TorServer VirtualServerHandle
	TorKey    crypto.PrivateKey
	// contains filtered or unexported fields
}

func NewPortListener

func NewPortListener(SIS *SISContext, BindAddress string, Port string) *PortListener

Create new PortListener

func (*PortListener) DefaultServer

func (l *PortListener) DefaultServer() VirtualServerHandle

func (*PortListener) ID

func (l *PortListener) ID() PortListenerID

func (*PortListener) SetTorKey

func (l *PortListener) SetTorKey(key crypto.PrivateKey)

func (*PortListener) SetTorServerRoute

func (l *PortListener) SetTorServerRoute(server VirtualServerHandle)

func (*PortListener) Start

func (l *PortListener) Start(wg *sync.WaitGroup)

type PortListenerID

type PortListenerID struct {
	BindAddress string
	BindPort    string
}

type PortListenerProperties

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

type ProtocolType

type ProtocolType uint
const ProtocolType_Gemini ProtocolType = 1
const ProtocolType_Gopher ProtocolType = 4
const ProtocolType_Gopher_SSL ProtocolType = 5 // TODO
const ProtocolType_Guppy ProtocolType = 12 // TODO
const ProtocolType_Misfin_A ProtocolType = 6 // Deprecated
const ProtocolType_Misfin_B ProtocolType = 7
const ProtocolType_Misfin_C ProtocolType = 8
const ProtocolType_NPS ProtocolType = 3
const ProtocolType_Nex ProtocolType = 2
const ProtocolType_Scorpion ProtocolType = 13 // TODO: Has both TLS and Non-TLS?
const ProtocolType_Scroll ProtocolType = 11
const ProtocolType_Spartan ProtocolType = 10
const ProtocolType_Titan ProtocolType = 9
const ProtocolType_Unknown ProtocolType = 0

func NameToProtocol

func NameToProtocol(name string) ProtocolType

type RateLimitListItem

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

type Request

type Request struct {
	Type ProtocolType // The expected protocol. When proxied, this will be the protocol being proxied to. Use proxyFromType for the protocol being proxied from.

	Host ServerHost // The Host information of the current request

	GlobString string // Set to the path components of the glob part of the route

	DataSize int64 // Expected Size for upload (-1 for any size until connection close)

	DataMime string // Used for Titan and other protocols that support upload with mimetype. For Spartan, it is usually empty or "text/plain" if proxying to Spartan servers from servers that use queries.

	UserCert   ClientCertificate // Used for protocols that support TLS Client Certs (Misfin and Gemini)
	IP         string
	RemotePort string // Remote Port of client host

	ProxiedUnder string // The path being proxied under. This is necessary to proxy gemini and nex over to gopher, because gopher requires links be absolute to originating server. It is also used for SCGI application servers, where it is set to the SCRIPT_NAME environment variable.

	Server VirtualServerHandle

	ScrollRequestedLanguages []string
	// contains filtered or unexported fields
}

func (*Request) Abstract

func (r *Request) Abstract(mimetype string, data string) error

For sending an Abstract file. Will parse data to get Author metadata.

func (*Request) BadRequest

func (r *Request) BadRequest(format string, elem ...any) error

func (*Request) Bytes

func (r *Request) Bytes(mimetype string, data []byte) error

func (*Request) CGIFailure

func (r *Request) CGIFailure(format string, elem ...any) error

func (*Request) ClearClassification

func (r *Request) ClearClassification(classification ScrollResponseUDC)

func (*Request) ClearScrollMetadataResponse

func (r *Request) ClearScrollMetadataResponse()

func (*Request) ClientCertNotAuthorized

func (r *Request) ClientCertNotAuthorized(format string, elem ...any) error

func (*Request) DataStream

func (r *Request) DataStream(filename string, reader io.ReadSeeker) (err error)

If filename is empty, the mimetype will still be detected from the content of the data.

func (*Request) DisableConvertMode

func (r *Request) DisableConvertMode()

func (*Request) EnableConvertMode

func (r *Request) EnableConvertMode()

func (*Request) File

func (r *Request) File(filePath string) error

Reads whole file into memory, automatically determins the correct mimetype, and sends it over (converting if in convert mode). If file not found or error on opening file, returns with error without sending anything back to the connection. Prefer FileMimetype() if you know the mimetype beforehand.

func (*Request) FileMimetype

func (r *Request) FileMimetype(mimetype string, filePath string) error

func (*Request) Fragment

func (r *Request) Fragment() string

NOTE: Should almost never be used

func (*Request) Gemini

func (r *Request) Gemini(text string) error

TODO: Add a way to configure nex width in Request (or Nex Server)

func (*Request) GetAbstractWithInlineMetadata

func (r *Request) GetAbstractWithInlineMetadata(data string) (abstractData string)

func (*Request) GetParam

func (r *Request) GetParam(name string) string

Returns empty string if param not in route

func (*Request) GetUploadData

func (r *Request) GetUploadData() ([]byte, error)

Get Titan or Spartan raw data.

func (*Request) Gophermap

func (r *Request) Gophermap(text string) error

TODO: make sure all lines end in CRLF

func (*Request) GophermapLine

func (r *Request) GophermapLine(linetype string, name string, selector string, hostname string, port string) error

Enter empty strings for hostname and port to use the server's hostname and port. TODO: Handle URL: links and cross-server links

func (*Request) HasUserCert

func (r *Request) HasUserCert() bool

func (*Request) Hostname

func (r *Request) Hostname() string

TODO: Reconsider how this works... Gets the requested hostname for protocols that use those in requests If not used in request, then gets the hostname of the server.

func (*Request) HostnamePort

func (r *Request) HostnamePort() string

Hostname + Port. Port is excluded if it's the default of the protocol.

func (*Request) IPHash

func (r *Request) IPHash() string

Takes checksum hash of IP and returns it in a hex string

func (r *Request) Link(link string, text string) error

Sends a link via the current expected protocol, prepending the proxied path if applicable. The link must be manually handled; it will not take into account routes that were created with a RoutePrefix. If you want to send over an absolute link, use LinkAbs to make relative links absolute, which *will* automatically handle routes created with a RoutePrefix.

func (*Request) LinkAbs

func (r *Request) LinkAbs(link string, text string) error

LinkAbs turns relative links absolute by joining them with the current path of request, also prepending the proxied path if applicable. This can be used to take into account routes that were created with a RoutePrefix.

func (*Request) Markdown

func (r *Request) Markdown(text string) error

func (*Request) NexListing

func (r *Request) NexListing(text string) error

Send Next text. TODO: This is unfinished.

func (*Request) NotFound

func (r *Request) NotFound(format string, elem ...any) error

func (*Request) Path

func (r *Request) Path() string

Gets the requested path, removing hostname and scheme information for protocols that use those in requests. Path is unescaped if part of URL (for protocols that use URL requests). Unescaping is unnecessary for Nex and Gopher.

func (*Request) PlainText

func (r *Request) PlainText(format string, elem ...any) error

func (*Request) PromptLine

func (r *Request) PromptLine(link string, text string) error

Uses a regular link linetype for Gemini and Nex, and a prompt/search linetype for Spartan and Gopher. The link should be in standard url format, even for gopher servers. The proxied path is auto-prepended if applicable. The link must be manually handled; it will not take into account routes that were created with a RoutePrefix. If you want to send over an absolute link, use PromptLineAbs to make relative links absolute, which *will* automatically handle routes created with a RoutePrefix.

func (*Request) PromptLineAbs

func (r *Request) PromptLineAbs(link string, text string) error

Uses a regular link linetype for Gemini and Nex, and a prompt/search linetype for Spartan and Gopher. The link should be in standard url format, even for gopher servers. The proxied path is auto-prepended if applicable. PromptLineAbs turns relative links absolute by joining them with the current path of request, also prepending the proxied path if applicable. This can be used to take into account routes that were created with a RoutePrefix.

func (*Request) Proxied

func (r *Request) Proxied() bool

Proxied returns true if request is being proxied, or if the request is going through an SCGI application server.

func (*Request) Query

func (r *Request) Query() (string, error)

Gets the query for protocols that support queries in requests. The returned query is unescaped. If Spartan, it gets the *raw* uploaded data (if there is any) as text. To get it query escaped, use request.RawQuery() If data is longer than Spartan Query Limit, then this method will return an error.

func (*Request) RawFragment

func (r *Request) RawFragment() string

NOTE: Should almost never be used

func (r *Request) RawLink(link string, text string) error

Sends a link without any conversion, RouteGroup prefix, or proxy correction.

func (*Request) RawPath

func (r *Request) RawPath() string

Gets the requested path, removing hostname and scheme information for protocols that use those in requests Path is escaped if part of URL (for protocols that use URL requests). NOTE: Nex and Gopher requests are not escaped.

func (*Request) RawQuery

func (r *Request) RawQuery() (string, error)

Gets the escaped query for protocols that support queries in requests. If Spartan, it gets the uploaded data (if there is any) as text and escapes it. If data is longer than Spartan Query Limit, then this method will return an error.

func (*Request) Redirect

func (r *Request) Redirect(format string, elem ...any)

func (*Request) RequestClientCert

func (r *Request) RequestClientCert(format string, elem ...any) error

func (*Request) RequestInput

func (r *Request) RequestInput(format string, elem ...any) error

TODO: When proxying gopher to gemini, translate the gopher input requested message/error to a gemini input request.

func (*Request) Scheme

func (r *Request) Scheme() string

func (*Request) Scroll

func (r *Request) Scroll(text string) error

TODO: Add a way to configure nex width in Request (or Nex Server)

func (*Request) ScrollMetadataRequested

func (r *Request) ScrollMetadataRequested() bool

func (*Request) SendAbstract

func (r *Request) SendAbstract(mimetype string) error

Will send the abstract that is already stored in the scroll metadata

func (*Request) ServerUnavailable

func (r *Request) ServerUnavailable(format string, elem ...any) error

func (*Request) SetClassification

func (r *Request) SetClassification(classification ScrollResponseUDC)

func (*Request) SetKeepAliveConfig

func (r *Request) SetKeepAliveConfig(config net.KeepAliveConfig) error

func (*Request) SetLanguage

func (r *Request) SetLanguage(lang string)

Used for all protocols that send a mimetype in the response

func (*Request) SetNoLanguage

func (r *Request) SetNoLanguage()

Forces the response to have no lang parameter

func (*Request) SetScrollMetadataResponse

func (r *Request) SetScrollMetadataResponse(metadata ScrollMetadata)

func (*Request) SetSpartanQueryLimit

func (r *Request) SetSpartanQueryLimit(bytesize int64)

Limits the number of bytes of uploaded data to read when you call request.Query() or request.RawQuery(). The default is 1024 to (somewhat) match Gemini. This only applies to .RawQuery() and .Query() calls. It does not apply to .GetUploadData() calls.

func (*Request) Spartan

func (r *Request) Spartan(text string) error

func (*Request) Stream

func (r *Request) Stream(mimetype string, reader io.Reader) error

TODO: Use a buffer bool and provide a 32KB buffer from the pool. Streams a file, using a 32KB buffer by default. If you want to control the buffer size, use StreamBuffer.

func (*Request) StreamBuffer

func (r *Request) StreamBuffer(mimetype string, reader io.Reader, buf []byte) error

Provide a buffer to handle the copy. This allows you to control your own buffer size to increase performance. For big files, create a big buffer (at the cost of memory). For small files, create a smaller buffer.

func (*Request) TemporaryFailure

func (r *Request) TemporaryFailure(format string, elem ...any) error

func (*Request) TextWithMimetype

func (r *Request) TextWithMimetype(mimetype string, text string) error

TODO

func (*Request) Upload

func (r *Request) Upload() bool

Upload returns true if the request supports reading uploaded data

func (*Request) UserCertHash

func (r *Request) UserCertHash() string

func (*Request) UserCertOldGeminiHash

func (r *Request) UserCertOldGeminiHash() string

type RequestFlag

type RequestFlag byte

NOTE: If more are added, RequestFlag needs to be expanded to uin16 or above

const (
	RequestFlag_Upload                  RequestFlag = iota // Set if request supports upload.
	RequestFlag_HeaderSent                                 // Set if the response header has already been sent (for protocols that use response headers).
	RequestFlag_ConvertMode                                // Set to convert from given format to default format of protocol.
	RequestFlag_Proxied                                    // Set if request is proxied, or if an SCGI application server.
	RequestFlag_AllowServeCert                             // Set to allow serving cert/key files. Will be set to the route's security setting.
	RequestFlag_AllowServeDotFiles                         // Set to allow serving dot (and hidden) files. Will be set to the route's security setting.
	RequestFlag_ScrollMetadataRequested                    // Set if request is asking for Metadata from the Scroll protocol.
)

type RequestHandler

type RequestHandler func(request *Request)

TODO: Ability to return errors (especially NotFound, which redirects to the NotFoundHandler)

type RequestHeader

type RequestHeader struct {
	Protocol        ProtocolType
	Request         string            // The Selector/Path or URL that is requested. Includes the query string.
	Hostname        string            // Used for Gemini, Misfin, and Titan
	Port            string            // aka. ServePort, the public-facing port.
	ContentLength   int64             // Used for Titan, Misfin, and Spartan. If Titan protocol and 0, it's a titan delete request. If Spartan and 0, no upload data is expected.
	Token           string            // Used for Titan
	Mime            string            // Used for Titan
	UserCert        ClientCertificate // For TLS protocols
	MetadataRequest bool              // Used for Scroll protocol
	Languages       []string          // Used for Scroll protocol

	SCGI             bool
	SCGI_SERVER_NAME string
	SCGI_REMOTE_ADDR string
	SCGI_REMOTE_PORT string
	SCGI_REMOTE_HOST string // FQDN of client, or empty.
	SCGI_SCRIPT_NAME string
	SCGI_PATH_INFO   string // TODO

}

type RouteGroup

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

Attach a prefix to routes.

func (RouteGroup) AddCGIRoute

func (prefix RouteGroup) AddCGIRoute(p string, filePath string)

func (RouteGroup) AddDirectory

func (prefix RouteGroup) AddDirectory(p string, directoryPath string)

func (RouteGroup) AddFile

func (prefix RouteGroup) AddFile(p string, filePath string)

func (RouteGroup) AddProxyRoute

func (prefix RouteGroup) AddProxyRoute(p string, proxyRoute string, gopherItemType rune)

func (RouteGroup) AddRoute

func (prefix RouteGroup) AddRoute(p string, handler RequestHandler)

func (RouteGroup) AddSCGIRoute

func (prefix RouteGroup) AddSCGIRoute(p string, address string)

func (RouteGroup) AddUploadRoute

func (prefix RouteGroup) AddUploadRoute(p string, handler RequestHandler)

func (RouteGroup) Group

func (prefix RouteGroup) Group(p string) RouteGroup

Group creates a prefix to be automatically prepended to all routes created on the RouteGroup. It will also ensure all absolute links in the responses of the attached routes will be prepended with the group prefix.

type RouteListItem

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

type RouteNode

type RouteNode struct {
	Component string         // If equal to "*", then it's a blob and matches with everything.
	Handler   RequestHandler // If nil, no handler

	Parent   *RouteNode
	Children *RouteNode // Linked List of Children

	// Linked List Info
	Next *RouteNode
	// contains filtered or unexported fields
}

func (*RouteNode) ChildrenLength

func (node *RouteNode) ChildrenLength() int

func (*RouteNode) GetRouteAncestry

func (node *RouteNode) GetRouteAncestry() []*RouteNode

Gets array of route nodes from root to last component

func (*RouteNode) GetRoutePath

func (node *RouteNode) GetRoutePath() string

Gets the route path string

type Router

type Router struct {
	NotFoundHandler RequestHandler
	// contains filtered or unexported fields
}

Uses a tree to store routes, and matches using a breadth-first search algorithm.

func (*Router) GetRoutesList

func (router *Router) GetRoutesList() []RouteListItem

Flattens routes tree into a list of routes. Returns an array of strings.

func (*Router) PrintRouteTree

func (router *Router) PrintRouteTree()

func (*Router) Search

func (router *Router) Search(p string) (*RouteNode, string, map[string]string)

Uses breadth-first search. Returns node, globString (if exists), and params map TODO: Make sure to collect list of params TODO: Differentiate between "/blah/" and "/blah"?

type SISContext

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

func InitConfiglessMode

func InitConfiglessMode() (*SISContext, error)

Initialize SIS in configless mode, without an admin server. This is primarily for using SIS as a library to create one-off servers, especially for SCGI servers.

func InitSIS

func InitSIS(directory string) (*SISContext, error)

func (*SISContext) AddServer

func (context *SISContext) AddServer(server VirtualServer, hosts ...HostConfig) (VirtualServerHandle, error)

When directory is empty, creates subdirectory under SIS directory named with the server's name. TODO: Take in a ServerConfig, rather than a Server that gets copied TODO: Make loadSISConfig use this function?

func (*SISContext) AddServerHostMapping

func (context *SISContext) AddServerHostMapping(BindAddress string, BindPort string, Hostname string, ServePort string, Upload bool, scgi bool, server VirtualServerHandle)

func (*SISContext) AdminServer

func (context *SISContext) AdminServer() *VirtualServer

Get the Admin server, which will let you customize it (like by adding routes and handlers).

func (*SISContext) AllowIP

func (context *SISContext) AllowIP(ip string)

func (*SISContext) BlockIP

func (context *SISContext) BlockIP(ip string)

func (*SISContext) CreateServer

func (context *SISContext) CreateServer(t ServerType, name string, defaultLanguage string, hosts ...HostConfig) (VirtualServerHandle, error)

TODO: Other settings one might want to specify include Directory, FS, Pubnix, and MaxConcurrentConnections

func (*SISContext) EnterMaintenanceMode_All

func (context *SISContext) EnterMaintenanceMode_All()

Enters maintenance mode for all portListeners

func (*SISContext) FindServerByName

func (context *SISContext) FindServerByName(name string) VirtualServerHandle

func (*SISContext) FullRestart

func (context *SISContext) FullRestart()

func (*SISContext) GetOrAddCertificateConnection

func (context *SISContext) GetOrAddCertificateConnection(certFilepath string, bindaddress string, bindport string, hostname string) CertID

func (*SISContext) GetOrCreatePortListener

func (context *SISContext) GetOrCreatePortListener(BindAddress string, BindPort string) *PortListener

func (*SISContext) GetPortListener

func (context *SISContext) GetPortListener(BindAddress string, Port string) *PortListener

func (*SISContext) GetTor

func (context *SISContext) GetTor() *tor.Tor

func (*SISContext) IsIPBlocked

func (context *SISContext) IsIPBlocked(ip string) bool

func (*SISContext) Log

func (context *SISContext) Log(serverType ServerType, label string, msgFormat string, args ...any)

Concurrent-safe

func (*SISContext) SaveConfiguration

func (context *SISContext) SaveConfiguration() error

Saves SIS Config File TODO: Mutex?

func (context *SISContext) SetUpdateLink(link string)

Set a gemini link to update the server

func (*SISContext) ShutdownPortListeners

func (context *SISContext) ShutdownPortListeners()

Shuts down all Port Listeners, but does not shut down SIS

func (*SISContext) ShutdownSIS

func (context *SISContext) ShutdownSIS()

Shuts down all of SIS

func (*SISContext) Start

func (context *SISContext) Start()

Starts SIS. Must call InitSIS first.

func (*SISContext) UpdateAndRestart

func (context *SISContext) UpdateAndRestart(data []byte) string

You must have the new subprocess delete the renamed filename (which is returned by the function). You can do this by redirecting to a route that deletes the old file. By the time the redirect happens, the server would have been updated. You can pass in the data of the executable instead of downloading the data from the update link.

type ScrollMetadata

type ScrollMetadata struct {
	Author         string
	PublishDate    time.Time // Should be in UTC
	UpdateDate     time.Time // Should be in UTC
	Language       string    // Should use BCP47
	Abstract       string
	Classification ScrollResponseUDC
}

type ScrollResponseUDC

type ScrollResponseUDC uint8

func ClassificationStringToUDC

func ClassificationStringToUDC(value string) ScrollResponseUDC

func GetInlineMetadataFromGemtext

func GetInlineMetadataFromGemtext(reader io.Reader) (title string, author string, publishdate time.Time, modificationdate time.Time, language string, classification ScrollResponseUDC)

Scans until it sees a level-1 heading, and then stops scanning and returns it Works with gemtext, scrolltext, and markdown

type ServeMux

type ServeMux interface {
	AddRoute(p string, handler RequestHandler)
	AddUploadRoute(p string, handler RequestHandler)
	AddDirectory(p string, directoryPath string)
	AddCGIRoute(p string, filePath string)
	AddSCGIRoute(p string, address string)
	AddProxyRoute(p string, proxyRoute string, gopherItemType rune)
	AddFile(p string, filePath string)

	// Group creates a prefix to be automatically prepended to all routes created on the RouteGroup.
	Group(p string) RouteGroup
}

Provides methods to add routes to a VirtualServer or RouteGroup

type ServerDirFS

type ServerDirFS string

func (ServerDirFS) Lstat

func (dir ServerDirFS) Lstat(name string) (fs.FileInfo, error)
func (dir ServerDirFS) MkSymlink(name, target string) error

NOTE: The target is *not* relative to the dirFS

func (ServerDirFS) Mkdir

func (dir ServerDirFS) Mkdir(name string, perm fs.FileMode) error

func (ServerDirFS) Open

func (dir ServerDirFS) Open(name string) (fs.File, error)

func (ServerDirFS) OpenFile

func (dir ServerDirFS) OpenFile(name string, flag int, perm fs.FileMode) (fs.File, error)

func (ServerDirFS) ReadDir

func (dir ServerDirFS) ReadDir(name string) ([]fs.DirEntry, error)

func (ServerDirFS) ReadFile

func (dir ServerDirFS) ReadFile(name string) ([]byte, error)
func (dir ServerDirFS) Readlink(name string) (string, error)

func (ServerDirFS) Stat

func (dir ServerDirFS) Stat(name string) (fs.FileInfo, error)

func (ServerDirFS) WriteFile

func (dir ServerDirFS) WriteFile(name string, data []byte, perm fs.FileMode) error

type ServerFS

type ServerFS interface {
	fs.FS
	fs.ReadFileFS
	fs.ReadDirFS
	fsx.FS
	fsx.FSSupportingWrite
	fsx.FSSupportingMkSymlink
	fsx.FSSupportingReadlink
	fsx.FSSupportingStat
	WriteFile(name string, data []byte, perm fs.FileMode) error
}

Extends go-fsx/osfs to add ReadDir and ReadFile methods

type ServerHandlerFunc

type ServerHandlerFunc func(s *VirtualServer)

type ServerHost

type ServerHost struct {
	BindAddress string
	BindPort    string
	Hostname    string
	Port        string // aka. ServePort, the public facing port. Should be empty for nex, nps, gopher, and spartan. // TODO
	//Protocol    ProtocolType
	Upload bool
	SCGI   bool
}

func ParseHostString

func ParseHostString(host string) ServerHost

func (*ServerHost) IsEmpty

func (s *ServerHost) IsEmpty() bool

func (*ServerHost) ToString

func (s *ServerHost) ToString() string

type ServerHostMapping

type ServerHostMapping struct {
	ServePort string // The public-facing port. For nex, nps, gopher, and spartan, should be what was set in the config file.
	Handle    VirtualServerHandle
}

type ServerType

type ServerType int
const ServerType_Admin ServerType = 4 // Gemini + Titan
const ServerType_Gemini ServerType = 0 // Gemini + Titan
const ServerType_Gopher ServerType = 2 // Gopher
const ServerType_Misfin ServerType = 3 // Misfin(B) + Misfin(C) + Gemini + Titan
const ServerType_Nex ServerType = 1 // Nex + NPS
const ServerType_Scroll ServerType = 6 // Scroll + Titan
const ServerType_Spartan ServerType = 5 // Spartan
const ServerType_Unknown ServerType = 7

type VirtualServer

type VirtualServer struct {
	Name string
	Type ServerType

	Protocols   bitset.BitSet[ProtocolType, ProtocolType]
	KeyValStore cmap.ConcurrentMap[string, interface{}] // To store data that can be used in request handlers.

	MaxConcurrentConnections int    // -1 for unlimited
	Directory                string // Defaults to SIS Directory, unless configured to elsewhere via sis.conf file in code.
	FS                       ServerFS

	ServerHandler   ServerHandlerFunc // For custom servers
	DefaultLanguage string

	Pubnix       bool
	Router       Router // For Downloads
	UploadRouter Router // For Uploads (if applicable)

	RateLimitDuration time.Duration

	SIS *SISContext
	// contains filtered or unexported fields
}

NOTE: Usually accessed through a ServerHandle. See server_handle.go

func (*VirtualServer) AddCGIRoute

func (s *VirtualServer) AddCGIRoute(p string, filePath string)

func (*VirtualServer) AddDirectory

func (s *VirtualServer) AddDirectory(p string, directoryPath string)

AddDirectory adds a directory that's either absolute, or relative to the server's directory Remember that a server's directory, when not specified, defaults to a subdirectory named after the server's name under the SIS directory.

func (*VirtualServer) AddEmbedDirectory

func (s *VirtualServer) AddEmbedDirectory(p string, content embed.FS, directoryPath string)

func (*VirtualServer) AddEmbedFile

func (s *VirtualServer) AddEmbedFile(p string, content embed.FS, filePath string)

func (*VirtualServer) AddFile

func (s *VirtualServer) AddFile(p string, filePath string)

Adds a file that's either absolute, or relative to the server's directory

func (*VirtualServer) AddHosts

func (s *VirtualServer) AddHosts(hosts ...HostConfig)

func (*VirtualServer) AddProxyRoute

func (s *VirtualServer) AddProxyRoute(p string, proxyRoute string, gopherItemType rune)

Proxy routes will proxy the handler from a different server to this server and will automatically set the request to convert mode.

func (*VirtualServer) AddRoute

func (s *VirtualServer) AddRoute(p string, handler RequestHandler)

func (*VirtualServer) AddSCGIRoute

func (s *VirtualServer) AddSCGIRoute(p string, address string)

func (*VirtualServer) AddServerProxyRoute

func (s *VirtualServer) AddServerProxyRoute(p string, server VirtualServerHandle)

Proxies an entire (Virtual)Server underneath the given route.

func (*VirtualServer) AddUploadRoute

func (s *VirtualServer) AddUploadRoute(p string, handler RequestHandler)

func (*VirtualServer) CleanupRateLimiting

func (s *VirtualServer) CleanupRateLimiting()

Removes all IPs that are passed the rate-limit duration. There's no need to call this too often, but do not wait so long that the ip list becomes too big.

func (*VirtualServer) GetHandle

func (s *VirtualServer) GetHandle() VirtualServerHandle

func (*VirtualServer) GetHostOfPortListener

func (s *VirtualServer) GetHostOfPortListener(protocol ProtocolType, upload bool, bind_addr string, bind_port string, hostname string, port string, scgi bool) ServerHost

func (*VirtualServer) GetPreferredHost

func (s *VirtualServer) GetPreferredHost(protocol ProtocolType, upload bool, scgi bool) ServerHost

TODO: This doesn't work correctly (because it uses maps). We need to store what the preferred host should be (and if it changes, it should change).

func (*VirtualServer) GetPreferredHostOfPortListener

func (s *VirtualServer) GetPreferredHostOfPortListener(protocol ProtocolType, upload bool, bind_addr string, bind_port string, scgi bool) ServerHost

TODO: This doesn't work correctly (because it uses maps)

func (*VirtualServer) Group

func (s *VirtualServer) Group(p string) RouteGroup

Group creates a prefix to be automatically prepended to all routes created on the RouteGroup. It will also ensure all absolute links in the responses of the attached routes will be prepended with the group prefix.

func (*VirtualServer) HasNonTLSProtocol

func (s *VirtualServer) HasNonTLSProtocol() bool

func (*VirtualServer) HasTLSProtocol

func (s *VirtualServer) HasTLSProtocol() bool

func (*VirtualServer) HasUploadProtocol

func (s *VirtualServer) HasUploadProtocol() bool

func (*VirtualServer) IPRateLimit_ClearRedirectPath

func (s *VirtualServer) IPRateLimit_ClearRedirectPath(ip string)

func (*VirtualServer) IPRateLimit_ExpectRedirectPath

func (s *VirtualServer) IPRateLimit_ExpectRedirectPath(ip string, redirectPath string)

When a redirection occurs, let server know to expect another request immediately following the previous one so that the rate-limiting can be bypassed

func (*VirtualServer) IPRateLimit_IsExpectingRedirect

func (s *VirtualServer) IPRateLimit_IsExpectingRedirect(ip string) bool

func (*VirtualServer) IpRateLimit_GetExpectedRedirectPath

func (s *VirtualServer) IpRateLimit_GetExpectedRedirectPath(ip string) string

func (*VirtualServer) IsIPRateLimited

func (s *VirtualServer) IsIPRateLimited(ip string) bool

If not rate-limited, set ip to current time and return false. If last access time is within duration, set ip to current time and return true. Otherwise, set ip to current time and return false

func (*VirtualServer) LoadRoutes

func (s *VirtualServer) LoadRoutes() error

Located in server's directory (which defaults to the SIS directory)

func (*VirtualServer) SaveRoutes

func (s *VirtualServer) SaveRoutes() error

func (*VirtualServer) Scheme

func (s *VirtualServer) Scheme() string

Gets the default/download protocol Scheme

func (*VirtualServer) UploadScheme

func (s *VirtualServer) UploadScheme() string

type VirtualServerHandle

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

Handle value for servers

func (VirtualServerHandle) AddCGIRoute

func (handle VirtualServerHandle) AddCGIRoute(p string, filePath string)

func (VirtualServerHandle) AddDirectory

func (handle VirtualServerHandle) AddDirectory(p string, directoryPath string)

func (VirtualServerHandle) AddFile

func (handle VirtualServerHandle) AddFile(p string, filePath string)

func (VirtualServerHandle) AddHosts

func (handle VirtualServerHandle) AddHosts(hosts ...HostConfig)

func (VirtualServerHandle) AddProxyRoute

func (handle VirtualServerHandle) AddProxyRoute(p string, proxyRoute string, gopherItemType rune)

func (VirtualServerHandle) AddRoute

func (handle VirtualServerHandle) AddRoute(p string, handler RequestHandler)

func (VirtualServerHandle) AddSCGIRoute

func (handle VirtualServerHandle) AddSCGIRoute(p string, address string)

func (VirtualServerHandle) AddUploadRoute

func (handle VirtualServerHandle) AddUploadRoute(p string, handler RequestHandler)

func (VirtualServerHandle) CleanupRateLimiting

func (handle VirtualServerHandle) CleanupRateLimiting()

func (VirtualServerHandle) DefaultLanguage

func (handle VirtualServerHandle) DefaultLanguage() string

func (VirtualServerHandle) Directory

func (handle VirtualServerHandle) Directory() string

func (VirtualServerHandle) FS

func (handle VirtualServerHandle) FS() ServerFS

func (VirtualServerHandle) GetData

func (handle VirtualServerHandle) GetData(key string) (interface{}, bool)

func (VirtualServerHandle) GetPreferredHost

func (handle VirtualServerHandle) GetPreferredHost(protocol ProtocolType, upload bool, scgi bool) ServerHost

func (VirtualServerHandle) GetPreferredHostOfPortListener

func (handle VirtualServerHandle) GetPreferredHostOfPortListener(protocol ProtocolType, upload bool, bind_addr string, bind_port string, scgi bool) ServerHost

func (VirtualServerHandle) GetServer

func (handle VirtualServerHandle) GetServer() *VirtualServer

func (VirtualServerHandle) Group

func (handle VirtualServerHandle) Group(p string) RouteGroup

Group creates a prefix to be automatically prepended to all routes created on the RouteGroup. It will also ensure all absolute links in the responses of the attached routes will be prepended with the group prefix.

func (VirtualServerHandle) HasNonTLSProtocol

func (handle VirtualServerHandle) HasNonTLSProtocol() bool

func (VirtualServerHandle) HasTLSProtocol

func (handle VirtualServerHandle) HasTLSProtocol() bool

func (VirtualServerHandle) HasUploadProtocol

func (handle VirtualServerHandle) HasUploadProtocol() bool

func (VirtualServerHandle) IsIPRateLimited

func (handle VirtualServerHandle) IsIPRateLimited(ip string) bool

func (VirtualServerHandle) LoadRoutes

func (handle VirtualServerHandle) LoadRoutes() error

func (VirtualServerHandle) MaxConcurrentConnections

func (handle VirtualServerHandle) MaxConcurrentConnections() int

func (VirtualServerHandle) Name

func (handle VirtualServerHandle) Name() string

func (VirtualServerHandle) Protocols

func (VirtualServerHandle) Pubnix

func (handle VirtualServerHandle) Pubnix() bool

func (VirtualServerHandle) RateLimitDuration

func (handle VirtualServerHandle) RateLimitDuration() time.Duration

func (VirtualServerHandle) Router

func (handle VirtualServerHandle) Router() *Router

func (VirtualServerHandle) SIS

func (handle VirtualServerHandle) SIS() *SISContext

func (VirtualServerHandle) SaveRoutes

func (handle VirtualServerHandle) SaveRoutes() error

func (VirtualServerHandle) Scheme

func (handle VirtualServerHandle) Scheme() string

func (VirtualServerHandle) ServerHandler

func (handle VirtualServerHandle) ServerHandler() ServerHandlerFunc

func (VirtualServerHandle) SetData

func (handle VirtualServerHandle) SetData(key string, value interface{})

func (VirtualServerHandle) SetMaxConcurrentConnections

func (handle VirtualServerHandle) SetMaxConcurrentConnections(v int)

func (VirtualServerHandle) SetName

func (handle VirtualServerHandle) SetName(v string)

func (VirtualServerHandle) SetPubnix

func (handle VirtualServerHandle) SetPubnix(v bool)

func (VirtualServerHandle) SetRateLimitDuration

func (handle VirtualServerHandle) SetRateLimitDuration(v time.Duration)

func (VirtualServerHandle) SetSIS

func (handle VirtualServerHandle) SetSIS(v *SISContext)

func (VirtualServerHandle) SetServerHandler

func (handle VirtualServerHandle) SetServerHandler(v ServerHandlerFunc)

func (VirtualServerHandle) SetType

func (handle VirtualServerHandle) SetType(v ServerType)

func (VirtualServerHandle) Type

func (handle VirtualServerHandle) Type() ServerType

Directories

Path Synopsis
The main Smallnet Information Services Server
The main Smallnet Information Services Server

Jump to

Keyboard shortcuts

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