diff options
author | tjpcc <tjp@ctrl-c.club> | 2023-08-12 11:15:10 -0600 |
---|---|---|
committer | tjpcc <tjp@ctrl-c.club> | 2023-08-12 17:50:07 -0600 |
commit | d33ae9da7691a254e08251c375aaa9f6d58631e5 (patch) | |
tree | fccd0fc3ddf2dd5304efdb9c482a4cab4d2e0d4c | |
parent | 39ab058ea779763b83e05812cd222e2cbef90eab (diff) |
quick and dirty http[s] client in the multi-client
-rw-r--r-- | client.go | 42 |
1 files changed, 40 insertions, 2 deletions
@@ -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") != "" +} |