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") != "" +} | 
