When getting the URL from a v2 registry url builder, it does not
honor the scheme from the endpoint object and will cause an https
endpoint to return urls starting with http.
Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
... | ... |
@@ -128,13 +128,28 @@ func (ub *URLBuilder) BuildBlobUploadChunkURL(name, uuid string, values ...url.V |
128 | 128 |
|
129 | 129 |
// clondedRoute returns a clone of the named route from the router. Routes |
130 | 130 |
// must be cloned to avoid modifying them during url generation. |
131 |
-func (ub *URLBuilder) cloneRoute(name string) *mux.Route { |
|
131 |
+func (ub *URLBuilder) cloneRoute(name string) clonedRoute { |
|
132 | 132 |
route := new(mux.Route) |
133 |
+ root := new(url.URL) |
|
134 |
+ |
|
133 | 135 |
*route = *ub.router.GetRoute(name) // clone the route |
136 |
+ *root = *ub.root |
|
137 |
+ |
|
138 |
+ return clonedRoute{Route: route, root: root} |
|
139 |
+} |
|
140 |
+ |
|
141 |
+type clonedRoute struct { |
|
142 |
+ *mux.Route |
|
143 |
+ root *url.URL |
|
144 |
+} |
|
145 |
+ |
|
146 |
+func (cr clonedRoute) URL(pairs ...string) (*url.URL, error) { |
|
147 |
+ routeURL, err := cr.Route.URL(pairs...) |
|
148 |
+ if err != nil { |
|
149 |
+ return nil, err |
|
150 |
+ } |
|
134 | 151 |
|
135 |
- return route. |
|
136 |
- Schemes(ub.root.Scheme). |
|
137 |
- Host(ub.root.Host) |
|
152 |
+ return cr.root.ResolveReference(routeURL), nil |
|
138 | 153 |
} |
139 | 154 |
|
140 | 155 |
// appendValuesURL appends the parameters to the url. |
... | ... |
@@ -6,62 +6,58 @@ import ( |
6 | 6 |
) |
7 | 7 |
|
8 | 8 |
type urlBuilderTestCase struct { |
9 |
- description string |
|
10 |
- expected string |
|
11 |
- build func() (string, error) |
|
9 |
+ description string |
|
10 |
+ expectedPath string |
|
11 |
+ build func() (string, error) |
|
12 | 12 |
} |
13 | 13 |
|
14 | 14 |
// TestURLBuilder tests the various url building functions, ensuring they are |
15 | 15 |
// returning the expected values. |
16 | 16 |
func TestURLBuilder(t *testing.T) { |
17 |
+ var ( |
|
18 |
+ urlBuilder *URLBuilder |
|
19 |
+ err error |
|
20 |
+ ) |
|
17 | 21 |
|
18 |
- root := "http://localhost:5000/" |
|
19 |
- urlBuilder, err := NewURLBuilderFromString(root) |
|
20 |
- if err != nil { |
|
21 |
- t.Fatalf("unexpected error creating urlbuilder: %v", err) |
|
22 |
- } |
|
23 |
- |
|
24 |
- for _, testcase := range []struct { |
|
25 |
- description string |
|
26 |
- expected string |
|
27 |
- build func() (string, error) |
|
28 |
- }{ |
|
22 |
+ testCases := []urlBuilderTestCase{ |
|
29 | 23 |
{ |
30 |
- description: "test base url", |
|
31 |
- expected: "http://localhost:5000/v2/", |
|
32 |
- build: urlBuilder.BuildBaseURL, |
|
24 |
+ description: "test base url", |
|
25 |
+ expectedPath: "/v2/", |
|
26 |
+ build: func() (string, error) { |
|
27 |
+ return urlBuilder.BuildBaseURL() |
|
28 |
+ }, |
|
33 | 29 |
}, |
34 | 30 |
{ |
35 |
- description: "test tags url", |
|
36 |
- expected: "http://localhost:5000/v2/foo/bar/tags/list", |
|
31 |
+ description: "test tags url", |
|
32 |
+ expectedPath: "/v2/foo/bar/tags/list", |
|
37 | 33 |
build: func() (string, error) { |
38 | 34 |
return urlBuilder.BuildTagsURL("foo/bar") |
39 | 35 |
}, |
40 | 36 |
}, |
41 | 37 |
{ |
42 |
- description: "test manifest url", |
|
43 |
- expected: "http://localhost:5000/v2/foo/bar/manifests/tag", |
|
38 |
+ description: "test manifest url", |
|
39 |
+ expectedPath: "/v2/foo/bar/manifests/tag", |
|
44 | 40 |
build: func() (string, error) { |
45 | 41 |
return urlBuilder.BuildManifestURL("foo/bar", "tag") |
46 | 42 |
}, |
47 | 43 |
}, |
48 | 44 |
{ |
49 |
- description: "build blob url", |
|
50 |
- expected: "http://localhost:5000/v2/foo/bar/blobs/tarsum.v1+sha256:abcdef0123456789", |
|
45 |
+ description: "build blob url", |
|
46 |
+ expectedPath: "/v2/foo/bar/blobs/tarsum.v1+sha256:abcdef0123456789", |
|
51 | 47 |
build: func() (string, error) { |
52 | 48 |
return urlBuilder.BuildBlobURL("foo/bar", "tarsum.v1+sha256:abcdef0123456789") |
53 | 49 |
}, |
54 | 50 |
}, |
55 | 51 |
{ |
56 |
- description: "build blob upload url", |
|
57 |
- expected: "http://localhost:5000/v2/foo/bar/blobs/uploads/", |
|
52 |
+ description: "build blob upload url", |
|
53 |
+ expectedPath: "/v2/foo/bar/blobs/uploads/", |
|
58 | 54 |
build: func() (string, error) { |
59 | 55 |
return urlBuilder.BuildBlobUploadURL("foo/bar") |
60 | 56 |
}, |
61 | 57 |
}, |
62 | 58 |
{ |
63 |
- description: "build blob upload url with digest and size", |
|
64 |
- expected: "http://localhost:5000/v2/foo/bar/blobs/uploads/?digest=tarsum.v1%2Bsha256%3Aabcdef0123456789&size=10000", |
|
59 |
+ description: "build blob upload url with digest and size", |
|
60 |
+ expectedPath: "/v2/foo/bar/blobs/uploads/?digest=tarsum.v1%2Bsha256%3Aabcdef0123456789&size=10000", |
|
65 | 61 |
build: func() (string, error) { |
66 | 62 |
return urlBuilder.BuildBlobUploadURL("foo/bar", url.Values{ |
67 | 63 |
"size": []string{"10000"}, |
... | ... |
@@ -70,15 +66,15 @@ func TestURLBuilder(t *testing.T) { |
70 | 70 |
}, |
71 | 71 |
}, |
72 | 72 |
{ |
73 |
- description: "build blob upload chunk url", |
|
74 |
- expected: "http://localhost:5000/v2/foo/bar/blobs/uploads/uuid-part", |
|
73 |
+ description: "build blob upload chunk url", |
|
74 |
+ expectedPath: "/v2/foo/bar/blobs/uploads/uuid-part", |
|
75 | 75 |
build: func() (string, error) { |
76 | 76 |
return urlBuilder.BuildBlobUploadChunkURL("foo/bar", "uuid-part") |
77 | 77 |
}, |
78 | 78 |
}, |
79 | 79 |
{ |
80 |
- description: "build blob upload chunk url with digest and size", |
|
81 |
- expected: "http://localhost:5000/v2/foo/bar/blobs/uploads/uuid-part?digest=tarsum.v1%2Bsha256%3Aabcdef0123456789&size=10000", |
|
80 |
+ description: "build blob upload chunk url with digest and size", |
|
81 |
+ expectedPath: "/v2/foo/bar/blobs/uploads/uuid-part?digest=tarsum.v1%2Bsha256%3Aabcdef0123456789&size=10000", |
|
82 | 82 |
build: func() (string, error) { |
83 | 83 |
return urlBuilder.BuildBlobUploadChunkURL("foo/bar", "uuid-part", url.Values{ |
84 | 84 |
"size": []string{"10000"}, |
... | ... |
@@ -86,15 +82,32 @@ func TestURLBuilder(t *testing.T) { |
86 | 86 |
}) |
87 | 87 |
}, |
88 | 88 |
}, |
89 |
- } { |
|
90 |
- u, err := testcase.build() |
|
89 |
+ } |
|
90 |
+ |
|
91 |
+ roots := []string{ |
|
92 |
+ "http://example.com", |
|
93 |
+ "https://example.com", |
|
94 |
+ "http://localhost:5000", |
|
95 |
+ "https://localhost:5443", |
|
96 |
+ } |
|
97 |
+ |
|
98 |
+ for _, root := range roots { |
|
99 |
+ urlBuilder, err = NewURLBuilderFromString(root) |
|
91 | 100 |
if err != nil { |
92 |
- t.Fatalf("%s: error building url: %v", testcase.description, err) |
|
101 |
+ t.Fatalf("unexpected error creating urlbuilder: %v", err) |
|
93 | 102 |
} |
94 | 103 |
|
95 |
- if u != testcase.expected { |
|
96 |
- t.Fatalf("%s: %q != %q", testcase.description, u, testcase.expected) |
|
104 |
+ for _, testCase := range testCases { |
|
105 |
+ url, err := testCase.build() |
|
106 |
+ if err != nil { |
|
107 |
+ t.Fatalf("%s: error building url: %v", testCase.description, err) |
|
108 |
+ } |
|
109 |
+ |
|
110 |
+ expectedURL := root + testCase.expectedPath |
|
111 |
+ |
|
112 |
+ if url != expectedURL { |
|
113 |
+ t.Fatalf("%s: %q != %q", testCase.description, url, expectedURL) |
|
114 |
+ } |
|
97 | 115 |
} |
98 | 116 |
} |
99 |
- |
|
100 | 117 |
} |