103 lines
2.2 KiB
Go
103 lines
2.2 KiB
Go
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. 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
|
||
|
}
|