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.
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;
secretKey
is used as the username and password.SO_REUSEPORT
) and reuses address(SO_REUSEADDR
). This makes it possible to do zero downtime deploys. X-Content-Type-Options
, Content-Security-Policy
, X-Frame-Options
, Cross-Origin-Resource-Policy
, Cross-Origin-Opener-Policy
, Referrer-Policy
, Strict-Transport-Security
)Those are the automatic ones. There are a few additional features that you can opt into;