From 43b207c9ab1af74c7a3a19eb41767e511e6d4bb4 Mon Sep 17 00:00:00 2001 From: antanst Date: Thu, 16 Jan 2025 13:58:14 +0200 Subject: [PATCH] Simplify duplicate code --- common/gemini_url.go | 44 +++++++++------------------------------ common/gemini_url_test.go | 5 +++-- gemini/geminiLinks.go | 4 ++-- 3 files changed, 15 insertions(+), 38 deletions(-) diff --git a/common/gemini_url.go b/common/gemini_url.go index 54aa8a3..74ec472 100644 --- a/common/gemini_url.go +++ b/common/gemini_url.go @@ -28,7 +28,7 @@ func (u *URL) Scan(value interface{}) error { if !ok { return fmt.Errorf("%w: expected string, got %T", ErrDatabaseScan, value) } - parsedURL, err := ParseURLNoNormalize(b, "") + parsedURL, err := ParseURL(b, "", false) if err != nil { err = fmt.Errorf("%w: failed to scan GeminiUrl %s: %v", ErrDatabaseScan, b, err) return err @@ -55,38 +55,14 @@ func (u URL) Value() (driver.Value, error) { return u.Full, nil } -func ParseURLNoNormalize(input string, descr string) (*URL, error) { - u, err := url.Parse(input) - if err != nil { - return nil, fmt.Errorf("%w: Input %s URL Parse Error: %w", ErrURLParse, input, err) +func ParseURL(input string, descr string, normalize bool) (*URL, error) { + var u *url.URL + var err error + if normalize { + u, err = NormalizeURL(input) + } else { + u, err = url.Parse(input) } - if u.Scheme != "gemini" { - return nil, fmt.Errorf("%w: URL scheme '%s' is not supported", ErrURLNotGemini, u.Scheme) - } - protocol := u.Scheme - hostname := u.Hostname() - strPort := u.Port() - urlPath := u.Path - if strPort == "" { - strPort = "1965" - } - port, err := strconv.Atoi(strPort) - if err != nil { - return nil, fmt.Errorf("%w: Input %s GeminiError %w", ErrURLParse, input, err) - } - full := fmt.Sprintf("%s://%s:%d%s", protocol, hostname, port, urlPath) - // full field should also contain query params and url fragments - if u.RawQuery != "" { - full += "?" + u.RawQuery - } - if u.Fragment != "" { - full += "#" + u.Fragment - } - return &URL{Protocol: protocol, Hostname: hostname, Port: port, Path: urlPath, Descr: descr, Full: full}, nil -} - -func ParseURL(input string, descr string) (*URL, error) { - u, err := NormalizeURL(input) if err != nil { return nil, fmt.Errorf("%w: Input %s URL Parse Error: %w", ErrURLParse, input, err) } @@ -121,7 +97,7 @@ func ParseURL(input string, descr string) (*URL, error) { func DeriveAbsoluteURL(currentURL URL, input string) (*URL, error) { // If target URL is absolute, return just it if strings.Contains(input, "://") { - return ParseURL(input, "") + return ParseURL(input, "", true) } // input is a relative path. Clean it and construct absolute. var newPath string @@ -134,7 +110,7 @@ func DeriveAbsoluteURL(currentURL URL, input string) (*URL, error) { newPath = path.Join(currentURL.Path, "/", path.Clean(input)) } strURL := fmt.Sprintf("%s://%s:%d%s", currentURL.Protocol, currentURL.Hostname, currentURL.Port, newPath) - return ParseURL(strURL, "") + return ParseURL(strURL, "", true) } // NormalizeURL takes a URL string and returns a normalized version. diff --git a/common/gemini_url_test.go b/common/gemini_url_test.go index 36ce19e..821946a 100644 --- a/common/gemini_url_test.go +++ b/common/gemini_url_test.go @@ -1,15 +1,16 @@ package common_test import ( - "gemini-grc/common" "reflect" "testing" + + "gemini-grc/common" ) func TestParseURL(t *testing.T) { t.Parallel() input := "gemini://caolan.uk/cgi-bin/weather.py/wxfcs/3162" - parsed, err := common.ParseURL(input, "") + parsed, err := common.ParseURL(input, "", true) value, _ := parsed.Value() if err != nil || !(value == "gemini://caolan.uk:1965/cgi-bin/weather.py/wxfcs/3162") { t.Errorf("fail: %s", parsed) diff --git a/gemini/geminiLinks.go b/gemini/geminiLinks.go index 050729a..bfc33b3 100644 --- a/gemini/geminiLinks.go +++ b/gemini/geminiLinks.go @@ -77,8 +77,8 @@ func ParseGeminiLinkLine(linkLine string, currentURL string) (*common.URL, error if len(description) > 0 && description[0] == ' ' { description = description[1:] } - - finalURL, err := common.ParseURL(parsedURL.String(), description) + + finalURL, err := common.ParseURL(parsedURL.String(), description, true) if err != nil { // If URL parsing fails, return an error return nil, fmt.Errorf("%w: %w", common.ErrURLParse, err)