Serve `robots.txt` from root (http://server/robots.txt)

This commit is contained in:
Deluan 2020-10-02 10:15:19 -04:00
parent deef8e162d
commit 8dfc259857
5 changed files with 91 additions and 4 deletions

View File

@ -3,13 +3,14 @@ package server
import (
"fmt"
"net/http"
"strings"
"time"
"github.com/deluan/navidrome/log"
"github.com/go-chi/chi/middleware"
)
func RequestLogger(next http.Handler) http.Handler {
func requestLogger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
scheme := "http"
if r.TLS != nil {
@ -44,3 +45,16 @@ func RequestLogger(next http.Handler) http.Handler {
}
})
}
func robotsTXT(fs http.FileSystem) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.HasSuffix(r.URL.Path, "/robots.txt") {
r.URL.Path = "/robots.txt"
http.FileServer(fs).ServeHTTP(w, r)
} else {
next.ServeHTTP(w, r)
}
})
}
}

View File

@ -0,0 +1,50 @@
package server
import (
"net/http"
"net/http/httptest"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("middlewares", func() {
var nextCalled bool
next := func(w http.ResponseWriter, r *http.Request) {
nextCalled = true
}
Describe("robotsTXT", func() {
BeforeEach(func() {
nextCalled = false
})
It("returns the robot.txt when requested from root", func() {
r := httptest.NewRequest("GET", "/robots.txt", nil)
w := httptest.NewRecorder()
robotsTXT(http.Dir("tests/fixtures"))(http.HandlerFunc(next)).ServeHTTP(w, r)
Expect(nextCalled).To(BeFalse())
Expect(w.Body.String()).To(HavePrefix("User-agent:"))
})
It("allows prefixes", func() {
r := httptest.NewRequest("GET", "/app/robots.txt", nil)
w := httptest.NewRecorder()
robotsTXT(http.Dir("tests/fixtures"))(http.HandlerFunc(next)).ServeHTTP(w, r)
Expect(nextCalled).To(BeFalse())
Expect(w.Body.String()).To(HavePrefix("User-agent:"))
})
It("passes through requests for other files", func() {
r := httptest.NewRequest("GET", "/this_is_not_a_robots.txt_file", nil)
w := httptest.NewRecorder()
robotsTXT(http.Dir("tests/fixtures"))(http.HandlerFunc(next)).ServeHTTP(w, r)
Expect(nextCalled).To(BeTrue())
})
})
})

View File

@ -5,6 +5,7 @@ import (
"path"
"time"
"github.com/deluan/navidrome/assets"
"github.com/deluan/navidrome/conf"
"github.com/deluan/navidrome/consts"
"github.com/deluan/navidrome/log"
@ -39,7 +40,7 @@ func (a *Server) MountRouter(urlPath string, subRouter Handler) {
log.Info("Mounting routes", "path", urlPath)
subRouter.Setup(urlPath)
a.router.Group(func(r chi.Router) {
r.Use(RequestLogger)
r.Use(requestLogger)
r.Mount(urlPath, subRouter)
})
}
@ -58,7 +59,8 @@ func (a *Server) initRoutes() {
r.Use(middleware.Recoverer)
r.Use(middleware.Compress(5, "application/xml", "application/json", "application/javascript"))
r.Use(middleware.Heartbeat("/ping"))
r.Use(InjectLogger)
r.Use(injectLogger)
r.Use(robotsTXT(assets.AssetFile()))
indexHtml := path.Join(conf.Server.BaseURL, consts.URLPathUI, "index.html")
r.Get("/*", func(w http.ResponseWriter, r *http.Request) {
@ -87,7 +89,7 @@ func (a *Server) initScanner() {
}()
}
func InjectLogger(next http.Handler) http.Handler {
func injectLogger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx = log.NewContext(r.Context(), "requestId", ctx.Value(middleware.RequestIDKey))

View File

@ -0,0 +1,17 @@
package server
import (
"testing"
"github.com/deluan/navidrome/log"
"github.com/deluan/navidrome/tests"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
func TestSubsonicApi(t *testing.T) {
tests.Init(t, false)
log.SetLevel(log.LevelCritical)
RegisterFailHandler(Fail)
RunSpecs(t, "Server Suite")
}

4
tests/fixtures/robots.txt vendored Normal file
View File

@ -0,0 +1,4 @@
User-agent: bingbot
Disallow: /manifest.json
User-agent: *