summaryrefslogtreecommitdiff
path: root/gemini/client.go
diff options
context:
space:
mode:
Diffstat (limited to 'gemini/client.go')
-rw-r--r--gemini/client.go40
1 files changed, 39 insertions, 1 deletions
diff --git a/gemini/client.go b/gemini/client.go
index 7c78b71..338271c 100644
--- a/gemini/client.go
+++ b/gemini/client.go
@@ -6,6 +6,7 @@ import (
"errors"
"io"
"net"
+ neturl "net/url"
sr "tildegit.org/tjp/sliderule"
)
@@ -18,14 +19,22 @@ import (
//
// The zero value is a usable Client with no client TLS certificate.
type Client struct {
+ MaxRedirects int
+
tlsConf *tls.Config
}
// Create a gemini Client with the given TLS configuration.
func NewClient(tlsConf *tls.Config) Client {
- return Client{tlsConf: tlsConf}
+ return Client{tlsConf: tlsConf, MaxRedirects: DefaultMaxRedirects}
}
+// DefaultMaxRedirects is the number of chained redirects a Client will perform for a
+// single request by default. This can be changed by altering the MaxRedirects field.
+const DefaultMaxRedirects int = 2
+
+var ExceededMaxRedirects = errors.New("gemini.Client: exceeded MaxRedirects")
+
// RoundTrip sends a single gemini request to the correct server and returns its response.
//
// It also populates the TLSState and RemoteAddr fields on the request - the only field
@@ -77,3 +86,32 @@ func (client Client) RoundTrip(request *sr.Request) (*sr.Response, error) {
return response, nil
}
+
+// Fetch parses a URL string and fetches the gemini resource.
+//
+// It will resolve any redirects along the way, up to client.MaxRedirects.
+func (c Client) Fetch(url string) (*sr.Response, error) {
+ u, err := neturl.Parse(url)
+ if err != nil {
+ return nil, err
+ }
+
+ for i := 0; i <= c.MaxRedirects; i += 1 {
+ response, err := c.RoundTrip(&sr.Request{URL: u})
+ if err != nil {
+ return nil, err
+ }
+ if ResponseCategoryForStatus(response.Status) != ResponseCategoryRedirect {
+ return response, nil
+ }
+
+ prev := u
+ u, err = neturl.Parse(url)
+ if err != nil {
+ return nil, err
+ }
+ u = prev.ResolveReference(u)
+ }
+
+ return nil, ExceededMaxRedirects
+}