diff --git a/internal/cmd/home/home.go b/internal/cmd/home/home.go index 1c2eb13..6b8f2a7 100644 --- a/internal/cmd/home/home.go +++ b/internal/cmd/home/home.go @@ -63,18 +63,6 @@ func NewApp(logger *log.Logger, config *domain.Config) (*App, error) { webfingerer := webfingerucase.NewWebFingerUseCase(sites) webfingerHandler := webfingerhttpdelivery.NewHandler(webfingerer) handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - head, tail := urlutil.ShiftPath(r.URL.Path) - - switch head { - case ".well-known": - switch { - case strings.HasPrefix(tail, "/webfinger"): - webfingerHandler.ServeHTTP(w, r) - - return - } - } - // NOTE(toby3d): any static file is public and unprotected by // design, so it's safe to search it first before deep down to // any page or it's resource which might be protected by @@ -85,6 +73,7 @@ func NewApp(logger *log.Logger, config *domain.Config) (*App, error) { return } + head, tail := urlutil.ShiftPath(r.URL.Path) lang := domain.LanguageUnd // NOTE(toby3d): read $HOME_CONTENT_DIR/index.md as a source of @@ -96,13 +85,9 @@ func NewApp(logger *log.Logger, config *domain.Config) (*App, error) { return } - if s.IsMultiLingual() { - // NOTE(toby3d): $HOME_CONTENT_DIR contains at least two - // index.md with different language codes. - if head, tail = urlutil.ShiftPath(r.URL.Path); head == "" { - // NOTE(toby3d): client request just '/', try to - // understand which language subdirectory is - // need to redirect. + switch strings.ToLower(head) { + case "": + if s.IsMultiLingual() { supported := make([]language.Tag, len(s.Languages)) for i := range s.Languages { supported[i] = language.Make(s.Languages[i].Lang()) @@ -113,9 +98,9 @@ func NewApp(logger *log.Logger, config *domain.Config) (*App, error) { supported...) } - requested, _, err := language.ParseAcceptLanguage(r.Header.Get( + requested, _, _ := language.ParseAcceptLanguage(r.Header.Get( common.HeaderAcceptLanguage)) - if err != nil || len(requested) == 0 { + if len(requested) == 0 { requested = append(requested, language.English) } @@ -127,13 +112,48 @@ func NewApp(logger *log.Logger, config *domain.Config) (*App, error) { return } - // NOTE(toby3d): client request '/:something/...', try - // to understand which language code in subdir is - // requested. - if lang = domain.NewLanguage(head); lang != domain.LanguageUnd { - r.URL.Path = tail + e, err := entrier.Do(r.Context(), lang, r.URL.Path) + if err != nil { + if errors.Is(err, entry.ErrNotExist) { + http.NotFound(w, r) + } else { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + + return } + template, err := themer.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) + } + + return + case ".well-known": + switch strings.ToLower(tail) { + case "/webfinger": + webfingerHandler.ServeHTTP(w, r) + + return + } + } + + if s.IsMultiLingual() { + // NOTE(toby3d): $HOME_CONTENT_DIR contains at least two + // index.md with different language codes. + head, tail = urlutil.ShiftPath(r.URL.Path) + + // NOTE(toby3d): client request '/:lang/...', try to + // understand which language code in subdir is requested. + lang = domain.NewLanguage(head) + // NOTE(toby3d): get localized site config for requested // subdir if exists. if s, err = siter.Do(r.Context(), lang); err != nil { @@ -143,31 +163,7 @@ func NewApp(logger *log.Logger, config *domain.Config) (*App, error) { } } - // NOTE(toby3d): search entry for requested URL and language - // code in subdir. - e, err := entrier.Do(r.Context(), lang, r.URL.Path) - if err != nil { - if !errors.Is(err, entry.ErrNotExist) { - http.Error(w, err.Error(), http.StatusInternalServerError) - - return - } - - // NOTE(toby3d): maybe it is not a entry, but is't - // resource? - res, err := resourcer.Do(r.Context(), r.URL.Path) - if err != nil { - if errors.Is(err, fs.ErrNotExist) { - http.Error(w, err.Error(), http.StatusNotFound) - - return - } - - http.Error(w, err.Error(), http.StatusInternalServerError) - - return - } - + if res, err := resourcer.Do(r.Context(), r.URL.Path); err == nil { // TODO(toby3d) : ugly workaround, must be refactored resFile, err := contentDir.Open(res.File.Path()) if err != nil { @@ -190,6 +186,17 @@ func NewApp(logger *log.Logger, config *domain.Config) (*App, error) { return } + // NOTE(toby3d): search entry for requested URL and language + // code in subdir. + e, err := entrier.Do(r.Context(), lang, tail) + if err != nil { + if !errors.Is(err, entry.ErrNotExist) { + http.Error(w, err.Error(), http.StatusInternalServerError) + + return + } + } + // NOTE(toby3d): wrap founded entry into theme template and // answer to client. contentLanguage := make([]string, len(e.Translations))