Invalid content-type when importing a repository from SCM Manager
Summary
When importing a project new project > project import > repository by URL
from SCM Manager customer get's an error in the UI while the field validates the URL:
After some digging it appears that the the SCM manager responds with incorrect content type.
data = { :url => "https://SCM-REPO_URL", :user => "USERNAME", :passwo
rd => "PASSWORD" }
Import::ValidateRemoteGitEndpointService.new(data).execute
=> #<ServiceResponse:0x00007f084e709218 @http_status=nil, @message="Not a git repository: Invalid content-type", @payload={}, @reason=nil, @status=:error>
It appear the reason this fails is that when you add the SCM URL in the field in GitLab, the SCM manager sends an incorrect response during the validation whether the URL is actually a Git repo. The URL that is being used here is "http://SCM-MANAGER:8080/scm/repo/scmadmin/test/info/refs?service=git-upload-pack" to check whether this is a git repository.
Once this request is sent to the SCM manager to validate the URL it responds with the content-type: text/html;charset=utf-8
or Content-Type: application/json; charset=utf-8
it was different for me and the cutsomer and GitLab expects application/x-git-upload-pack-advertisement
TEST FOR THE SCM MANAGER:
uri = Gitlab::Utils.parse_url("http://SCM-MANAGER:8080/scm/repo/scmadmin/test.git")
url = Gitlab::Utils.append_path(uri.to_s, "/info/refs?service=#{GIT_SERVICE_NAME}")
response_body = ""
Gitlab::HTTP.get(url, stream_body: true, follow_redirects: false, basic_auth: { username: "scmadmin", password: "PASSWORD" }) do |response_chunk|
response = response_chunk
puts response.http_response['content-type']
response_body += response_chunk
puts response_body
break if GIT_MINIMUM_RESPONSE_LENGTH <= response_body.length
end
text/html;charset=utf-8
TEST FOR ANOTHER GITLAB INSTANCE:
uri = Gitlab::Utils.parse_url("http://gitlab.example.com/root/test.git")
url = Gitlab::Utils.append_path(uri.to_s, "/info/refs?service=#{GIT_SERVICE_NAME}")
Gitlab::HTTP.get(url, stream_body: true, follow_redirects: false, basic_auth: { username: "root", password: "PASSWORD" }) do |response_chunk|
response = response_chunk
puts response.http_response['content-type']
response_body += response_chunk
puts response_body
break if GIT_MINIMUM_RESPONSE_LENGTH <= response_body.length
end
application/x-git-upload-pack-advertisement
Customer had stated that this worked fine before.
I have tried using username and password in the URL as well , however that did not help.
https://USERNAME:PASSWORD@SCM-MANAGER:8080/repository/path.git
Steps to reproduce
Do a import repository from URL from the SCM manager https://scm-manager.org/
Results of GitLab environment info
VERSION GitLab 16.7.3
Proposed solution
We should change the user agent in Import::ValidateRemoteGitEndpointService
. Ideally we'd find some way to keep the user agent value in sync with the version of git that we actually use. Maybe we can use Gitlab::Git::Version
/ Gitaly::Server.all.first.git_binary_version
for this.