gemini

package module
v0.0.0-...-3afd89a Latest Latest
Warning

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

Go to latest
Published: Jun 25, 2020 License: MIT Imports: 18 Imported by: 0

README

Gemini

Protocol implementation of the gemini protocol as described here:

https://gemini.circumlunar.space/

Goal

The goal is to mimic the interfaces of go's http package. But since it's such a simple protocol, i highly suggest that you spend a bit of time to study the protocol on your own.

Status

This implementation is still in it's very early stages and should not be used for any production use.

TODO

  • Implement Fileserver ala http.Fileserver
  • Implement ServeMux ala http.ServeMux
  • Harden server to withstand malicious clients.
  • Harden client to make it more robust in case of failures.
  • Support TOFU
  • Support Client certificates

Documentation

Overview

Most of this file content is copied and adapted from net/http

Index

Constants

View Source
const (
	StatusInput                  int = 10
	StatusSuccess                int = 20
	StatusSuccessEOCS            int = 21 // SUCCESS - END OF CLIENT CERTIFICATE SESSION
	StatusTemporaryRedirect      int = 30
	StatusPermanentRedirect      int = 31
	StatusTemporaryFailure       int = 40
	StatusServerUnavailable      int = 41
	StatusCGIError               int = 42
	StatusProxyError             int = 43
	StatusSlowdown               int = 44
	StatusPermanentFailure       int = 50
	StatusGone                   int = 52
	StatusProxyRequestRefused    int = 53
	StatusBadRequest             int = 59
	StatusClientCertRequired     int = 60
	StatusTransientCertRequested int = 61
	StatusAuthorizedCertRequired int = 62
	StatusCertNotAccepted        int = 63
	StatusFutureCertRejected     int = 64
	StatusExpiredCertRejected    int = 65
)

Variables

This section is empty.

Functions

func DetectContentType

func DetectContentType(data []byte) string

DetectContentType implements the algorithm described at https://mimesniff.spec.whatwg.org/ to determine the Content-Type of the given data. It considers at most the first 512 bytes of data. DetectContentType always returns a valid MIME type: if it cannot determine a more specific one, it returns "application/octet-stream".

func NotFound

func NotFound(w ResponseWriter, r *Request)

NotFound replies to the request with an HTTP 404 not found error.

func Redirect

func Redirect(w ResponseWriter, r *Request, redirectURL string, code int)

func RedirectTemporary

func RedirectTemporary(wr ResponseWriter, url string)

func SplitFunc

func SplitFunc(data []byte, atEOF bool) (int, []byte, error)

Types

type Client

type Client struct {
}

func NewClient

func NewClient() *Client

func (*Client) Fetch

func (cli *Client) Fetch(path string) (*Response, error)

type Dir

type Dir string

A Dir implements FileSystem using the native file system restricted to a specific directory tree.

While the FileSystem.Open method takes '/'-separated paths, a Dir's string value is a filename on the native file system, not a URL, so it is separated by filepath.Separator, which isn't necessarily '/'.

Note that Dir will allow access to files and directories starting with a period, which could expose sensitive directories like a .git directory or sensitive files like .htpasswd. To exclude files with a leading period, remove the files/directories from the server or create a custom FileSystem implementation.

An empty Dir is treated as ".".

func (Dir) Open

func (d Dir) Open(name string) (File, error)

Open implements FileSystem using os.Open, opening files for reading rooted and relative to the directory d.

type File

type File interface {
	io.Closer
	io.Reader
	io.Seeker
	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

type FileSystem interface {
	Open(name string) (File, error)
}

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

func FileServer

func FileServer(root FileSystem) Handler

func NotFoundHandler

func NotFoundHandler() Handler

func RedirectHandler

func RedirectHandler(redirectURL string, code int) Handler

type HandlerFunc

type HandlerFunc func(ResponseWriter, *Request)

The HandlerFunc type is an adapter to allow the use of ordinary functions as HTTP handlers. If f is a function with the appropriate signature, HandlerFunc(f) is a Handler that calls f.

func (HandlerFunc) ServeGemini

func (f HandlerFunc) ServeGemini(w ResponseWriter, r *Request)

ServeHTTP calls f(w, r).

type Request

type Request struct {
	URL        *url.URL
	Host       string // TODO: Set it somewhere based on tls cert requests?
	StatusCode int
	Meta       string
}

type Response

type Response struct {
	Meta       string
	Body       io.ReadCloser
	StatusCode int
	Status     string
}

type ResponseWriter

type ResponseWriter interface {
	Write([]byte) (int, error)
	WriteHeader(statusCode int, meta string)
}

type ServeMux

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

ServeMux is an HTTP request multiplexer. It matches the URL of each incoming request against a list of registered patterns and calls the handler for the pattern that most closely matches the URL.

Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash). Longer patterns take precedence over shorter ones, so that if there are handlers registered for both "/images/" and "/images/thumbnails/", the latter handler will be called for paths beginning "/images/thumbnails/" and the former will receive requests for any other paths in the "/images/" subtree.

Note that since a pattern ending in a slash names a rooted subtree, the pattern "/" matches all paths not matched by other registered patterns, not just the URL with Path == "/".

If a subtree has been registered and a request is received naming the subtree root without its trailing slash, ServeMux redirects that request to the subtree root (adding the trailing slash). This behavior can be overridden with a separate registration for the path without the trailing slash. For example, registering "/images/" causes ServeMux to redirect a request for "/images" to "/images/", unless "/images" has been registered separately.

Patterns may optionally begin with a host name, restricting matches to URLs on that host only. Host-specific patterns take precedence over general patterns, so that a handler might register for the two patterns "/codesearch" and "codesearch.google.com/" without also taking over requests for "http://www.google.com/".

ServeMux also takes care of sanitizing the URL request path and the Host header, stripping the port number and redirecting any request containing . or .. elements or repeated slashes to an equivalent, cleaner URL.

func NewServeMux

func NewServeMux() *ServeMux

NewServeMux allocates and returns a new ServeMux.

func (*ServeMux) Handle

func (mux *ServeMux) Handle(pattern string, handler Handler)

Handle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics.

func (*ServeMux) HandleFunc

func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))

HandleFunc registers the handler function for the given pattern.

func (*ServeMux) Handler

func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string)

Handler returns the handler to use for the given request, consulting r.Method, r.Host, and r.URL.Path. It always returns a non-nil handler. If the path is not in its canonical form, the handler will be an internally-generated handler that redirects to the canonical path. If the host contains a port, it is ignored when matching handlers.

The path and host are used unchanged for CONNECT requests.

Handler also returns the registered pattern that matches the request or, in the case of internally-generated redirects, the pattern that will match after following the redirect.

If there is no registered handler that applies to the request, Handler returns a “page not found” handler and an empty pattern.

func (*ServeMux) ServeGemini

func (mux *ServeMux) ServeGemini(w ResponseWriter, r *Request)

type Server

type Server struct {
	Addr string

	Handler Handler
}

func (*Server) ListenAndServe

func (srv *Server) ListenAndServe(cert, key []byte) error

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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