Initial QSfera import
This commit is contained in:
+81
@@ -0,0 +1,81 @@
|
||||
package icapclient
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Client represents the ICAP client who makes the ICAP server calls.
|
||||
type Client struct {
|
||||
config Config // Store config for connection parameters
|
||||
}
|
||||
|
||||
// NewClient creates a new ICAP client (no persistent connection).
|
||||
func NewClient(options ...ConfigOption) (Client, error) {
|
||||
config := DefaultConfig()
|
||||
for _, option := range options {
|
||||
option(&config)
|
||||
}
|
||||
return Client{config: config}, nil
|
||||
}
|
||||
|
||||
// Do make the ICAP request, creating and dropping a connection each time.
|
||||
func (c Client) Do(req Request) (res Response, err error) {
|
||||
conn, err := NewICAPConn(c.config.ICAPConn)
|
||||
if err != nil {
|
||||
return Response{}, err
|
||||
}
|
||||
|
||||
if err := conn.Connect(req.ctx, req.URL.Host); err != nil {
|
||||
return Response{}, err
|
||||
}
|
||||
defer func() {
|
||||
err = errors.Join(err, conn.Close())
|
||||
}()
|
||||
|
||||
req.setDefaultRequestHeaders()
|
||||
|
||||
message, err := toICAPRequest(req)
|
||||
if err != nil {
|
||||
return Response{}, err
|
||||
}
|
||||
|
||||
// send the ICAP message to the server
|
||||
dataRes, err := conn.Send(message)
|
||||
if err != nil {
|
||||
return Response{}, err
|
||||
}
|
||||
|
||||
res, err = toClientResponse(bufio.NewReader(strings.NewReader(string(dataRes))))
|
||||
if err != nil {
|
||||
return Response{}, err
|
||||
}
|
||||
|
||||
// check if the message is fully done scanning or if it needs to be sent another chunk.
|
||||
done := !(res.StatusCode == http.StatusContinue && !req.bodyFittedInPreview && req.previewSet)
|
||||
if done {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// get the remaining body bytes.
|
||||
data := req.remainingPreviewBytes
|
||||
if !bodyIsChunked(string(data)) {
|
||||
data = []byte(addHexBodyByteNotations(string(data)))
|
||||
}
|
||||
|
||||
// hydrate the ICAP message with closing doubleCRLF suffix.
|
||||
if !bytes.HasSuffix(data, []byte(doubleCRLF)) {
|
||||
data = append(data, []byte(crlf)...)
|
||||
}
|
||||
|
||||
// send the remaining body bytes to the server.
|
||||
dataRes, err = conn.Send(data)
|
||||
if err != nil {
|
||||
return Response{}, err
|
||||
}
|
||||
|
||||
return toClientResponse(bufio.NewReader(strings.NewReader(string(dataRes))))
|
||||
}
|
||||
Reference in New Issue
Block a user