// Copyright 2024 Matthew Rich . All rights reserved. package transport import ( _ "errors" "io" _ "os" "net/http" "context" "log/slog" ) type HTTPConnection struct { stream *Pipe request *http.Request response *http.Response Client *http.Client } func NewHTTPConnection(client *http.Client) *HTTPConnection { return &HTTPConnection { Client: client, } } func (h *HTTPConnection) NewPostRequest(ctx context.Context, uri string) (err error) { h.stream = NewPipe() h.request, err = http.NewRequestWithContext(ctx, "POST", uri, h.Reader()) slog.Info("transport.HTTPConnection.NewPostRequest()", "stream", h.stream, "request", h.request) return } func (h *HTTPConnection) NewGetRequest(ctx context.Context, uri string) (err error) { h.request, err = http.NewRequestWithContext(ctx, "GET", uri, nil) return } func (h *HTTPConnection) Request() *http.Request { return h.request } func (h *HTTPConnection) Response() *http.Response { return h.response } func (h *HTTPConnection) Writer() io.WriteCloser { return h.stream.Writer } func (h *HTTPConnection) Reader() io.ReadCloser { return h.stream.Reader } func (h *HTTPConnection) Do() (err error) { slog.Info("transport.HTTPConnection.Do()", "connection", h, "request", h.request) h.response, err = h.Client.Do(h.request) return } func (h *HTTPConnection) Read(p []byte) (n int, err error) { slog.Info("transport.Read()", "request", h.request) if h.response == nil { if err = h.Do(); err != nil { return } } return h.response.Body.Read(p) } func (h *HTTPConnection) Write(p []byte) (n int, err error) { if h.response == nil { go func() { err = h.Do() }() if err != nil { return } } slog.Info("transport.HTTPConnection.Write()", "data", p, "connection", h) return h.Writer().Write(p) } func (h *HTTPConnection) ReadFrom(r io.Reader) (n int64, err error) { slog.Info("transport.ReadFrom()", "request", h.request) h.request.Body = r.(io.ReadCloser) if h.response == nil { if err = h.Do(); err != nil { return } } return h.request.ContentLength, nil } func (h *HTTPConnection) Close() (err error) { if h.response != nil { defer h.response.Body.Close() } if h.stream != nil { err = h.Writer().Close() } return }