feat: redirect browse to canonical sfw url
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"mal/internal/observability"
|
"mal/internal/observability"
|
||||||
"mal/internal/server"
|
"mal/internal/server"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -181,6 +182,25 @@ func parseBrowseQuery(c *gin.Context) (browseQuery, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func canonicalBrowseURL(rawURL *url.URL) (string, bool) {
|
||||||
|
if rawURL == nil {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
query := rawURL.Query()
|
||||||
|
if _, exists := query["sfw"]; exists {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
query.Set("sfw", "true")
|
||||||
|
encoded := query.Encode()
|
||||||
|
if encoded == "" {
|
||||||
|
return rawURL.Path, true
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawURL.Path + "?" + encoded, true
|
||||||
|
}
|
||||||
|
|
||||||
func browseStudioName(ctx context.Context, svc Service, studioID int) string {
|
func browseStudioName(ctx context.Context, svc Service, studioID int) string {
|
||||||
if studioID <= 0 {
|
if studioID <= 0 {
|
||||||
return ""
|
return ""
|
||||||
@@ -286,6 +306,11 @@ func (h *AnimeHandler) respondBrowseSearchError(c *gin.Context, query browseQuer
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *AnimeHandler) HandleBrowse(c *gin.Context) {
|
func (h *AnimeHandler) HandleBrowse(c *gin.Context) {
|
||||||
|
if target, ok := canonicalBrowseURL(c.Request.URL); ok {
|
||||||
|
c.Redirect(http.StatusSeeOther, target)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
query, err := parseBrowseQuery(c)
|
query, err := parseBrowseQuery(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
server.RespondHTMLOrJSONError(c, http.StatusBadRequest, err.Error())
|
server.RespondHTMLOrJSONError(c, http.StatusBadRequest, err.Error())
|
||||||
|
|||||||
39
internal/anime/browse_handler_test.go
Normal file
39
internal/anime/browse_handler_test.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package anime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCanonicalBrowseURLAddsSFWTrueWhenMissing(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
rawURL, err := url.Parse("/browse?status=airing&order_by=popularity&sort=asc")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("url.Parse() error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
got, ok := canonicalBrowseURL(rawURL)
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("canonicalBrowseURL() should request redirect when sfw is missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
want := "/browse?order_by=popularity&sfw=true&sort=asc&status=airing"
|
||||||
|
if got != want {
|
||||||
|
t.Fatalf("canonicalBrowseURL() = %q, want %q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCanonicalBrowseURLSkipsWhenSFWAlreadyPresent(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
rawURL, err := url.Parse("/browse?status=airing&sfw=false")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("url.Parse() error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
got, ok := canonicalBrowseURL(rawURL)
|
||||||
|
if ok {
|
||||||
|
t.Fatalf("canonicalBrowseURL() unexpectedly requested redirect to %q", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user