Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit size of _redirects and _headers files #150

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ echo dotenv > .envrc && direnv allow
Boot up database (or bring your own)

```bash
docker compose up -f docker-compose.yml -f docker-compose.override.yml --profile db -d
docker compose -f docker-compose.yml -f docker-compose.override.yml --profile db up -d
```

Create db and migrate
Expand Down
22 changes: 18 additions & 4 deletions pgs/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,18 @@ func hasProtocol(url string) bool {

func (h *AssetHandler) handle(logger *slog.Logger, w http.ResponseWriter, r *http.Request) {
var redirects []*RedirectRule
redirectFp, _, err := h.Storage.GetObject(h.Bucket, filepath.Join(h.ProjectDir, "_redirects"))
redirectFp, redirectInfo, err := h.Storage.GetObject(h.Bucket, filepath.Join(h.ProjectDir, "_redirects"))
if err == nil {
defer redirectFp.Close()
if redirectInfo != nil && redirectInfo.Size > h.Cfg.MaxSpecialFileSize {
errMsg := fmt.Sprintf("_redirects file is too large (%d > %d)", redirectInfo.Size, h.Cfg.MaxSpecialFileSize)
logger.Error(errMsg)
http.Error(w, errMsg, http.StatusInternalServerError)
return
}
buf := new(strings.Builder)
_, err := io.Copy(buf, redirectFp)
lr := io.LimitReader(redirectFp, h.Cfg.MaxSpecialFileSize)
_, err := io.Copy(buf, lr)
if err != nil {
logger.Error("io copy", "err", err.Error())
http.Error(w, "cannot read _redirects file", http.StatusInternalServerError)
Expand Down Expand Up @@ -299,11 +306,18 @@ func (h *AssetHandler) handle(logger *slog.Logger, w http.ResponseWriter, r *htt
}

var headers []*HeaderRule
headersFp, _, err := h.Storage.GetObject(h.Bucket, filepath.Join(h.ProjectDir, "_headers"))
headersFp, headersInfo, err := h.Storage.GetObject(h.Bucket, filepath.Join(h.ProjectDir, "_headers"))
if err == nil {
defer headersFp.Close()
if headersInfo != nil && headersInfo.Size > h.Cfg.MaxSpecialFileSize {
errMsg := fmt.Sprintf("_headers file is too large (%d > %d)", headersInfo.Size, h.Cfg.MaxSpecialFileSize)
logger.Error(errMsg)
http.Error(w, errMsg, http.StatusInternalServerError)
return
}
buf := new(strings.Builder)
_, err := io.Copy(buf, headersFp)
lr := io.LimitReader(headersFp, h.Cfg.MaxSpecialFileSize)
_, err := io.Copy(buf, lr)
if err != nil {
logger.Error("io copy", "err", err.Error())
http.Error(w, "cannot read _headers file", http.StatusInternalServerError)
Expand Down
30 changes: 17 additions & 13 deletions pgs/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
var maxSize = uint64(25 * utils.MB)
var maxAssetSize = int64(10 * utils.MB)

// Needs to be small for caching files like _headers and _redirects.
var maxSpecialFileSize = int64(5 * utils.KB)

func NewConfigSite() *shared.ConfigSite {
domain := utils.GetEnv("PGS_DOMAIN", "pgs.sh")
port := utils.GetEnv("PGS_WEB_PORT", "3000")
Expand All @@ -23,19 +26,20 @@ func NewConfigSite() *shared.ConfigSite {
}

cfg := shared.ConfigSite{
Secret: secret,
Domain: domain,
Port: port,
Protocol: protocol,
DbURL: dbURL,
StorageDir: storageDir,
MinioURL: minioURL,
MinioUser: minioUser,
MinioPass: minioPass,
Space: "pgs",
MaxSize: maxSize,
MaxAssetSize: maxAssetSize,
Logger: shared.CreateLogger("pgs"),
Secret: secret,
Domain: domain,
Port: port,
Protocol: protocol,
DbURL: dbURL,
StorageDir: storageDir,
MinioURL: minioURL,
MinioUser: minioUser,
MinioPass: minioPass,
Space: "pgs",
MaxSize: maxSize,
MaxAssetSize: maxAssetSize,
MaxSpecialFileSize: maxSpecialFileSize,
Logger: shared.CreateLogger("pgs"),
}

return &cfg
Expand Down
10 changes: 6 additions & 4 deletions prose/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func NewConfigSite() *shared.ConfigSite {
dbURL := utils.GetEnv("DATABASE_URL", "")
maxSize := uint64(500 * utils.MB)
maxImgSize := int64(10 * utils.MB)
maxSpecialFileSize := int64(5 * utils.KB)
secret := utils.GetEnv("PICO_SECRET", "")
if secret == "" {
panic("must provide PICO_SECRET environment variable")
Expand Down Expand Up @@ -44,9 +45,10 @@ func NewConfigSite() *shared.ConfigSite {
".svg",
".ico",
},
HiddenPosts: []string{"_readme.md", "_styles.css", "_footer.md", "_404.md"},
Logger: shared.CreateLogger("prose"),
MaxSize: maxSize,
MaxAssetSize: maxImgSize,
HiddenPosts: []string{"_readme.md", "_styles.css", "_footer.md", "_404.md"},
Logger: shared.CreateLogger("prose"),
MaxSize: maxSize,
MaxAssetSize: maxImgSize,
MaxSpecialFileSize: maxSpecialFileSize,
}
}
37 changes: 19 additions & 18 deletions shared/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,25 @@ type PageData struct {
}

type ConfigSite struct {
Debug bool
SendgridKey string
Secret string
Domain string
Port string
PortOverride string
Protocol string
DbURL string
StorageDir string
MinioURL string
MinioUser string
MinioPass string
Space string
AllowedExt []string
HiddenPosts []string
MaxSize uint64
MaxAssetSize int64
Logger *slog.Logger
Debug bool
SendgridKey string
Secret string
Domain string
Port string
PortOverride string
Protocol string
DbURL string
StorageDir string
MinioURL string
MinioUser string
MinioPass string
Space string
AllowedExt []string
HiddenPosts []string
MaxSize uint64
MaxAssetSize int64
MaxSpecialFileSize int64
Logger *slog.Logger
}

func NewConfigSite() *ConfigSite {
Expand Down
Loading