1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-05-31 23:19:50 +02:00
oauth2-proxy/pkg/app/pagewriter/static_pages.go
2021-03-21 18:28:37 +00:00

99 lines
2.8 KiB
Go

package pagewriter
import (
// Import embed to allow importing default page templates
_ "embed"
"fmt"
"net/http"
"os"
"path/filepath"
middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
)
const (
robotsTxtName = "robots.txt"
)
//go:embed robots.txt
var defaultRobotsTxt []byte
// staticPageWriter is used to write static pages.
type staticPageWriter struct {
pages map[string][]byte
errorPageWriter *errorPageWriter
}
// WriteRobotsTxt writes the robots.txt content to the response writer.
func (s *staticPageWriter) WriteRobotsTxt(rw http.ResponseWriter, req *http.Request) {
s.writePage(rw, req, robotsTxtName)
}
// writePage writes the content of the page to the response writer.
func (s *staticPageWriter) writePage(rw http.ResponseWriter, req *http.Request, pageName string) {
content, ok := s.pages[pageName]
if !ok {
// If the page isn't regiested, something went wrong and there is a bug.
// Tests should make sure this code path is never hit.
panic(fmt.Sprintf("Static page %q not found", pageName))
}
_, err := rw.Write(content)
if err != nil {
logger.Printf("Error writing %q: %v", pageName, err)
scope := middlewareapi.GetRequestScope(req)
s.errorPageWriter.WriteErrorPage(rw, ErrorPageOpts{
Status: http.StatusInternalServerError,
RequestID: scope.RequestID,
AppError: err.Error(),
})
return
}
}
func newStaticPageWriter(customDir string, errorWriter *errorPageWriter) (*staticPageWriter, error) {
pages, err := loadStaticPages(customDir)
if err != nil {
return nil, fmt.Errorf("could not load static pages: %v", err)
}
return &staticPageWriter{
pages: pages,
errorPageWriter: errorWriter,
}, nil
}
// loadStaticPages loads static page content from the custom directory provided.
// If any file is not provided in the custom directory, the default will be used
// instead.
// Statis files include:
// - robots.txt
func loadStaticPages(customDir string) (map[string][]byte, error) {
pages := make(map[string][]byte)
if err := addStaticPage(pages, customDir, robotsTxtName, defaultRobotsTxt); err != nil {
return nil, fmt.Errorf("could not add robots.txt: %v", err)
}
return pages, nil
}
// addStaticPage tries to load the named file from the custom directory.
// If no custom directory is provided, the default content is used instead.
func addStaticPage(pages map[string][]byte, customDir, fileName string, defaultContent []byte) error {
filePath := filepath.Join(customDir, fileName)
if customDir != "" && isFile(filePath) {
content, err := os.ReadFile(filePath)
if err != nil {
return fmt.Errorf("could not read file: %v", err)
}
pages[fileName] = content
return nil
}
// No custom content defined, use the default.
pages[fileName] = defaultContent
return nil
}