142
144
return "git/Breezy/%s" % breezy_version
147
def is_github_url(url):
148
(scheme, user, password, host, port,
149
path) = urlutils.parse_url(url)
150
return host in ("github.com", "gopkg.in")
145
153
class RemoteGitProber(Prober):
156
def priority(klass, transport):
157
# This is a surprisingly good heuristic to determine whether this
158
# prober is more likely to succeed than the Bazaar one.
159
if 'git' in transport.base:
147
163
def probe_http_transport(self, transport):
148
from .. import urlutils
149
base_url, _ = urlutils.split_segment_parameters(
150
transport.external_url())
151
url = urlutils.join(base_url, "info/refs") + "?service=git-upload-pack"
152
from ..transport.http import Request
164
# This function intentionally doesn't use any of the support code under
165
# breezy.git, since it's called for every repository that's
166
# accessed over HTTP, whether it's Git, Bzr or something else.
167
# Importing Dulwich and the other support code adds unnecessray slowdowns.
168
base_url = urlutils.strip_segment_parameters(transport.external_url())
169
url = urlutils.URL.from_string(base_url)
170
url.user = url.quoted_user = None
171
url.password = url.quoted_password = None
173
url = urlutils.join(str(url), "info/refs") + "?service=git-upload-pack"
153
174
headers = {"Content-Type": "application/x-git-upload-pack-request",
154
175
"Accept": "application/x-git-upload-pack-result",
156
req = Request('GET', url, accepted_errors=[200, 403, 404, 405],
158
(scheme, user, password, host, port,
159
path) = urlutils.parse_url(req.get_full_url())
160
if host == "github.com":
177
if is_github_url(url):
161
178
# GitHub requires we lie.
162
179
# https://github.com/dulwich/dulwich/issues/562
163
req.add_header("User-Agent", user_agent_for_github())
164
elif host == "bazaar.launchpad.net":
165
# Don't attempt Git probes against bazaar.launchpad.net; pad.lv/1744830
166
raise brz_errors.NotBranchError(transport.base)
167
resp = transport._perform(req)
168
if resp.code in (404, 405):
169
raise brz_errors.NotBranchError(transport.base)
170
headers = resp.headers
171
ct = headers.get("Content-Type")
173
raise brz_errors.NotBranchError(transport.base)
174
if ct.startswith("application/x-git"):
180
headers["User-Agent"] = user_agent_for_github()
181
resp = transport.request('GET', url, headers=headers)
182
if resp.status in (404, 405):
183
raise brz_errors.NotBranchError(transport.base)
184
elif resp.status == 400 and resp.reason == 'no such method: info':
186
raise brz_errors.NotBranchError(transport.base)
187
elif resp.status != 200:
188
raise brz_errors.UnexpectedHttpStatus(url, resp.status)
190
ct = resp.getheader("Content-Type")
191
if ct and ct.startswith("application/x-git"):
175
192
from .remote import RemoteGitControlDirFormat
176
193
return RemoteGitControlDirFormat()
178
195
from .dir import (
179
196
BareLocalGitControlDirFormat,
181
198
ret = BareLocalGitControlDirFormat()
182
199
ret._refs_text = resp.read()
201
raise brz_errors.NotBranchError(transport.base)
185
203
def probe_transport(self, transport):