♻️ Simplify entry HTTP delivery

This commit is contained in:
Maxim Lebedev 2024-02-14 23:44:22 +06:00
parent 8cf7d160c2
commit c420a83618
Signed by: toby3d
GPG Key ID: 1F14E25B7C119FC5
2 changed files with 14 additions and 78 deletions

View File

@ -1,11 +1,11 @@
package http
import (
"context"
"encoding/json"
"errors"
"fmt"
"mime"
"net/http"
"strings"
"github.com/go-ap/activitypub"
@ -13,21 +13,11 @@ import (
"source.toby3d.me/toby3d/home/internal/domain"
"source.toby3d.me/toby3d/home/internal/entry"
"source.toby3d.me/toby3d/home/internal/site"
"source.toby3d.me/toby3d/home/internal/theme"
"source.toby3d.me/toby3d/home/internal/urlutil"
)
type (
Handler struct {
*ThemeHandler
*ActivityPubHandler
sites site.UseCase
entries entry.UseCase
themes theme.UseCase
}
ThemeHandler struct {
themes theme.UseCase
}
ActivityPubHandler struct{}
@ -58,78 +48,26 @@ type (
*/
)
func NewHandler(sites site.UseCase, entries entry.UseCase, themes theme.UseCase) *Handler {
func NewHandler(sites site.UseCase, entries entry.UseCase) *Handler {
return &Handler{
sites: sites,
entries: entries,
themes: themes,
ThemeHandler: NewThemeHandler(themes),
ActivityPubHandler: NewActivityPubHandler(),
entries: entries,
}
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
head, tail := urlutil.ShiftPath(r.URL.Path)
lang := domain.NewLanguage(head)
s, err := h.sites.Do(r.Context(), lang)
func (h *Handler) Handle(ctx context.Context, site *domain.Site, path string) (*domain.Entry, http.Handler, error) {
entry, err := h.entries.Do(ctx, site.Language, path)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
return nil, nil, fmt.Errorf("cannot handle entry: %w", err)
}
e, err := h.entries.Do(r.Context(), lang, tail)
if err != nil {
if errors.Is(err, entry.ErrNotExist) {
http.NotFound(w, r)
} else {
http.Error(w, err.Error(), http.StatusInternalServerError)
return entry, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
contentType, _, _ := mime.ParseMediaType(r.Header.Get(common.HeaderAccept))
switch contentType {
case common.MIMEApplicationLdJSON:
h.ActivityPubHandler.Handle(s, e).ServeHTTP(w, r)
}
return
}
contentType, _, _ := mime.ParseMediaType(r.Header.Get(common.HeaderAccept))
switch contentType {
default:
h.ThemeHandler.Handle(s, e).ServeHTTP(w, r)
case common.MIMEApplicationLdJSON:
h.ActivityPubHandler.Handle(s, e).ServeHTTP(w, r)
}
}
func NewThemeHandler(themes theme.UseCase) *ThemeHandler {
return &ThemeHandler{
themes: themes,
}
}
func (h *ThemeHandler) Handle(s *domain.Site, e *domain.Entry) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// NOTE(toby3d): wrap founded entry into theme template and
// answer to client.
contentLanguage := make([]string, len(e.Translations))
for i := range e.Translations {
contentLanguage[i] = e.Translations[i].Language.Code()
}
w.Header().Set(common.HeaderContentLanguage, strings.Join(contentLanguage, ", "))
template, err := h.themes.Do(r.Context(), s, e)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set(common.HeaderContentType, common.MIMETextHTMLCharsetUTF8)
if err = template(w); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})
}), nil
}
func NewActivityPubHandler() *ActivityPubHandler {

View File

@ -11,7 +11,6 @@ import (
entryucase "source.toby3d.me/toby3d/home/internal/entry/usecase"
siteucase "source.toby3d.me/toby3d/home/internal/site/usecase"
"source.toby3d.me/toby3d/home/internal/testutil"
themeucase "source.toby3d.me/toby3d/home/internal/theme/usecase"
)
func TestHandler_ServeHTTP(t *testing.T) {
@ -36,7 +35,6 @@ func TestHandler_ServeHTTP(t *testing.T) {
delivery.NewHandler(
siteucase.NewStubSiteUseCase(domain.TestSite(t), nil),
entryucase.NewStubEntryUseCase(domain.TestEntry(t), nil),
themeucase.NewDummyThemeUseCase(),
).ServeHTTP(w, req)
testutil.GoldenEqual(t, w.Result().Body)
})