ong

module
v0.0.97 Latest Latest
Warning

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

Go to latest
Published: Jun 6, 2024 License: MIT

README

ong

Go Reference
ci
codecov

Ong is a small http toolkit.

It's name is derived from Tanzanian artiste, Remmy Ongala.

Inspired by; How I Write HTTP Web Services after Eight Years[1][2] by Mat Ryer.

You really should not use this library/toolkit.
Instead, use the Go net/http package; and if you need some extra bits, may I suggest the awesome github.com/gorilla web toolkit.

This library is made just for me, it might be unsafe & it does not generally accept code contributions.

package main

import (
	"context"
	"fmt"
	"net/http"
	"os"

	"github.com/komuw/ong/config"
	"github.com/komuw/ong/log"
	"github.com/komuw/ong/middleware"
	"github.com/komuw/ong/mux"
	"github.com/komuw/ong/server"
)

func main() {
	l := log.New(context.Background(), os.Stdout, 1000)
	secretKey := "super-h@rd-Pas1word"
	opts := config.WithOpts(
		"localhost",
		65081,
		secretKey,
		config.DirectIpStrategy,
		l,
	) // dev options.
	// alternatively for production:
	//   opts := config.LetsEncryptOpts(...)

	mx := mux.New(
		opts,
		nil,
		mux.NewRoute(
			"hello/",
			mux.MethodGet,
			hello("hello world"),
		),
		mux.NewRoute(
			"check/:age/",
			mux.MethodAll,
			check(),
		),
	)

	err := server.Run(mx, opts)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func hello(msg string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		cspNonce := middleware.GetCspNonce(r.Context())
		csrfToken := middleware.GetCsrfToken(r.Context())
		fmt.Printf("hello called cspNonce: %s, csrfToken: %s", cspNonce, csrfToken)

		// use msg, which is a dependency specific to this handler
		fmt.Fprint(w, msg)
	}
}

func check() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		age := mux.Param(r.Context(), "age")
		_, _ = fmt.Fprintf(w, "Age is %s", age)
	}
}

go run -race ./...

A more complete example can be found in the example/ folder.

References:
  1. https://www.youtube.com/watch?v=rWBSMsLG8po
  2. https://pace.dev/blog/2018/05/09/how-I-write-http-services-after-eight-years.html
Features:

The simplest production ready program using ong http toolkit would be something like;

package main

import (
	"context"
	"fmt"
	"net/http"
	"os"

	"github.com/komuw/ong/config"
	"github.com/komuw/ong/log"
	"github.com/komuw/ong/mux"
	"github.com/komuw/ong/server"
)

func main() {
	logger := log.New(context.Background(), os.Stdout, 1000)
	domain := "example.com"
	secretKey := "super-h@rd-Pas1word"
	email := "hey@example.com"
	opts := config.LetsEncryptOpts(
		domain, secretKey, config.DirectIpStrategy, logger, email, []string{domain})

	mx := mux.New(opts, nil, mux.NewRoute("hello/", mux.MethodGet, hello()))
	_ = server.Run(mx, opts)
}

func hello() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "hello")
	}
}

If you do that, these are the features you would enjoy automatically without doing any extra configuration;

  1. Http server. You get a server that automatically;
    • sets GOMEMLIMIT & GOMAXPROCS to match linux container memory & cpu quotas.
    • fetches and auto renews TLS certificates from letsencrypt or any other compatible ACME authority.
    • serves pprof endpoints that are secured by basic authentication. The secretKey is used as the username and password.
    • handles automatic http->https redirection.
    • implements robust http timeouts to prevent attacks.
    • limits size of request bodies to prevent attacks.
    • shutsdown cleanly after receiving termination signals. If running in kubernetes, the shutdown is well co-ordinated to prevent errors.
    • Reuses port(SO_REUSEPORT) and reuses address(SO_REUSEADDR). This makes it possible to do zero downtime deploys.
  2. Automatic ratelimiting.
  3. Automatic loadshedding.
  4. Automatic proper handling of CORS
  5. Automatic CSRF protection.
  6. Automatic logging of erroring requests with correlation IDs included. The logging is lightweight so it only logs when an error occurs. Importantly, when the error occurs, it also includes all the log statements that occured before(including the non-error ones). This is possible because ong/log uses a circular buffer
  7. Automatic recovery of panics in http handlers and logging of the same including stack traces.
  8. Automatic addition of the real client IP to request context.
  9. Protection against inadvertent form re-submission.
  10. Automatically sets appropriate secure headers(X-Content-Type-Options, Content-Security-Policy, X-Frame-Options, Cross-Origin-Resource-Policy, Cross-Origin-Opener-Policy, Referrer-Policy, Strict-Transport-Security)
  11. Automatic addition of TLS fingerprint to request context.
  12. Set's up secure authenticated encrypted http sessions.
  13. Uses a http request multiplexer that;
    • panics(during application startup) if there are any conflicting routes.
    • has a debugging tool where if given a url, it will return the corresponding http handler for that url.
    • can capture path parameters

