From 2e5ac8b9e1f2f705455d74750e465c2066ffdc7c Mon Sep 17 00:00:00 2001 From: tjp Date: Thu, 3 Apr 2025 09:51:32 -0600 Subject: empty path handling for spartan/gemini clients and servers --- spartan/client.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'spartan') diff --git a/spartan/client.go b/spartan/client.go index d77e791..aff9276 100644 --- a/spartan/client.go +++ b/spartan/client.go @@ -8,6 +8,7 @@ import ( "net" neturl "net/url" "strconv" + "strings" "tildegit.org/tjp/sliderule/internal/types" ) @@ -30,7 +31,10 @@ func NewClient() Client { // single request by default. This can be changed by altering the MaxRedirects field. const DefaultMaxRedirects int = 2 -var ExceededMaxRedirects = errors.New("spartan.Client: exceeded MaxRedirects") +var ( + ErrExceededMaxRedirects = errors.New("spartan.Client: exceeded MaxRedirects") + ErrInvalidRequest = errors.New("spartan.Client: request is invalid") +) // RoundTrip sends a single spartan request and returns its response. func (c Client) RoundTrip(ctx context.Context, request *types.Request) (*types.Response, error) { @@ -64,6 +68,13 @@ func (c Client) RoundTrip(ctx context.Context, request *types.Request) (*types.R } } + if request.Path == "" { + request.Path = "/" + } + if !strings.HasPrefix(request.Path, "/") { + return nil, ErrInvalidRequest + } + requestLine := host + " " + request.EscapedPath() + " " + strconv.Itoa(int(rdr.N)) + "\r\n" if _, err := conn.Write([]byte(requestLine)); err != nil { @@ -114,7 +125,7 @@ func (c Client) Fetch(ctx context.Context, url string) (*types.Response, error) u = prev.ResolveReference(u) } - return nil, ExceededMaxRedirects + return nil, ErrExceededMaxRedirects } func (c Client) IsRedirect(response *types.Response) bool { -- cgit v1.2.3