diff options
author | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-06-30 14:49:58 +0200 |
---|---|---|
committer | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-07-15 17:35:23 +0200 |
commit | 3e4dc164a7a99f19c24accc64b15fb33c0bee1aa (patch) | |
tree | c28ec585f70ca4a06709577b3273652063ff5547 /lib/container_registry | |
parent | a3d8a7e6be2511ba9457a5045581de2b3ce80ab0 (diff) | |
download | gitlab-ce-3e4dc164a7a99f19c24accc64b15fb33c0bee1aa.tar.gz |
Explicitly remove authorization token and make sure that invalid addresses are properly handled
Diffstat (limited to 'lib/container_registry')
-rw-r--r-- | lib/container_registry/client.rb | 72 |
1 files changed, 35 insertions, 37 deletions
diff --git a/lib/container_registry/client.rb b/lib/container_registry/client.rb index 50ddf79601d..3dda60f607c 100644 --- a/lib/container_registry/client.rb +++ b/lib/container_registry/client.rb @@ -10,54 +10,41 @@ module ContainerRegistry # Taken from: FaradayMiddleware::FollowRedirects REDIRECT_CODES = Set.new [301, 302, 303, 307] - # Regex that matches characters that need to be escaped in URLs, sans - # the "%" character which we assume already represents an escaped sequence. - URI_UNSAFE = /[^\-_.!~*'()a-zA-Z\d;\/?:@&=+$,\[\]%]/ - def initialize(base_uri, options = {}) @base_uri = base_uri - @faraday = Faraday.new(@base_uri) do |conn| - initialize_connection(conn, options) - end + @options = options end def repository_tags(name) - response_body @faraday.get("/v2/#{name}/tags/list") + response_body faraday.get("/v2/#{name}/tags/list") end def repository_manifest(name, reference) - response_body @faraday.get("/v2/#{name}/manifests/#{reference}") + response_body faraday.get("/v2/#{name}/manifests/#{reference}") end def repository_tag_digest(name, reference) - response = @faraday.head("/v2/#{name}/manifests/#{reference}") + response = faraday.head("/v2/#{name}/manifests/#{reference}") response.headers['docker-content-digest'] if response.success? end def delete_repository_tag(name, reference) - @faraday.delete("/v2/#{name}/manifests/#{reference}").success? + faraday.delete("/v2/#{name}/manifests/#{reference}").success? end def blob(name, digest, type = nil) - headers = {} - headers['Accept'] = type if type - response_body @faraday.get("/v2/#{name}/blobs/#{digest}", nil, headers), allow_redirect: true + type ||= 'application/octet-stream' + response_body faraday_blob.get("/v2/#{name}/blobs/#{digest}", nil, 'Accept' => type), allow_redirect: true end def delete_blob(name, digest) - @faraday.delete("/v2/#{name}/blobs/#{digest}").success? + faraday.delete("/v2/#{name}/blobs/#{digest}").success? end - + private - + def initialize_connection(conn, options) conn.request :json - conn.headers['Accept'] = MANIFEST_VERSION - - conn.response :json, content_type: 'application/json' - conn.response :json, content_type: 'application/vnd.docker.distribution.manifest.v1+prettyjws' - conn.response :json, content_type: 'application/vnd.docker.distribution.manifest.v1+json' - conn.response :json, content_type: 'application/vnd.docker.distribution.manifest.v2+json' if options[:user] && options[:password] conn.request(:basic_auth, options[:user].to_s, options[:password].to_s) @@ -68,32 +55,43 @@ module ContainerRegistry conn.adapter :net_http end + def accept_manifest(conn) + conn.headers['Accept'] = MANIFEST_VERSION + + conn.response :json, content_type: 'application/json' + conn.response :json, content_type: 'application/vnd.docker.distribution.manifest.v1+prettyjws' + conn.response :json, content_type: 'application/vnd.docker.distribution.manifest.v1+json' + conn.response :json, content_type: 'application/vnd.docker.distribution.manifest.v2+json' + end + def response_body(response, allow_redirect: false) if allow_redirect && REDIRECT_CODES.include?(response.status) - response = redirect_response(response.env['url'], response.headers['location']) + response = redirect_response(response.headers['location']) end response.body if response && response.success? end - def redirect_response(url, location) + def redirect_response(location) return unless location - url += safe_escape(location) + # We explicitly remove authorization token + faraday_blob.get(location) do |req| + req['Authorization'] = '' + end + end - # We use HTTParty due to fact that @faraday contains internal authorization token - HTTParty.get(url) + def faraday + @faraday ||= Faraday.new(@base_uri) do |conn| + initialize_connection(conn, @options) + accept_manifest(conn) + end end - # Taken from: FaradayMiddleware::FollowRedirects - # Internal: escapes unsafe characters from an URL which might be a path - # component only or a fully qualified URI so that it can be joined onto an - # URI:HTTP using the `+` operator. Doesn't escape "%" characters so to not - # risk double-escaping. - def safe_escape(uri) - uri.to_s.gsub(URI_UNSAFE) { |match| - '%' + match.unpack('H2' * match.bytesize).join('%').upcase - } + def faraday_blob + @faraday_blob ||= Faraday.new(@base_uri) do |conn| + initialize_connection(conn, @options) + end end end end |