Those are the automatic ones. There are a few additional features that you can opt into;

  1. A http client that properly handles server-side request forgery attacks.
  2. A cookie package that enables you to work with both plain text cookies and also authenticated encrypted cookies.
  3. A cryptography package that simplifies using authenticated encryption and also hashing.
  4. An errors package that includes error wrapping and stack trace support.
  5. An id package that can generate unique random human friendly identifiers, as well as uuid4(does not leak its creation time) and uuid8(has good database locality).
  6. A log package that implements slog.Logger and is backed by an slog.Handler that stores log messages into a circular buffer.
  7. A sess package that makes it easy to work with http sessions that are backed by tamper-proof & encrypted cookies.
  8. A sync package that makes it easier to work with groups of goroutines working on subtasks of a common task.

Directories

Path Synopsis
Package automax automatically sets GOMEMLIMIT & GOMAXPROCS to match the linux container memory & cpu quotas, if any.
Package automax automatically sets GOMEMLIMIT & GOMAXPROCS to match the linux container memory & cpu quotas, if any.
Package client provides a HTTP client implementation.
Package client provides a HTTP client implementation.
Package config provides various parameters(configuration optionals) that can be used to configure ong.
Package config provides various parameters(configuration optionals) that can be used to configure ong.
Package cookie provides utilities for using HTTP cookies.
Package cookie provides utilities for using HTTP cookies.
Package cry provides utilities for cryptography.
Package cry provides utilities for cryptography.
Package errors implements functions to manipulate errors.
Package errors implements functions to manipulate errors.
Package id generates unique random identifiers.
Package id generates unique random identifiers.
internal
acme
Package acme provides automatic access to certificates from ACME-based certificate authorities(like Let's Encrypt).
Package acme provides automatic access to certificates from ACME-based certificate authorities(like Let's Encrypt).
clientip
Package clientip provides(in a best effort manner) a client's IP address.
Package clientip provides(in a best effort manner) a client's IP address.
finger
Package finger provides(in a best effort manner) a client's TLS fingerprint.
Package finger provides(in a best effort manner) a client's TLS fingerprint.
key
Package key implements some common secure functionality.
Package key implements some common secure functionality.
mx
Package mx implements a HTTP request multiplexer.
Package mx implements a HTTP request multiplexer.
octx
Package octx houses context keys used by multiple ong packages.
Package octx houses context keys used by multiple ong packages.
tst
Package tst implements some common test functionality needed across ong.
Package tst implements some common test functionality needed across ong.
Package log implements a simple logging handler.
Package log implements a simple logging handler.
Package middleware provides helpful functions that implement some common functionalities in http servers.
Package middleware provides helpful functions that implement some common functionalities in http servers.
Package mux implements a HTTP request multiplexer.
Package mux implements a HTTP request multiplexer.
Package server provides HTTP server implementation.
Package server provides HTTP server implementation.
Package sess provides an implementation of http sessions that is backed by tamper-proof & encrypted cookies.
Package sess provides an implementation of http sessions that is backed by tamper-proof & encrypted cookies.
Package sync provides synchronization, error propagation, and Context cancelation for groups of goroutines working on subtasks of a common task.
Package sync provides synchronization, error propagation, and Context cancelation for groups of goroutines working on subtasks of a common task.

Jump to

Keyboard shortcuts

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