Safer handling of Accept headers #84
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,12 +14,15 @@ def test_invalid_repo_name(self): | |
self.assertEqual(parsed_response_data['errors'][0]['message'], 'Not Found') | ||
|
||
def test_valid_repo_name_for_manifest(self): | ||
headers = {'Accept': 'application/vnd.docker.distribution.manifest.v2+json'} | ||
response = self.test_client.get('/v2/redhat/foo/manifests/1.25.1-musl', headers=headers) | ||
# #3303: verify multi-valued headers too | ||
# manifest lists are evaluated first, so pass a longer media type that | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you elaborate more on this please? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code first checks if manifest_list_mediatype is in accept_headers. If the client sent a string that includes 'application/vnd.docker.distribution.manifest.list.v2+json like in my +junk test, as well as a valid manifest v2 media type, then you'd get a false match for a manifest list. |
||
# matches the manifest list as a prefix | ||
headers = {'Accept': 'application/vnd.docker.distribution.manifest.list.v2+jsonjunk,application/vnd.docker.distribution.manifest.v2+json'} # noqa | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i don't think +jsonjunk would be a valid mediatype sent from docker client :) max what you can have is +json or +prettyjws There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's with a civilized client. As a server, you should always check the inputs from the client. This is not a realistic example, just like this patch is not fixing something broken now. |
||
response = self.test_client.get('/v2/redhat/zoo/manifests/1.25.1-musl', headers=headers) | ||
|
||
self.assertEqual(response.status_code, 302) | ||
self.assertTrue(response.headers['Content-Type'].startswith('text/html')) | ||
self.assertTrue('foo/bar/manifests/2' in response.headers['Location']) | ||
self.assertTrue('zoo/bar/manifests/2/1.25.1-musl' in response.headers['Location']) | ||
|
||
def test_valid_repo_name_for_manifest_list(self): | ||
headers = {'Accept': 'application/vnd.docker.distribution.manifest.list.v2+json'} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import mock | ||
import unittest2 | ||
|
||
from crane.views import v2 | ||
|
||
|
||
class UtilTest(unittest2.TestCase): | ||
def test_get_accept_headers(self): | ||
tests = [ | ||
(dict(), set()), | ||
(dict(Accept="a"), set(["a"])), | ||
(dict(Accept="a, b"), set(["a", "b"])), | ||
(dict(Accept="a,b"), set(["a", "b"])), | ||
(dict(Accept=" a , b "), set(["a", "b"])), | ||
(dict(Accept="a; q=1, b"), set(["a", "b"])), | ||
] | ||
req = mock.MagicMock() | ||
for headers, expected in tests: | ||
req.headers = headers | ||
self.assertEquals(expected, v2.get_accept_headers(req)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add doc block
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.