diff options
-rw-r--r-- | handler.go | 27 |
1 files changed, 23 insertions, 4 deletions
@@ -31,6 +31,24 @@ type Handler struct { cfg Config } +func (h Handler) validateRequest(r gemini.Request, absItemPath string) error { + u, err := url.Parse(r.URL) + if err != nil { + return gemini.Error{Err: err, Status: gemini.StatusBadRequest} + } + + if u.Scheme != "" && u.Scheme != "gemini" { + err = fmt.Errorf("proxy is not supported by the server") + return gemini.Error{Err: err, Status: gemini.StatusProxyRequestRefused} + } + + if !strings.HasPrefix(absItemPath, h.cfg.SourceDir) { + return gemini.Error{Err: fmt.Errorf("permission denied"), Status: gemini.StatusBadRequest} + } + + return nil +} + func (h Handler) urlAbsPath(rawURL string) (string, error) { u, err := url.Parse(rawURL) if err != nil { @@ -42,10 +60,6 @@ func (h Handler) urlAbsPath(rawURL string) (string, error) { return "", gemini.Error{Err: err, Status: gemini.StatusTemporaryFailure} } - if !strings.HasPrefix(itemPath, h.cfg.SourceDir) { - return "", gemini.Error{Err: fmt.Errorf("permission denied"), Status: gemini.StatusBadRequest} - } - return itemPath, nil } @@ -88,5 +102,10 @@ func (h Handler) Handle(r gemini.Request) gemini.Response { return gemini.ErrorResponse(err) } + err = h.validateRequest(r, path) + if err != nil { + return gemini.ErrorResponse(err) + } + return h.serveFile(path) } |