Documentation ¶
Index ¶
- Constants
- Variables
- func AuthoriserAllowAll(id, key string) bool
- func BadRequest(w ResponseWriter, r *Request)
- func IsErrorCode(code Code) bool
- func ListenAndServe(ctx context.Context, addr string, domains ...*DomainHandler) (err error)
- func NotFound(w ResponseWriter, r *Request)
- type Certificate
- type Client
- func (client *Client) AddClientCertificate(prefix string, cert tls.Certificate)
- func (client *Client) AddServerCertificate(host, certificateHash string)
- func (client *Client) GetCertificate(u *url.URL) (cert tls.Certificate, ok bool)
- func (client *Client) Request(ctx context.Context, u string) (resp *Response, certificates []string, authenticated, ok bool, err error)
- func (client *Client) RequestConn(ctx context.Context, conn net.Conn, u *url.URL) (resp *Response, err error)
- func (client *Client) RequestNoTLS(ctx context.Context, u *url.URL) (resp *Response, err error)
- func (client *Client) RequestURL(ctx context.Context, u *url.URL) (resp *Response, certificates []string, authenticated, ok bool, err error)
- type Code
- type Dir
- type DomainHandler
- type File
- type FileSystem
- type Handler
- func BadRequestHandler() Handler
- func DirectoryListingHandler(path string, f File) Handler
- func FileContentHandler(name string, f File) Handler
- func FileSystemHandler(fs FileSystem) Handler
- func NotFoundHandler() Handler
- func RedirectPermanentHandler(to string) Handler
- func RedirectTemporaryHandler(to string) Handler
- func RequireCertificateHandler(h Handler, authoriser func(certID, certKey string) bool) Handler
- func StripPrefixHandler(prefix string, h Handler) Handler
- type HandlerFunc
- type Header
- type Request
- type Response
- type ResponseWriter
- type Server
- type Writer
Constants ¶
const ( CodeInput Code = "10" CodeInputSensitive = "11" CodeSuccess = "20" CodeRedirect = "30" CodeRedirectTemporary = CodeRedirect CodeRedirectPermanent = "31" CodeTemporaryFailure = "40" CodeCGIError = "42" CodeProxyError = "43" CodeSlowDown = "44" CodePermanentFailure = "50" CodeNotFound = "51" CodeGone = "52" CodeProxyRequestRefused = "53" CodeBadRequest = "59" CodeClientCertificateRequired = "60" CodeClientCertificateNotAuthorised = "61" CodeClientCertificateNotValid = "62" )
const DefaultMIMEType = "text/gemini; charset=utf-8"
DefaultMIMEType for Gemini responses.
Variables ¶
var ErrCannotWriteBodyWithoutSuccessCode = errors.New("gemini: cannot write body without success code")
var ErrCrLfNotFoundWithinMaxLength = errors.New("gemini: invalid header - CRLF not found within maximum length")
ErrCrLfNotFoundWithinMaxLength is returned if the Gemini server returns an invalid response.
var ErrHeaderAlreadyWritten = errors.New("gemini: header already written")
ErrHeaderAlreadyWritten is returned by SetHeader when the Gemini header has already been written to the response.
var ErrInvalidCode = errors.New("gemini: invalid code")
ErrInvalidCode is returned if the Gemini server returns an invalid code.
var ErrInvalidMeta = errors.New("gemini: invalid meta")
ErrInvalidMeta is returned if the Gemini server returns an invalid meta value.
var ErrInvalidStatus = errors.New("gemini: server status did not match the expected format")
ErrInvalidStatus is returned if the Gemini request did not match the expected format.
var ErrServerClosed = errors.New("gemini: server closed")
ErrServerClosed is returned when a server is attempted to start up when it's already shutting down.
Functions ¶
func AuthoriserAllowAll ¶
AuthoriserAllowAll allows any authenticated user to access the handler.
func BadRequest ¶
func BadRequest(w ResponseWriter, r *Request)
BadRequest responds with a 59 status.
func IsErrorCode ¶
IsErrorCode returns true if the code is invalid, or starts with 4, 5 or 6.
func ListenAndServe ¶
func ListenAndServe(ctx context.Context, addr string, domains ...*DomainHandler) (err error)
ListenAndServe starts up a new server to handle multiple domains with a specific certFile, keyFile and handler.
Types ¶
type Certificate ¶
type Certificate struct { // ID is the base64-encoded SHA256 hash of the key. ID string // Key is the user public key in PKIX, ASN.1 DER form. Key string // Error is an error message related to any failures in handling the client certificate. Error string }
Certificate information provided to the server by the client.
type Client ¶
type Client struct { // Insecure mode does not check the hash of remote certificates. Insecure bool WriteTimeout time.Duration ReadTimeout time.Duration // contains filtered or unexported fields }
Client for Gemini requests.
func (*Client) AddClientCertificate ¶
func (client *Client) AddClientCertificate(prefix string, cert tls.Certificate)
AddClientCertificate adds a certificate to use when the URL prefix is encountered.
func (*Client) AddServerCertificate ¶
AddServerCertificate allows the client to connect to a domain based on its hash.
func (*Client) GetCertificate ¶
GetCertificate returns a certificate to use for the given URL, if one exists.
func (*Client) Request ¶
func (client *Client) Request(ctx context.Context, u string) (resp *Response, certificates []string, authenticated, ok bool, err error)
Request a response from a given Gemini URL.
func (*Client) RequestConn ¶
func (client *Client) RequestConn(ctx context.Context, conn net.Conn, u *url.URL) (resp *Response, err error)
RequestConn uses a given connection to make the request. This allows for insecure requests to be made. net.Dial("tcp", "localhost:1965")
func (*Client) RequestNoTLS ¶
RequestNoTLS carries out a request without TLS enabled.
func (*Client) RequestURL ¶
func (client *Client) RequestURL(ctx context.Context, u *url.URL) (resp *Response, certificates []string, authenticated, ok bool, err error)
RequestURL requests a response from a parsed URL. ok returns true if a matching server certificate is found (i.e. the server is OK).
type Code ¶
type Code string
Code returned as part of the Gemini response (see https://gemini.circumlunar.space/docs/specification.html).
type DomainHandler ¶
type DomainHandler struct { ServerName string KeyPair tls.Certificate Handler Handler }
DomainHandler handles incoming requests for the ServerName using the provided KeyPair certificate and Handler to process the request.
func NewDomainHandler ¶
func NewDomainHandler(serverName string, cert tls.Certificate, handler Handler) *DomainHandler
NewDomainHandler creates a new handler to listen for Gemini requests using TLS. The cert can be generated by the github.com/a-h/gemini/cert.Generate package, or can generated using openssl: keyFile:
openssl ecparam -genkey -name secp384r1 -out server.key
certFile:
openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
func NewDomainHandlerFromFiles ¶
func NewDomainHandlerFromFiles(serverName, certFile, keyFile string, handler Handler) (*DomainHandler, error)
NewDomainHandlerFromFiles creates a new handler to listen for Gemini requests using TLS. certFile / keyFile are links to the X509 keypair. This can be generated using openssl: keyFile:
openssl ecparam -genkey -name secp384r1 -out server.key
certFile:
openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
type File ¶
type File interface { io.Closer io.Reader Readdir(count int) ([]os.FileInfo, error) Stat() (os.FileInfo, error) }
A File is returned by a FileSystem's Open method and can be served by the FileServer implementation.
The methods should behave the same as those on an *os.File.
type FileSystem ¶
A FileSystem implements access to a collection of named files. The elements in a file path are separated by slash ('/', U+002F) characters, regardless of host operating system convention.
type Handler ¶
type Handler interface {
ServeGemini(w ResponseWriter, r *Request)
}
Handler of Gemini content.
func BadRequestHandler ¶
func BadRequestHandler() Handler
BadRequestHandler creates a handler that returns a bad request code (59).
func DirectoryListingHandler ¶
func FileContentHandler ¶
func FileSystemHandler ¶
func FileSystemHandler(fs FileSystem) Handler
func NotFoundHandler ¶
func NotFoundHandler() Handler
NotFoundHandler creates a handler that returns not found.
func RedirectPermanentHandler ¶
RedirectPermanentHandler returns a handler which returns a permanent redirect.
func RedirectTemporaryHandler ¶
RedirectTemporaryHandler returns a temporary redirection.
func RequireCertificateHandler ¶
RequireCertificateHandler returns a handler that enforces authentication on h. authoriser can be set to limit which users can access h. If authoriser is nil, authoriser is set to AuthoriserAllowAll which allows any authenticated user to access the handler.
func StripPrefixHandler ¶
StripPrefixHandler strips a prefix from the incoming URL and passes the strippe URL to h.
type HandlerFunc ¶
type HandlerFunc func(ResponseWriter, *Request)
HandlerFunc handles a Gemini request and returns a response.
func (HandlerFunc) ServeGemini ¶
func (f HandlerFunc) ServeGemini(w ResponseWriter, r *Request)
ServeGemini implements the Handler interface.
type Request ¶
type Request struct { Context context.Context URL *url.URL Certificate Certificate }
Request from the client. A Gemini request contains only the URL, the Certificates field is populated by the TLS certificates presented by the client.
type Response ¶
type Response struct { Header *Header Body io.ReadCloser }
Response from the Gemini server.
func NewResponse ¶
func NewResponse(r io.ReadCloser) (resp *Response, err error)
NewResponse parses the server response.
type ResponseWriter ¶
ResponseWriter used by handlers to send a response to the client.
type Server ¶
type Server struct { Context context.Context Addr string Insecure bool DomainToHandler map[string]*DomainHandler ReadTimeout time.Duration WriteTimeout time.Duration HandlerTimeout time.Duration }
Server hosts Gemini content.
func NewServer ¶
NewServer creates a new Gemini server. addr is in the form "<optional_ip>:<port>", e.g. ":1965". If left empty, it will default to ":1965". domainToHandler is a map of the server name (domain) to the certificate key pair and the Gemini handler used to serve content.
func (*Server) ListenAndServe ¶
Set the server listening on the specified port.