summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client.go42
1 files changed, 40 insertions, 2 deletions
diff --git a/client.go b/client.go
index 3631bc5..936c2d8 100644
--- a/client.go
+++ b/client.go
@@ -4,6 +4,7 @@ import (
"crypto/tls"
"errors"
"fmt"
+ "net/http"
neturl "net/url"
"tildegit.org/tjp/sliderule/finger"
@@ -25,7 +26,7 @@ type Client struct {
protos map[string]protocolClient
}
-const DefaultMaxRedirects int = 2
+const DefaultMaxRedirects int = 5
var ExceededMaxRedirects = errors.New("Client: exceeded MaxRedirects")
@@ -34,12 +35,15 @@ var ExceededMaxRedirects = errors.New("Client: exceeded MaxRedirects")
// tlsConf may be nil, in which case gemini requests connections will not be made
// with any client certificate.
func NewClient(tlsConf *tls.Config) Client {
+ hc := httpClient{}
return Client{
protos: map[string]protocolClient{
"finger": finger.Client{},
"gopher": gopher.Client{},
"gemini": gemini.NewClient(tlsConf),
"spartan": spartan.NewClient(),
+ "http": hc,
+ "https": hc,
},
MaxRedirects: DefaultMaxRedirects,
}
@@ -74,7 +78,7 @@ func (c Client) Fetch(url string) (*Response, error) {
}
prev := u
- u, err = neturl.Parse(response.Meta.(string))
+ u, err = neturl.Parse(getRedirectLocation(u.Scheme, response.Meta))
if err != nil {
return nil, err
}
@@ -85,3 +89,37 @@ func (c Client) Fetch(url string) (*Response, error) {
return nil, ExceededMaxRedirects
}
+
+func getRedirectLocation(proto string, meta any) string {
+ switch proto {
+ case "gemini", "spartan":
+ return meta.(string)
+ case "http", "https":
+ return meta.(http.Header).Get("Location")
+ }
+ return ""
+}
+
+type httpClient struct{}
+
+func (hc httpClient) RoundTrip(request *Request) (*Response, error) {
+ hreq, err := http.NewRequest("GET", request.URL.String(), nil)
+ if err != nil {
+ return nil, err
+ }
+
+ hresp, err := http.DefaultTransport.RoundTrip(hreq)
+ if err != nil {
+ return nil, err
+ }
+
+ return &Response{
+ Status: Status(hresp.StatusCode),
+ Meta: hresp.Header,
+ Body: hresp.Body,
+ }, nil
+}
+
+func (hc httpClient) IsRedirect(response *Response) bool {
+ return response.Meta.(http.Header).Get("Location") != ""
+}