diff options
author | tjp <tjp@ctrl-c.club> | 2023-11-13 07:27:36 -0700 |
---|---|---|
committer | tjp <tjp@ctrl-c.club> | 2023-11-13 07:27:36 -0700 |
commit | 629e6a0e0c3a24f35888036f957ee3a631e62816 (patch) | |
tree | 76001a2311d3566bf0050b3ef2aa3119fe0823bf /nex/client.go | |
parent | 1e0f8e0aaeaf1bd2ee39c02e922238b641bcf88b (diff) |
add nex protocol support
Diffstat (limited to 'nex/client.go')
-rw-r--r-- | nex/client.go | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/nex/client.go b/nex/client.go new file mode 100644 index 0000000..5f53746 --- /dev/null +++ b/nex/client.go @@ -0,0 +1,61 @@ +package nex + +import ( + "bytes" + "errors" + "io" + "net" + neturl "net/url" + + "tildegit.org/tjp/sliderule/internal/types" +) + +// Client is used for sending nex requests and reading 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 nex request and returns its response. +func (c Client) RoundTrip(request *types.Request) (*types.Response, error) { + if request.Scheme != "nex" && request.Scheme != "" { + return nil, errors.New("non-nex protocols not supported") + } + + host := request.Host + if _, port, _ := net.SplitHostPort(host); port == "" { + host = net.JoinHostPort(host, "1900") + } + + conn, err := net.Dial("tcp", host) + if err != nil { + return nil, err + } + defer conn.Close() + + request.RemoteAddr = conn.RemoteAddr() + request.TLSState = nil + + if _, err := conn.Write([]byte(request.Path + "\n")); err != nil { + return nil, err + } + + response, err := io.ReadAll(conn) + if err != nil { + return nil, err + } + + return &types.Response{Body: bytes.NewBuffer(response)}, nil +} + +// Fetch builds and sends a nex request, and returns the response. +func (c Client) Fetch(url string) (*types.Response, error) { + u, err := neturl.Parse(url) + if err != nil { + return nil, err + } + return c.RoundTrip(&types.Request{URL: u}) +} + +func (c Client) IsRedirect(response *types.Response) bool { return false } |