diff --git a/.gitignore b/.gitignore index 9f11b75..8682019 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .idea/ +.data/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..d306d2c --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Daisy + +A CardDav-based contacts service. + +Built using: +- [Tokidoki](https://git.sr.ht/~sircmpwn/tokidoki) +- [go-webdav](https://github.com/emersion/go-webdav) diff --git a/backend.go b/backend.go deleted file mode 100644 index 4ca4bc6..0000000 --- a/backend.go +++ /dev/null @@ -1,50 +0,0 @@ -package daisy - -import ( - "context" - "github.com/emersion/go-vcard" - "github.com/emersion/go-webdav/carddav" -) - -type Backend struct { -} - -func (b *Backend) AddressbookHomeSetPath(ctx context.Context) (string, error) { - //TODO implement me - panic("implement me") -} - -func (b *Backend) AddressBook(ctx context.Context) (*carddav.AddressBook, error) { - //TODO implement me - panic("implement me") -} - -func (b *Backend) GetAddressObject(ctx context.Context, path string, req *carddav.AddressDataRequest) (*carddav.AddressObject, error) { - //TODO implement me - panic("implement me") -} - -func (b *Backend) ListAddressObjects(ctx context.Context, req *carddav.AddressDataRequest) ([]carddav.AddressObject, error) { - //TODO implement me - panic("implement me") -} - -func (b *Backend) QueryAddressObjects(ctx context.Context, query *carddav.AddressBookQuery) ([]carddav.AddressObject, error) { - //TODO implement me - panic("implement me") -} - -func (b *Backend) PutAddressObject(ctx context.Context, path string, card vcard.Card, opts *carddav.PutAddressObjectOptions) (loc string, err error) { - //TODO implement me - panic("implement me") -} - -func (b *Backend) DeleteAddressObject(ctx context.Context, path string) error { - //TODO implement me - panic("implement me") -} - -func (b *Backend) CurrentUserPrincipal(ctx context.Context) (string, error) { - //TODO implement me - panic("implement me") -} diff --git a/cmd/daisy/serve.go b/cmd/daisy/serve.go index 14c35db..d67c8cb 100644 --- a/cmd/daisy/serve.go +++ b/cmd/daisy/serve.go @@ -6,14 +6,17 @@ import ( "flag" "github.com/1f349/daisy" "github.com/1f349/violet/utils" + "github.com/charmbracelet/log" "github.com/google/subcommands" "github.com/mrmelon54/exit-reload" - "log" "os" "path/filepath" ) -type serveCmd struct{ configPath string } +type serveCmd struct { + configPath string + debugLog bool +} func (s *serveCmd) Name() string { return "serve" } @@ -21,6 +24,7 @@ func (s *serveCmd) Synopsis() string { return "Serve contacts service" } func (s *serveCmd) SetFlags(f *flag.FlagSet) { f.StringVar(&s.configPath, "conf", "", "/path/to/config.json : path to the config file") + f.BoolVar(&s.debugLog, "debug", false, "enable debug logging") } func (s *serveCmd) Usage() string { @@ -30,19 +34,22 @@ func (s *serveCmd) Usage() string { } func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...any) subcommands.ExitStatus { - log.Println("[Daisy] Starting...") + if s.debugLog { + daisy.Logger.SetLevel(log.DebugLevel) + } + daisy.Logger.Info("Starting...") if s.configPath == "" { - log.Println("[Daisy] Error: config flag is missing") + daisy.Logger.Error("Config flag is missing") return subcommands.ExitUsageError } openConf, err := os.Open(s.configPath) if err != nil { if os.IsNotExist(err) { - log.Println("[Daisy] Error: missing config file") + daisy.Logger.Error("Missing config file") } else { - log.Println("[Daisy] Error: open config file: ", err) + daisy.Logger.Error("Open config file", "err", err) } return subcommands.ExitFailure } @@ -50,13 +57,14 @@ func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...any) subcomm var config daisy.Conf err = json.NewDecoder(openConf).Decode(&config) if err != nil { - log.Println("[Daisy] Error: invalid config file: ", err) + daisy.Logger.Error("Invalid config file", "err", err) return subcommands.ExitFailure } configPathAbs, err := filepath.Abs(s.configPath) if err != nil { - log.Fatal("[Daisy] Failed to get absolute config path") + daisy.Logger.Error("Failed to get absolute config path") + return subcommands.ExitFailure } wd := filepath.Dir(configPathAbs) normalLoad(config, wd) @@ -65,7 +73,7 @@ func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...any) subcomm func normalLoad(startUp daisy.Conf, wd string) { srv := daisy.NewHttpServer(startUp, wd) - log.Printf("[Daisy] Starting HTTP server on '%s'\n", srv.Addr) + daisy.Logger.Infof("Starting HTTP server on '%s'", srv.Addr) go utils.RunBackgroundHttp("HTTP", srv) exit_reload.ExitReload("Daisy", func() {}, func() { diff --git a/go.mod b/go.mod index 59bc3ac..b8e9348 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,36 @@ module github.com/1f349/daisy go 1.22 require ( + git.sr.ht/~sircmpwn/tokidoki v0.0.0-20240419154046-4ca7d8c4e7ca + github.com/1f349/cardcaldav v0.0.3 github.com/1f349/violet v0.0.13 - github.com/emersion/go-webdav v0.5.0 + github.com/charmbracelet/log v0.4.0 + github.com/emersion/go-webdav v0.5.1-0.20240419143909-21f251fa1de2 github.com/google/subcommands v1.2.0 - github.com/julienschmidt/httprouter v1.3.0 github.com/mrmelon54/exit-reload v0.0.2 ) require ( + filippo.io/edwards25519 v1.1.0 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/lipgloss v0.10.0 // indirect + github.com/emersion/go-ical v0.0.0-20240127095438-fc1c9d8fb2b6 // indirect github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-sql-driver/mysql v1.8.1 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/muesli/reflow v0.3.0 // indirect + github.com/muesli/termenv v0.15.2 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/rs/zerolog v1.32.0 // indirect + github.com/teambition/rrule-go v1.8.2 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.20.0 // indirect ) + +replace github.com/emersion/go-webdav => github.com/1f349/go-webdav v0.0.1 diff --git a/go.sum b/go.sum index 08eb2e0..c83fe5d 100644 --- a/go.sum +++ b/go.sum @@ -1,27 +1,74 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +git.sr.ht/~sircmpwn/tokidoki v0.0.0-20240419154046-4ca7d8c4e7ca h1:HBRu4nwicaaZ4oqwTis2qy4Gb/CKLA2OSlibdKpMhb8= +git.sr.ht/~sircmpwn/tokidoki v0.0.0-20240419154046-4ca7d8c4e7ca/go.mod h1:/1jsi+vx9b/T8UHrDRJXwoY8td9JUXd9UajtVCpVoeg= +github.com/1f349/cardcaldav v0.0.3 h1:c2/wmOf+hwgKdaWLlKm5v8l0g9brD+Seqcp+xIDUXJI= +github.com/1f349/cardcaldav v0.0.3/go.mod h1:MCoGRimM7p/rLWtaJxYO91tsvgXZ47M69X3lldb5dfk= +github.com/1f349/go-webdav v0.0.1 h1:qF0k+zdcwE9DapLu+fGYQO866W269eHVLQ1mrhZGlb4= +github.com/1f349/go-webdav v0.0.1/go.mod h1:mI8iBx3RAODwX7PJJ7qzsKAKs/vY429YfS2/9wKnDbQ= github.com/1f349/violet v0.0.13 h1:lJpTz15Ea83Uc1VAISXTjtKuzr8Pe8NM4cMGp3Aiyhk= github.com/1f349/violet v0.0.13/go.mod h1:Ga5/hWqI+EkR6J1mAMNzs7aJhuGcA89XFqgQaDXC7Jo= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s= +github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE= +github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8ZM= +github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emersion/go-ical v0.0.0-20220601085725-0864dccc089f/go.mod h1:2MKFUgfNMULRxqZkadG1Vh44we3y5gJAtTBlVsx1BKQ= +github.com/emersion/go-ical v0.0.0-20240127095438-fc1c9d8fb2b6 h1:kHoSgklT8weIDl6R6xFpBJ5IioRdBU1v2X2aCZRVCcM= +github.com/emersion/go-ical v0.0.0-20240127095438-fc1c9d8fb2b6/go.mod h1:BEksegNspIkjCQfmzWgsgbu6KdeJ/4LwUZs7DMBzjzw= github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 h1:ATgqloALX6cHCranzkLb8/zjivwQ9DWWDCQRnxTPfaA= github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM= -github.com/emersion/go-webdav v0.5.0 h1:Ak/BQLgAihJt/UxJbCsEXDPxS5Uw4nZzgIMOq3rkKjc= -github.com/emersion/go-webdav v0.5.0/go.mod h1:ycyIzTelG5pHln4t+Y32/zBvmrM7+mV7x+V+Gx4ZQno= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mrmelon54/exit-reload v0.0.2 h1:vqgfrMD/bF21HkDsWgg5+NLjFDrD3KGVEN/iTrMn9Ms= github.com/mrmelon54/exit-reload v0.0.2/go.mod h1:aE3NhsqGMLUqmv6cJZRouC/8gXkZTvVSabRGOpI+Vjc= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= +github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/teambition/rrule-go v1.7.2/go.mod h1:mBJ1Ht5uboJ6jexKdNUJg2NcwP8uUMNvStWXlJD3MvU= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/teambition/rrule-go v1.8.2 h1:lIjpjvWTj9fFUZCmuoVDrKVOtdiyzbzc93qTmRVe/J8= github.com/teambition/rrule-go v1.8.2/go.mod h1:Ieq5AbrKGciP1V//Wq8ktsTXwSwJHDD5mD/wLBGl3p4= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/logger.go b/logger.go new file mode 100644 index 0000000..4867e06 --- /dev/null +++ b/logger.go @@ -0,0 +1,12 @@ +package daisy + +import ( + "github.com/charmbracelet/log" + "os" +) + +var Logger = log.NewWithOptions(os.Stderr, log.Options{ + ReportCaller: true, + ReportTimestamp: true, + Prefix: "Daisy", +}) diff --git a/server.go b/server.go index 86997f7..9b25e7c 100644 --- a/server.go +++ b/server.go @@ -1,23 +1,90 @@ package daisy import ( + "git.sr.ht/~sircmpwn/tokidoki/storage" + "github.com/1f349/cardcaldav" + "github.com/emersion/go-webdav" "github.com/emersion/go-webdav/carddav" "net/http" + "path/filepath" "time" ) type Conf struct { Listen string `json:"listen"` + DB string `json:"db"` +} + +type daisyHandler struct { + auth *cardcaldav.Auth + backend carddav.Backend +} + +func (d *daisyHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + principlePath, err := d.auth.CurrentUserPrincipal(req.Context()) + if err != nil { + http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + return + } + + var homeSets []webdav.BackendSuppliedHomeSet + path, err := d.backend.AddressBookHomeSetPath(req.Context()) + if err != nil { + http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + return + } + homeSets = append(homeSets, carddav.NewAddressBookHomeSet(path)) + + if req.URL.Path == principlePath { + opts := webdav.ServePrincipalOptions{ + CurrentUserPrincipalPath: principlePath, + HomeSets: homeSets, + Capabilities: []webdav.Capability{ + carddav.CapabilityAddressBook, + }, + } + webdav.ServePrincipal(rw, req, &opts) + return + } + + if req.URL.Path == "/" { + http.Error(rw, "Daisy API Endpoint", http.StatusOK) + return + } + + http.NotFound(rw, req) } func NewHttpServer(conf Conf, wd string) *http.Server { - h := &carddav.Handler{ - Backend: &Backend{}, + cardcaldav.SetupLogger(Logger) + principle := cardcaldav.NewAuth(conf.DB, Logger) + + _, cardStorage, err := storage.NewFilesystem(filepath.Join(wd, "storage"), "/calendar/", "/contacts/", principle) + if err != nil { + Logger.Fatal("Failed to load storage backend", "err", err) } + cardHandler := &carddav.Handler{Backend: cardStorage} + + handler := &daisyHandler{ + auth: principle, + backend: cardStorage, + } + + r := http.NewServeMux() + r.Handle("/", handler) + r.Handle("/.well-known/carddav", cardHandler) + r.Handle("/{user}/contacts/", cardHandler) + + r2 := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + t := time.Now() + r.ServeHTTP(rw, req) + td := time.Since(t) + Logger.Debug("Request", "method", req.Method, "url", req.URL.String(), "remote", req.RemoteAddr, "dur", td.String()) + }) return &http.Server{ Addr: conf.Listen, - Handler: h, + Handler: principle.Middleware(r2), ReadTimeout: time.Minute, ReadHeaderTimeout: time.Minute, WriteTimeout: time.Minute,