152
// decodeLink decodes the Nexus-Link header values.
153
// It must have the same format of HTTP Link header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link
154
>
func decodeLink(encodedLink string) (nexus.Link, error) {
api.go
155
>
var link nexus.Link
156
>
encodedLink = strings.TrimSpace(encodedLink)
157
>
if len(encodedLink) == 0 {
158
return link, errors.New("failed to parse link header: value is empty")
159
}
160
161
>
if encodedLink[0] != '<' {
api.go
162
return link, fmt.Errorf("failed to parse link header: invalid format: %s", encodedLink)
163
}
164
>
urlEnd := strings.Index(encodedLink, ">")
api.go
165
>
if urlEnd == -1 {
166
return link, fmt.Errorf("failed to parse link header: invalid format: %s", encodedLink)
167
}
168
>
urlStr := strings.TrimSpace(encodedLink[1:urlEnd])
api.go
169
>
if len(urlStr) == 0 {
170
return link, errors.New("failed to parse link header: url is empty")
171
}
172
>
u, err := url.Parse(urlStr)
api.go
173
>
if err != nil {
174
return link, fmt.Errorf("failed to parse link header: invalid url: %s", urlStr)
175
}
176
>
if err := validateLinkURL(u); err != nil {
api.go
177
return link, fmt.Errorf("failed to parse link header: %w", err)
178
}
180
>
181
>
params := strings.Split(encodedLink[urlEnd+1:], ";")
182
>
// must contain at least one semi-colon, and first param must be empty since
183
>
// it corresponds to the url part parsed above.
184
>
if len(params) < 2 {
185
return link, fmt.Errorf("failed to parse link header: invalid format: %s", encodedLink)
186
}
187
>
if strings.TrimSpace(params[0]) != "" {
api.go
188
return link, fmt.Errorf("failed to parse link header: invalid format: %s", encodedLink)
189
}
190
191
>
typeKeyFound := false
api.go
192
>
for _, param := range params[1:] {
193
>
param = strings.TrimSpace(param)
194
>
if len(param) == 0 {
195
return link, fmt.Errorf("failed to parse link header: parameter is empty: %s", encodedLink)
196
}
197
>
kv := strings.SplitN(param, "=", 2)
api.go
198
>
if len(kv) != 2 {
199
return link, fmt.Errorf("failed to parse link header: invalid parameter format: %s", param)
200
}
201
>
key := strings.TrimSpace(kv[0])
api.go
202
>
val := strings.TrimSpace(kv[1])
203
>
if strings.HasPrefix(val, `"`) != strings.HasSuffix(val, `"`) {
204
return link, fmt.Errorf(
205
"failed to parse link header: parameter value missing double-quote: %s",