Documentation
¶
Overview ¶
Package gig implements high performance, minimalist Go framework for Gemini protocol.
Example:
package main import ( "github.com/handsomesymme/gig" ) func main() { // Gig instance g := gig.Default() // Routes g.Handle("/user/:name", func(c gig.Context) error { return c.Gemini(gig.StatusSuccess, "# Hello, %s!", c.Param("name")) }) // Start server g.Run("my.crt", "my.key") }
Index ¶
- Constants
- Variables
- func DefaultGeminiErrorHandler(err error, c Context)
- func DefaultSkipper(Context) bool
- func HEUQGjC() error
- type CertAuthConfig
- type CertAuthValidator
- type Context
- type FakeAddr
- type FakeConn
- func (c *FakeConn) Close() error
- func (c *FakeConn) ConnectionState() tls.ConnectionState
- func (c *FakeConn) LocalAddr() net.Addr
- func (c *FakeConn) Read(b []byte) (n int, err error)
- func (c *FakeConn) RemoteAddr() net.Addr
- func (c *FakeConn) SetDeadline(t time.Time) error
- func (c *FakeConn) SetReadDeadline(t time.Time) error
- func (c *FakeConn) SetWriteDeadline(t time.Time) error
- func (c *FakeConn) Write(b []byte) (n int, err error)
- type GeminiError
- type GeminiErrorHandler
- type Gig
- func (g *Gig) Close() error
- func (g *Gig) File(path, file string, m ...MiddlewareFunc) *Route
- func (g *Gig) Group(prefix string, m ...MiddlewareFunc) (gg *Group)
- func (g *Gig) Handle(path string, h HandlerFunc, m ...MiddlewareFunc) *Route
- func (g *Gig) NewFakeContext(uri string, tlsState *tls.ConnectionState) (Context, *FakeConn)
- func (g *Gig) PassAuthLoginHandle(path string, fn PassAuthLogin)
- func (g *Gig) Pre(middleware ...MiddlewareFunc)
- func (g *Gig) Reverse(name string, params ...interface{}) string
- func (g *Gig) Routes() []*Route
- func (g *Gig) Run(args ...interface{}) (err error)
- func (g *Gig) ServeGemini(c Context)
- func (g *Gig) Static(prefix, root string) *Route
- func (g *Gig) URL(handler HandlerFunc, params ...interface{}) string
- func (g *Gig) Use(middleware ...MiddlewareFunc)
- type Group
- type HandlerFunc
- type LoggerConfig
- type MiddlewareFunc
- func CertAuth(fn CertAuthValidator) MiddlewareFunc
- func CertAuthWithConfig(config CertAuthConfig) MiddlewareFunc
- func Logger() MiddlewareFunc
- func LoggerWithConfig(config LoggerConfig) MiddlewareFunc
- func PassAuth(check PassAuthCertCheck) MiddlewareFunc
- func Recover() MiddlewareFunc
- func RecoverWithConfig(config RecoverConfig) MiddlewareFunc
- type PassAuthCertCheck
- type PassAuthLogin
- type RecoverConfig
- type Renderer
- type Response
- type Route
- type Skipper
- type Status
Constants ¶
const ( MIMETextGemini = "text/gemini" MIMETextGeminiCharsetUTF8 = "text/gemini; charset=UTF-8" MIMETextPlain = "text/plain" MIMETextPlainCharsetUTF8 = "text/plain; charset=UTF-8" )
MIME types.
const (
// Version of Gig.
Version = "0.9.8"
)
Variables ¶
var ( // DefaultWriter is the default io.Writer used by gig for debug output and // middleware output like Logger() or Recovery(). // Note that both Logger and Recovery provides custom ways to configure their // output io.Writer. // To support coloring in Windows use: // import "github.com/mattn/go-colorable" // gig.DefaultWriter = colorable.NewColorableStdout() DefaultWriter io.Writer = os.Stdout // Debug enables gig to print its internal debug messages. Debug = true )
var ( ErrTemporaryFailure = NewError(StatusTemporaryFailure, "Temporary Failure") ErrCGIError = NewError(StatusCGIError, "CGI Error") ErrProxyError = NewError(StatusProxyError, "Proxy Error") ErrSlowDown = NewError(StatusSlowDown, "Slow Down") ErrPermanentFailure = NewError(StatusPermanentFailure, "Permanent Failure") ErrNotFound = NewError(StatusNotFound, "Not Found") ErrGone = NewError(StatusGone, "Gone") ErrProxyRequestRefused = NewError(StatusProxyRequestRefused, "Proxy Request Refused") ErrBadRequest = NewError(StatusBadRequest, "Bad Request") ErrClientCertificateRequired = NewError(StatusClientCertificateRequired, "Client Certificate Required") ErrCertificateNotAuthorised = NewError(StatusCertificateNotAuthorised, "Certificate Not Authorised") ErrCertificateNotValid = NewError(StatusCertificateNotValid, "Certificate Not Valid") ErrRendererNotRegistered = errors.New("renderer not registered") ErrInvalidCertOrKeyType = errors.New("invalid cert or key type, must be string or []byte") ErrServerClosed = errors.New("gemini: Server closed") )
Errors that can be inherited from using NewErrorFrom.
var ( // DefaultCertAuthConfig is the default CertAuth middleware config. DefaultCertAuthConfig = CertAuthConfig{ Skipper: DefaultSkipper, Validator: ValidateHasCertificate, } )
var ( // DefaultLoggerConfig is the default Logger middleware config. DefaultLoggerConfig = LoggerConfig{ Skipper: DefaultSkipper, Format: "time=\"${time_rfc3339}\" path=${path} status=${status} duration=${latency} ${error}\n", CustomTimeFormat: "2006-01-02 15:04:05.00000", } )
var ( // DefaultRecoverConfig is the default Recover middleware config. DefaultRecoverConfig = RecoverConfig{ Skipper: DefaultSkipper, StackSize: 4 << 10, DisableStackAll: false, DisablePrintStack: false, } )
var ( NotFoundHandler = func(c Context) error { return ErrNotFound } )
Error handlers.
Functions ¶
func DefaultGeminiErrorHandler ¶
DefaultGeminiErrorHandler is the default HTTP error handler. It sends a JSON response with status code.
func DefaultSkipper ¶
DefaultSkipper returns false which processes the middleware.
Types ¶
type CertAuthConfig ¶
type CertAuthConfig struct { // Skipper defines a function to skip middleware. Skipper Skipper // Validator is a function to validate client certificate. // Required. Validator CertAuthValidator }
CertAuthConfig defines the config for CertAuth middleware.
type CertAuthValidator ¶
type CertAuthValidator func(*x509.Certificate, Context) *GeminiError
CertAuthValidator defines a function to validate CertAuth credentials.
type Context ¶
type Context interface { // Response returns `*Response`. Response() *Response // IP returns the client's network address. IP() string // Certificate returns client's leaf certificate or nil if none provided Certificate() *x509.Certificate // CertHash returns a hash of client's leaf certificate or empty string is none CertHash() string // URL returns the URL for the context. URL() *url.URL // Path returns the registered path for the handler. Path() string // QueryString returns unescaped URL query string or error if the raw query // could not be unescaped. Use Context#URL().RawQuery to get raw query string. QueryString() (string, error) // RequestURI is the unmodified URL string as sent by the client // to a server. Usually the URL() or Path() should be used instead. RequestURI() string // Param returns path parameter by name. Param(name string) string // Get retrieves data from the context. Get(key string) interface{} // Set saves data in the context. Set(key string, val interface{}) // Render renders a template with data and sends a text/gemini response with status // code Success. Renderer must be registered using `Gig.Renderer`. Render(name string, data interface{}) error // Gemini sends a text/gemini response with status code Success. Gemini(text string, args ...interface{}) error // GeminiBlob sends a text/gemini blob response with status code Success. GeminiBlob(b []byte) error // Text sends a text/plain response with status code Success. Text(format string, values ...interface{}) error // Blob sends a blob response with status code Success and content type. Blob(contentType string, b []byte) error // Stream sends a streaming response with status code Success and content type. Stream(contentType string, r io.Reader) error // File sends a response with the content of the file. File(file string) error // NoContent sends a response with no body, and a status code and meta field. // Use for any non-2x status codes NoContent(code Status, meta string, values ...interface{}) error // Error invokes the registered error handler. Generally used by middleware. Error(err error) // Handler returns the matched handler by router. Handler() HandlerFunc // Gig returns the `Gig` instance. Gig() *Gig }
Context represents the context of the current request. It holds connection reference, path, path parameters, data and registered handler. DO NOT retain Context instance, as it will be reused by other connections.
type FakeConn ¶
FakeConn ia a fake net.Conn that can record what is written and can fail after FailAfter bytes were written.
func (*FakeConn) ConnectionState ¶
func (c *FakeConn) ConnectionState() tls.ConnectionState
ConnectionState always returns nil.
func (*FakeConn) RemoteAddr ¶
RemoteAddr returns fake address.
func (*FakeConn) SetDeadline ¶
SetDeadline always returns nil.
func (*FakeConn) SetReadDeadline ¶
SetReadDeadline always returns nil.
func (*FakeConn) SetWriteDeadline ¶
SetWriteDeadline always returns nil.
type GeminiError ¶
GeminiError represents an error that occurred while handling a request.
func NewError ¶
func NewError(code Status, message string) *GeminiError
NewError creates a new GeminiError instance.
func NewErrorFrom ¶
func NewErrorFrom(err *GeminiError, message string) *GeminiError
NewErrorFrom creates a new GeminiError instance using Code from existing GeminiError.
func ValidateHasCertificate ¶
func ValidateHasCertificate(cert *x509.Certificate, c Context) *GeminiError
ValidateHasCertificate returns ErrClientCertificateRequired if no certificate is sent. It also stores subject name in context under "subject".
func (*GeminiError) Error ¶
func (ge *GeminiError) Error() string
Error makes it compatible with `error` interface.
type GeminiErrorHandler ¶
GeminiErrorHandler is a centralized error handler.
type Gig ¶
type Gig struct { // HideBanner disables banner on startup. HideBanner bool // HidePort disables startup message. HidePort bool // GeminiErrorHandler allows setting custom error handler GeminiErrorHandler GeminiErrorHandler // Renderer must be set for Context#Render to work Renderer Renderer // ReadTimeout set max read timeout on socket. // Default is none. ReadTimeout time.Duration // WriteTimeout set max write timeout on socket. // Default is none. WriteTimeout time.Duration // TLSConfig is passed to tls.NewListener and needs to be modified // before Run is called. TLSConfig *tls.Config // contains filtered or unexported fields }
Gig is the top-level framework instance.
func Default ¶
func Default() *Gig
Default returns a Gig instance with Logger and Recover middleware enabled.
func (*Gig) File ¶
func (g *Gig) File(path, file string, m ...MiddlewareFunc) *Route
File registers a new route with path to serve a static file with optional route-level middleware.
func (*Gig) Group ¶
func (g *Gig) Group(prefix string, m ...MiddlewareFunc) (gg *Group)
Group creates a new router group with prefix and optional group-level middleware.
func (*Gig) Handle ¶
func (g *Gig) Handle(path string, h HandlerFunc, m ...MiddlewareFunc) *Route
Handle registers a new route for a path with matching handler in the router with optional route-level middleware.
func (*Gig) NewFakeContext ¶
NewFakeContext returns Context that writes to FakeConn.
func (*Gig) PassAuthLoginHandle ¶
func (g *Gig) PassAuthLoginHandle(path string, fn PassAuthLogin)
PassAuthLoginHandle sets up handlers to check username/password using PassAuthLogin.
func (*Gig) Pre ¶
func (g *Gig) Pre(middleware ...MiddlewareFunc)
Pre adds middleware to the chain which is run before router.
func (*Gig) Run ¶
Run starts a Gemini server. If `certFile` or `keyFile` is `string` the values are treated as file paths. If `certFile` or `keyFile` is `[]byte` the values are treated as the certificate or key as-is.
func (*Gig) Static ¶
Static registers a new route with path prefix to serve static files from the provided root directory.
func (*Gig) URL ¶
func (g *Gig) URL(handler HandlerFunc, params ...interface{}) string
URL generates a URL from handler.
func (*Gig) Use ¶
func (g *Gig) Use(middleware ...MiddlewareFunc)
Use adds middleware to the chain which is run after router.
type Group ¶
type Group struct {
// contains filtered or unexported fields
}
Group is a set of sub-routes for a specified route. It can be used for inner routes that share a common middleware or functionality that should be separate from the parent gig instance while still inheriting from it.
func (*Group) Group ¶
func (g *Group) Group(prefix string, middleware ...MiddlewareFunc) *Group
Group creates a new sub-group with prefix and optional sub-group-level middleware.
func (*Group) Handle ¶
func (g *Group) Handle(path string, h HandlerFunc, m ...MiddlewareFunc) *Route
Handle implements `Gig#Handle()` for sub-routes within the Group.
func (*Group) Use ¶
func (g *Group) Use(middleware ...MiddlewareFunc)
Use implements `Gig#Use()` for sub-routes within the Group.
type HandlerFunc ¶
HandlerFunc defines a function to serve requests.
type LoggerConfig ¶
type LoggerConfig struct { // Skipper defines a function to skip middleware. Skipper Skipper // Tags to construct the logger format. // // - time_unix // - time_unix_nano // - time_rfc3339 // - time_rfc3339_nano // - time_custom // - remote_ip // - uri // - host // - path // - status // - error // - latency (In nanoseconds) // - latency_human (Human readable) // - bytes_in (Bytes received) // - bytes_out (Bytes sent) // - meta // - query // // Example "${remote_ip} ${status}" // // Optional. Default value DefaultLoggerConfig.Format. Format string // Optional. Default value DefaultLoggerConfig.CustomTimeFormat. CustomTimeFormat string // contains filtered or unexported fields }
LoggerConfig defines the config for Logger middleware.
type MiddlewareFunc ¶
type MiddlewareFunc func(HandlerFunc) HandlerFunc
MiddlewareFunc defines a function to process middleware.
func CertAuth ¶
func CertAuth(fn CertAuthValidator) MiddlewareFunc
CertAuth returns an CertAuth middleware.
For valid credentials it calls the next handler.
func CertAuthWithConfig ¶
func CertAuthWithConfig(config CertAuthConfig) MiddlewareFunc
CertAuthWithConfig returns an CertAuth middleware with config. See `CertAuth()`.
func LoggerWithConfig ¶
func LoggerWithConfig(config LoggerConfig) MiddlewareFunc
LoggerWithConfig returns a Logger middleware with config. See: `Logger()`.
func PassAuth ¶
func PassAuth(check PassAuthCertCheck) MiddlewareFunc
PassAuth is a middleware that implements username/password authentication by first requiring a certificate, checking username/password using PassAuthValidator, and then pinning certificate to it.
For valid credentials it calls the next handler.
func Recover ¶
func Recover() MiddlewareFunc
Recover returns a middleware which recovers from panics anywhere in the chain and handles the control to the centralized GeminiErrorHandler.
func RecoverWithConfig ¶
func RecoverWithConfig(config RecoverConfig) MiddlewareFunc
RecoverWithConfig returns a Recover middleware with config. See: `Recover()`.
type PassAuthCertCheck ¶
PassAuthCertCheck defines a function to validate certificate fingerprint. Must return path on unsuccessful login.
type PassAuthLogin ¶
PassAuthLogin defines a function to login user. It may pin certificate to user if login is successful. Must return path to redirect to after login.
type RecoverConfig ¶
type RecoverConfig struct { // Skipper defines a function to skip middleware. Skipper Skipper // Size of the stack to be printed. // Optional. Default value 4KB. StackSize int // DisableStackAll disables formatting stack traces of all other goroutines // into buffer after the trace for the current goroutine. // Optional. Default value false. DisableStackAll bool // DisablePrintStack disables printing stack trace. // Optional. Default value as false. DisablePrintStack bool }
RecoverConfig defines the config for Recover middleware.
type Response ¶
type Response struct { Writer io.Writer Status Status Meta string Size int64 Committed bool // contains filtered or unexported fields }
Response wraps net.Conn, to be used by a context to construct a response.
func NewResponse ¶
NewResponse creates a new instance of Response. Typically used for tests.
func (*Response) WriteHeader ¶
WriteHeader sends a Gemini response header with status code. If WriteHeader is not called explicitly, the first call to Write will trigger an implicit WriteHeader(StatusSuccess, "text/gemini"). Thus explicit calls to WriteHeader are mainly used to send error codes.
type Skipper ¶
Skipper defines a function to skip middleware. Returning true skips processing the middleware.
type Status ¶
type Status int
Status is a Gemini status code type.
const ( StatusInput Status = 10 StatusSensitiveInput Status = 11 StatusSuccess Status = 20 StatusRedirectTemporary Status = 30 StatusRedirectPermanent Status = 31 StatusTemporaryFailure Status = 40 StatusCGIError Status = 42 StatusProxyError Status = 43 StatusSlowDown Status = 44 StatusPermanentFailure Status = 50 StatusNotFound Status = 51 StatusGone Status = 52 StatusProxyRequestRefused Status = 53 StatusBadRequest Status = 59 StatusClientCertificateRequired Status = 60 StatusCertificateNotAuthorised Status = 61 StatusCertificateNotValid Status = 62 )
Gemini status codes as documented by specification. See: https://gemini.circumlunar.space/docs/spec-spec.txt