package gopher import ( "bytes" "errors" "io" "net" "tildegit.org/tjp/gus" ) // Client is used for sending gopher requests and producing the responses. // // It carries no state and is reusable simultaneously by multiple goroutines. // // The zero value is immediately usable. type Client struct{} // RoundTrip sends a single gopher request and returns its response. func (c Client) RoundTrip(request *gus.Request) (*gus.Response, error) { if request.Scheme != "gopher" && request.Scheme != "" { return nil, errors.New("non-gopher protocols not supported") } host := request.Host if _, port, _ := net.SplitHostPort(host); port == "" { host = net.JoinHostPort(host, "70") } conn, err := net.Dial("tcp", host) if err != nil { return nil, err } defer conn.Close() request.RemoteAddr = conn.RemoteAddr() request.TLSState = nil requestBody := request.Path if request.RawQuery != "" { requestBody += "\t" + request.UnescapedQuery() } requestBody += "\r\n" if _, err := conn.Write([]byte(requestBody)); err != nil { return nil, err } response, err := io.ReadAll(conn) if err != nil { return nil, err } return &gus.Response{Body: bytes.NewBuffer(response)}, nil }