mirror of
https://github.com/mjl-/mox.git
synced 2024-12-26 16:33:47 +03:00
6706c5c84a
- serve static files, serving index.html or optionally listings for directories - redirects - reverse-proxy, forwarding requests to a backend these are configurable through the config file. a domain and path regexp have to be configured. path prefixes can be stripped. configured domains are added to the autotls allowlist, so acme automatically fetches certificates for them. all webserver requests now have (access) logging, metrics, rate limiting. on http errors, the error message prints an encrypted cid for relating with log files. this also adds a new mechanism for example config files.
97 lines
3.5 KiB
Go
97 lines
3.5 KiB
Go
package autotls
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"golang.org/x/crypto/acme/autocert"
|
|
|
|
"github.com/mjl-/mox/dns"
|
|
)
|
|
|
|
func TestAutotls(t *testing.T) {
|
|
os.RemoveAll("../testdata/autotls")
|
|
os.MkdirAll("../testdata/autotls", 0770)
|
|
|
|
shutdown := make(chan struct{})
|
|
m, err := Load("test", "../testdata/autotls", "mox@localhost", "https://localhost/", shutdown)
|
|
if err != nil {
|
|
t.Fatalf("load manager: %v", err)
|
|
}
|
|
l := m.Hostnames()
|
|
if len(l) != 0 {
|
|
t.Fatalf("hostnames, got %v, expected empty list", l)
|
|
}
|
|
if err := m.HostPolicy(context.Background(), "mox.example"); err == nil || !errors.Is(err, errHostNotAllowed) {
|
|
t.Fatalf("hostpolicy, got err %v, expected errHostNotAllowed", err)
|
|
}
|
|
m.SetAllowedHostnames(map[dns.Domain]struct{}{{ASCII: "mox.example"}: {}})
|
|
l = m.Hostnames()
|
|
if !reflect.DeepEqual(l, []dns.Domain{{ASCII: "mox.example"}}) {
|
|
t.Fatalf("hostnames, got %v, expected single mox.example", l)
|
|
}
|
|
if err := m.HostPolicy(context.Background(), "mox.example"); err != nil {
|
|
t.Fatalf("hostpolicy, got err %v, expected no error", err)
|
|
}
|
|
if err := m.HostPolicy(context.Background(), "other.mox.example"); err == nil || !errors.Is(err, errHostNotAllowed) {
|
|
t.Fatalf("hostpolicy, got err %v, expected errHostNotAllowed", err)
|
|
}
|
|
|
|
ctx := context.Background()
|
|
cache := m.Manager.Cache
|
|
if _, err := cache.Get(ctx, "mox.example"); err == nil || !errors.Is(err, autocert.ErrCacheMiss) {
|
|
t.Fatalf("cache get for absent entry: got err %v, expected autocert.ErrCacheMiss", err)
|
|
}
|
|
if err := cache.Put(ctx, "mox.example", []byte("test")); err != nil {
|
|
t.Fatalf("cache put for absent entry: got err %v, expected error", err)
|
|
}
|
|
if data, err := cache.Get(ctx, "mox.example"); err != nil || string(data) != "test" {
|
|
t.Fatalf("cache get: got err %v data %q, expected nil, 'test'", err, data)
|
|
}
|
|
if err := cache.Put(ctx, "mox.example", []byte("test2")); err != nil {
|
|
t.Fatalf("cache put for absent entry: got err %v, expected error", err)
|
|
}
|
|
if data, err := cache.Get(ctx, "mox.example"); err != nil || string(data) != "test2" {
|
|
t.Fatalf("cache get: got err %v data %q, expected nil, 'test2'", err, data)
|
|
}
|
|
if err := cache.Delete(ctx, "mox.example"); err != nil {
|
|
t.Fatalf("cache delete: got err %v, expected no error", err)
|
|
}
|
|
if _, err := cache.Get(ctx, "mox.example"); err == nil || !errors.Is(err, autocert.ErrCacheMiss) {
|
|
t.Fatalf("cache get for absent entry: got err %v, expected autocert.ErrCacheMiss", err)
|
|
}
|
|
|
|
close(shutdown)
|
|
if err := m.HostPolicy(context.Background(), "mox.example"); err == nil {
|
|
t.Fatalf("hostpolicy, got err %v, expected error due to shutdown", err)
|
|
}
|
|
|
|
key0 := m.Manager.Client.Key
|
|
|
|
m, err = Load("test", "../testdata/autotls", "mox@localhost", "https://localhost/", shutdown)
|
|
if err != nil {
|
|
t.Fatalf("load manager again: %v", err)
|
|
}
|
|
if !reflect.DeepEqual(m.Manager.Client.Key, key0) {
|
|
t.Fatalf("private key changed after reload")
|
|
}
|
|
m.shutdown = make(chan struct{})
|
|
m.SetAllowedHostnames(map[dns.Domain]struct{}{{ASCII: "mox.example"}: {}})
|
|
if err := m.HostPolicy(context.Background(), "mox.example"); err != nil {
|
|
t.Fatalf("hostpolicy, got err %v, expected no error", err)
|
|
}
|
|
|
|
m2, err := Load("test2", "../testdata/autotls", "mox@localhost", "https://localhost/", shutdown)
|
|
if err != nil {
|
|
t.Fatalf("load another manager: %v", err)
|
|
}
|
|
if reflect.DeepEqual(m.Manager.Client.Key, m2.Manager.Client.Key) {
|
|
t.Fatalf("private key reused between managers")
|
|
}
|
|
|
|
// Only remove in case of success.
|
|
os.RemoveAll("../testdata/autotls")
|
|
}
|