package shortify import ( "bytes" "context" "errors" "io" "net" "net/http" "time" ) type ClientConfig struct { UseUnixSocket bool // true = unix socket, false = http SocketPath string // e.g. /tmp/shorty.sock HTTPAddress string // e.g. http://localhost:8080 Timeout time.Duration } type Client struct { httpClient *http.Client baseURL string } func NewClient(cfg ClientConfig) (*Client, error) { transport := &http.Transport{} if cfg.UseUnixSocket { dialer := func(_ context.Context, _, _ string) (net.Conn, error) { return net.Dial("unix", cfg.SocketPath) } transport.DialContext = dialer cfg.HTTPAddress = "http://unix" // dummy for request building } client := &http.Client{ Transport: transport, Timeout: cfg.Timeout, } return &Client{ httpClient: client, baseURL: cfg.HTTPAddress, }, nil } func (c *Client) Shorten(url string) (string, error) { body := []byte(url) req, err := http.NewRequest("POST", c.baseURL+"/s", bytes.NewReader(body)) if err != nil { return "", err } resp, err := c.httpClient.Do(req) if err != nil { return "", err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) return "", errors.New("shorten failed: " + string(b)) } result, err := io.ReadAll(resp.Body) if err != nil { return "", err } return string(result), nil }