Documentation
¶
Overview ¶
Package gemini implements a Gemini server and exposes an interface that should be familiar to the users of the `net/http` package.
Example (ReadWriteTimeouts) ¶
package main
import (
"crypto/tls"
"fmt"
"net"
"os"
"time"
"github.com/francescomari/gemini"
)
func main() {
cert, err := tls.LoadX509KeyPair(os.Getenv("TLS_CERT"), os.Getenv("TLS_KEY"))
if err != nil {
panic(fmt.Sprintf("load X.509 key pair: %v", err))
}
listener, err := net.Listen("tcp", ":1965")
if err != nil {
panic(fmt.Sprintf("listen: %v", err))
}
handler := gemini.HandlerFunc(func(r *gemini.Request, w gemini.ResponseWriter) {
fmt.Fprint(w, "=> https://github.com/francescomari/gemini Yet another Gemini server\r\n")
})
// Configure separate timeouts for read and write operations.
server := gemini.Server{
Cert: cert,
Handler: handler,
ReadTimeout: 2 * time.Second,
WriteTimeout: 3 * time.Second,
}
if err := server.Serve(listener); err != nil {
panic(fmt.Sprintf("serve: %v", err))
}
}
Output:
Example (Run) ¶
package main
import (
"crypto/tls"
"fmt"
"net"
"os"
"github.com/francescomari/gemini"
)
func main() {
cert, err := tls.LoadX509KeyPair(os.Getenv("TLS_CERT"), os.Getenv("TLS_KEY"))
if err != nil {
panic(fmt.Sprintf("load X.509 key pair: %v", err))
}
listener, err := net.Listen("tcp", ":1965")
if err != nil {
panic(fmt.Sprintf("listen: %v", err))
}
handler := gemini.HandlerFunc(func(r *gemini.Request, w gemini.ResponseWriter) {
fmt.Fprint(w, "=> https://github.com/francescomari/gemini Yet another Gemini server\r\n")
})
server := gemini.Server{
Cert: cert,
Handler: handler,
}
if err := server.Serve(listener); err != nil {
panic(fmt.Sprintf("serve: %v", err))
}
}
Output:
Example (Timeout) ¶
package main
import (
"crypto/tls"
"fmt"
"net"
"os"
"time"
"github.com/francescomari/gemini"
)
func main() {
cert, err := tls.LoadX509KeyPair(os.Getenv("TLS_CERT"), os.Getenv("TLS_KEY"))
if err != nil {
panic(fmt.Sprintf("load X.509 key pair: %v", err))
}
listener, err := net.Listen("tcp", ":1965")
if err != nil {
panic(fmt.Sprintf("listen: %v", err))
}
handler := gemini.HandlerFunc(func(r *gemini.Request, w gemini.ResponseWriter) {
fmt.Fprint(w, "=> https://github.com/francescomari/gemini Yet another Gemini server\r\n")
})
// Configure a single timeout for both read and write operations.
server := gemini.Server{
Cert: cert,
Handler: handler,
Timeout: time.Second,
}
if err := server.Serve(listener); err != nil {
panic(fmt.Sprintf("serve: %v", err))
}
}
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Handler ¶
type Handler interface {
Handle(r *Request, w ResponseWriter)
}
Handler handles client requests and produces responses.
If a handler doesn't write a response header or response data, the server automatically sends a StatusSuccess response with media type "text/gemini" and no content.
While a handler should deal with its own panics, the server intercepts and swallows a panic thrown by a handler. Unless a response has already been sent to the client, a panic results in a StatusCGIError response.
type HandlerFunc ¶
type HandlerFunc func(r *Request, w ResponseWriter)
HandlerFunc is an implementation of Handler using a plain function.
func (HandlerFunc) Handle ¶
func (f HandlerFunc) Handle(r *Request, w ResponseWriter)
Handle implements Handler.
type Request ¶
type Request struct {
// The URL scheme. It's always "gemini".
Scheme string
// The URL host. It's never empty.
Host string
// The URL port. It can be zero if the request didn't specify a port, in
// which case the client expects the default port for the gemini scheme
// to be used.
Port int
// The URL path. It's never empty. If the client didn't include a path in
// the request, or if the path normalizes to nothing, Path is /.
//
// Paths are normalized by removing single-dot components and resolving
// double-dot components.
//
// A trailing / in the original URL path is preserved.
Path string
// The query component of the URL. It can be the empty string if not
// provided.
Query string
// The client certificate. It can be nil if the client did not provide a
// certificate.
//
// If the client provides a certificate, the server always validates the
// not-before, not-after, and signature of the provided certificate.
// Self-signed certificates are expected and encouraged.
Cert *x509.Certificate
// The client's remote address. Mostly for logging purposes.
RemoteAddr string
}
Request contains the URL requested by the client.
type ResponseWriter ¶
type ResponseWriter interface {
io.Writer
// WriteHeader writes the response header.
//
// If response data is written without calling this method, WriteHeader is
// automatically called with StatusSuccess and a media type
// of "text/gemini".
//
// Calling this method multiple times, or calling this method after
// response data is written, has no effect.
//
// WriteHeader panics if trying to generate a header that does not conform
// to the specification. For example, StatusSuccess always requires a
// media type, and StatusInputExpected a prompt.
WriteHeader(statusCode StatusCode, meta string)
}
ResponseWriter generates the server response. A ResponseWriter can't be safely used by multiple goroutines.
type Server ¶
type Server struct {
// The server certificate. Self-signed certificates are supported and
// encouraged. This field is mandatory.
Cert tls.Certificate
// The handler for requests sent to this server. If not provided, the
// server responds with StatusNotFound to every request that would
// otherwise be processed by the handler.
Handler Handler
// Timeout sets the timeout for each I/O operation performed while serving a
// connection, be it a read or a write. If not specified, no timeout is set.
Timeout time.Duration
// ReadTimeout sets the timeout for each read operation performed while
// serving a connection. If not specified, no read timeout is set. If both
// Timeout and ReadTimeout are specified, ReadTimeout overrides Timeout.
ReadTimeout time.Duration
// WriteTimeout sets the timeout for each write operation performed while
// serving a connection. If not specified, no write timeout is set. If both
// Timeout and WriteTimeout are specified, WriteTimeout overrides Timeout.
WriteTimeout time.Duration
}
Server is a Gemini server. A Server can be safely used by multiple goroutines.
type StatusCode ¶
type StatusCode int
StatusCode is one of the available status codes.
const ( StatusInputExpected StatusCode = 10 StatusSensitiveInput StatusCode = 11 StatusSuccess StatusCode = 20 StatusTemporaryRedirection StatusCode = 30 StatusPermanentRedirection StatusCode = 31 StatusTemporaryFailure StatusCode = 40 StatusCGIError StatusCode = 42 StatusProxyError StatusCode = 43 StatusSlowDown StatusCode = 44 StatusPermanentFailure StatusCode = 50 StatusNotFound StatusCode = 51 StatusGone StatusCode = 52 StatusProxyRequestRefused StatusCode = 53 StatusBadRequest StatusCode = 59 StatusCertificateRequired StatusCode = 60 StatusCertificateNotAuthorized StatusCode = 61 StatusCertificateNotValid StatusCode = 62 )