-- Leo's gemini proxy

-- Connecting to godocs.io:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

package gig - github.com/pitr/gig - godocs.io


import "github.com/pitr/gig"

Package gig implements high performance, minimalist Go framework for Gemini protocol.


Example:


package main

import (
  "github.com/pitr/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")
}

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")
	ErrServerUnavailable         = NewError(StatusServerUnavailable, "Server Unavailable")
	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

func DefaultGeminiErrorHandler(err error, c Context)

DefaultGeminiErrorHandler is the default HTTP error handler. It sends a JSON response with status code.


func DefaultSkipper

func DefaultSkipper(Context) bool

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. 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 FakeAddr

type FakeAddr struct{}

FakeAddr ia a fake net.Addr implementation.


func (*FakeAddr) Network

func (a *FakeAddr) Network() string

Network returns dummy data.


func (*FakeAddr) String

func (a *FakeAddr) String() string

String returns dummy data.


type FakeConn

type FakeConn struct {
	FailAfter int
	Written   string
}

FakeConn ia a fake net.Conn that can record what is written and can fail after FailAfter bytes were written.


func (*FakeConn) Close

func (c *FakeConn) Close() error

Close always returns nil.


func (*FakeConn) LocalAddr

func (c *FakeConn) LocalAddr() net.Addr

LocalAddr returns fake address.


func (*FakeConn) Read

func (c *FakeConn) Read(b []byte) (n int, err error)

Read always returns success.


func (*FakeConn) RemoteAddr

func (c *FakeConn) RemoteAddr() net.Addr

RemoteAddr returns fake address.


func (*FakeConn) SetDeadline

func (c *FakeConn) SetDeadline(t time.Time) error

SetDeadline always returns nil.


func (*FakeConn) SetReadDeadline

func (c *FakeConn) SetReadDeadline(t time.Time) error

SetReadDeadline always returns nil.


func (*FakeConn) SetWriteDeadline

func (c *FakeConn) SetWriteDeadline(t time.Time) error

SetWriteDeadline always returns nil.


func (*FakeConn) Write

func (c *FakeConn) Write(b []byte) (n int, err error)

Write records bytes written and fails after FailAfter bytes.


type GeminiError

type GeminiError struct {
	Code    Status
	Message string
}

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

type GeminiErrorHandler func(error, Context)

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 New

func New() *Gig

New creates an instance of Gig.


func (*Gig) Close

func (g *Gig) Close() error

Close immediately stops the server. It internally calls `net.Listener#Close()`.


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

func (g *Gig) NewFakeContext(uri string, tlsState *tls.ConnectionState) (Context, *FakeConn)

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) Reverse

func (g *Gig) Reverse(name string, params ...interface{}) string

Reverse generates an URL from route name and provided parameters.


func (*Gig) Routes

func (g *Gig) Routes() []*Route

Routes returns the registered routes.


func (*Gig) Run

func (g *Gig) Run(args ...interface{}) (err error)

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) ServeGemini

func (g *Gig) ServeGemini(c Context)

ServeGemini serves Gemini request.


func (*Gig) Static

func (g *Gig) Static(prefix, root string) *Route

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) File

func (g *Group) File(path, file string)

File implements `Gig#File()` for sub-routes within the Group.


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) Static

func (g *Group) Static(prefix, root string)

Static implements `Gig#Static()` 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

type HandlerFunc func(Context) error

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 Logger

func Logger() MiddlewareFunc

Logger returns a middleware that logs Gemini requests.


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

type PassAuthCertCheck func(string, Context) (string, error)

PassAuthCertCheck defines a function to validate certificate fingerprint. Must return path on unsuccessful login.


type PassAuthLogin

type PassAuthLogin func(username, password, sig string, c Context) (string, error)

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 Renderer

type Renderer interface {
	Render(io.Writer, string, interface{}, Context) error
}

Renderer is the interface that wraps the Render function.


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

func NewResponse(w io.Writer) (r *Response)

NewResponse creates a new instance of Response. Typically used for tests.


func (*Response) Write

func (r *Response) Write(b []byte) (int, error)

Write writes the data to the connection as part of a reply.


func (*Response) WriteHeader

func (r *Response) WriteHeader(code Status, meta string) error

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 Route

type Route struct {
	Path string
	Name string
}

Route contains a handler and information for matching against requests.


type Skipper

type Skipper func(Context) bool

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
	StatusServerUnavailable         Status = 41
	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


Directories


examples


Details

Version: v0.9.8 (latest)

Published: Feb 13, 2021

Platform: linux/amd64

Imports: 23 packages

Last checked: 4 days ago

Refresh now


Back to home

Search

-- Response ended

-- Page fetched on Mon May 20 14:36:35 2024