mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
For methods using the decodeWithRaw utility, we were handling closing of the body twice. The ensureReaderClosed utility also drains the response to let the transport reuse the connnection. Let's use that utility in decodeWithRaw as well. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
87 lines
2.0 KiB
Go
87 lines
2.0 KiB
Go
package client
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
|
|
cerrdefs "github.com/containerd/errdefs"
|
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
)
|
|
|
|
type emptyIDError string
|
|
|
|
func (e emptyIDError) InvalidParameter() {}
|
|
|
|
func (e emptyIDError) Error() string {
|
|
return "invalid " + string(e) + " name or ID: value is empty"
|
|
}
|
|
|
|
// trimID trims the given object-ID / name, returning an error if it's empty.
|
|
func trimID(objType, id string) (string, error) {
|
|
id = strings.TrimSpace(id)
|
|
if id == "" {
|
|
return "", emptyIDError(objType)
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
// encodePlatforms marshals the given platform(s) to JSON format, to
|
|
// be used for query-parameters for filtering / selecting platforms.
|
|
func encodePlatforms(platform ...ocispec.Platform) ([]string, error) {
|
|
if len(platform) == 0 {
|
|
return []string{}, nil
|
|
}
|
|
if len(platform) == 1 {
|
|
p, err := encodePlatform(&platform[0])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return []string{p}, nil
|
|
}
|
|
|
|
seen := make(map[string]struct{}, len(platform))
|
|
out := make([]string, 0, len(platform))
|
|
for i := range platform {
|
|
p, err := encodePlatform(&platform[i])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if _, ok := seen[p]; !ok {
|
|
out = append(out, p)
|
|
seen[p] = struct{}{}
|
|
}
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
// encodePlatform marshals the given platform to JSON format, to
|
|
// be used for query-parameters for filtering / selecting platforms. It
|
|
// is used as a helper for encodePlatforms,
|
|
func encodePlatform(platform *ocispec.Platform) (string, error) {
|
|
p, err := json.Marshal(platform)
|
|
if err != nil {
|
|
return "", fmt.Errorf("%w: invalid platform: %v", cerrdefs.ErrInvalidArgument, err)
|
|
}
|
|
return string(p), nil
|
|
}
|
|
|
|
func decodeWithRaw[T any](resp *http.Response, out *T) (raw json.RawMessage, _ error) {
|
|
if resp == nil || resp.Body == nil {
|
|
return nil, errors.New("empty response")
|
|
}
|
|
defer ensureReaderClosed(resp)
|
|
|
|
var buf bytes.Buffer
|
|
tr := io.TeeReader(resp.Body, &buf)
|
|
err := json.NewDecoder(tr).Decode(out)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return buf.Bytes(), nil
|
|
}
|