-
Notifications
You must be signed in to change notification settings - Fork 81
/
common.go
127 lines (111 loc) · 3.02 KB
/
common.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package manifest
import (
"net/http"
"strconv"
"strings"
// crypto libraries included for go-digest
_ "crypto/sha256"
_ "crypto/sha512"
digest "github.com/opencontainers/go-digest"
"github.com/regclient/regclient/types"
"github.com/regclient/regclient/types/descriptor"
"github.com/regclient/regclient/types/errs"
"github.com/regclient/regclient/types/ref"
)
type common struct {
r ref.Ref
desc descriptor.Descriptor
manifSet bool
ratelimit types.RateLimit
rawHeader http.Header
rawBody []byte
}
// GetDigest returns the digest
func (m *common) GetDigest() digest.Digest {
return m.desc.Digest
}
// GetDescriptor returns the descriptor
func (m *common) GetDescriptor() descriptor.Descriptor {
return m.desc
}
// GetMediaType returns the media type
func (m *common) GetMediaType() string {
return m.desc.MediaType
}
// GetRateLimit returns the rate limit when the manifest was pulled from a registry.
// This supports the headers used by Docker Hub.
func (m *common) GetRateLimit() types.RateLimit {
return m.ratelimit
}
// GetRef returns the reference from the upstream registry
func (m *common) GetRef() ref.Ref {
return m.r
}
// HasRateLimit indicates if the rate limit is set
func (m *common) HasRateLimit() bool {
return m.ratelimit.Set
}
// IsList indicates if the manifest is a docker Manifest List or OCI Index
func (m *common) IsList() bool {
switch m.desc.MediaType {
case MediaTypeDocker2ManifestList, MediaTypeOCI1ManifestList:
return true
default:
return false
}
}
// IsSet indicates if the manifest is defined.
// A false indicates this is from a HEAD request, providing the digest, media-type, and other headers, but no body.
func (m *common) IsSet() bool {
return m.manifSet
}
// RawBody returns the raw body from the manifest if available.
func (m *common) RawBody() ([]byte, error) {
if len(m.rawBody) == 0 {
return m.rawBody, errs.ErrManifestNotSet
}
return m.rawBody, nil
}
// RawHeaders returns any headers included when manifest was pulled from a registry.
func (m *common) RawHeaders() (http.Header, error) {
return m.rawHeader, nil
}
func (m *common) setRateLimit(header http.Header) {
// check for rate limit headers
rlLimit := header.Get("RateLimit-Limit")
rlRemain := header.Get("RateLimit-Remaining")
rlReset := header.Get("RateLimit-Reset")
if rlLimit != "" {
lpSplit := strings.Split(rlLimit, ",")
lSplit := strings.Split(lpSplit[0], ";")
rlLimitI, err := strconv.Atoi(lSplit[0])
if err != nil {
m.ratelimit.Limit = 0
} else {
m.ratelimit.Limit = rlLimitI
}
if len(lSplit) > 1 {
m.ratelimit.Policies = lpSplit
} else if len(lpSplit) > 1 {
m.ratelimit.Policies = lpSplit[1:]
}
}
if rlRemain != "" {
rSplit := strings.Split(rlRemain, ";")
rlRemainI, err := strconv.Atoi(rSplit[0])
if err != nil {
m.ratelimit.Remain = 0
} else {
m.ratelimit.Remain = rlRemainI
m.ratelimit.Set = true
}
}
if rlReset != "" {
rlResetI, err := strconv.Atoi(rlReset)
if err != nil {
m.ratelimit.Reset = 0
} else {
m.ratelimit.Reset = rlResetI
}
}
}