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