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
|
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package azuredevops
import "strconv"
func negotiateRequestVersion(location *ApiResourceLocation, apiVersion string) (string, error) {
if apiVersion == "" {
// if no api-version is sent to the server, the server will decide the version. The server uses the latest
// released version if the endpoint has been released, otherwise it will use the latest preview version.
return apiVersion, nil
}
matches := apiVersionRegEx.FindStringSubmatch(apiVersion)
if len(matches) == 0 && matches[0] != "" {
return apiVersion, &InvalidApiVersion{apiVersion}
}
requestedApiVersion, err := NewVersion(matches[1])
if err != nil {
return apiVersion, err
}
locationMinVersion, err := NewVersion(*location.MinVersion)
if err != nil {
return apiVersion, err
}
if locationMinVersion.CompareTo(*requestedApiVersion) > 0 {
// Client is older than the server. The server no longer supports this
// resource (deprecated).
return apiVersion, nil
} else {
locationMaxVersion, err := NewVersion(*location.MaxVersion)
if err != nil {
return apiVersion, err
}
if locationMaxVersion.CompareTo(*requestedApiVersion) < 0 {
// Client is newer than the server. Negotiate down to the latest version
// on the server
negotiatedVersion := string(*location.MaxVersion)
if *location.ReleasedVersion < *location.MaxVersion {
negotiatedVersion += "-preview"
}
return negotiatedVersion, nil
} else {
// We can send at the requested api version. Make sure the resource version
// is not bigger than what the server supports
negotiatedVersion := matches[1]
if len(matches) > 3 && matches[3] != "" { // matches '-preview'
negotiatedVersion += "-preview"
if len(matches) > 5 && matches[5] != "" { // has a resource version
requestedResourceVersion, _ := strconv.Atoi(matches[5])
if *location.ResourceVersion < requestedResourceVersion {
negotiatedVersion += "." + strconv.Itoa(*location.ResourceVersion)
} else {
negotiatedVersion += "." + matches[5]
}
}
} else {
// requesting released version, ensure server supports a released version, and if not append '-preview'
locationReleasedVersion, err := NewVersion(*location.ReleasedVersion)
if err != nil {
return apiVersion, err
}
if (locationReleasedVersion.Major == 0 && locationReleasedVersion.Minor == 0) || locationReleasedVersion.CompareTo(*requestedApiVersion) < 0 {
negotiatedVersion += "-preview"
}
}
return negotiatedVersion, nil
}
}
}
|