| 286 | |
| 287 | def _forests_do_cmd(self, cmd, **args): |
| 288 | data = args.pop('data', None) |
| 289 | headers = args.pop('headers', {}) |
| 290 | self.ui.debug("sending %s command\n" % cmd) |
| 291 | q = {"cmd": cmd} |
| 292 | q.update(args) |
| 293 | qs = '?%s' % urllib.urlencode(q) |
| 294 | cu = "%s%s" % (self._url, qs) |
| 295 | req = urllib2.Request(cu, data, headers) |
| 296 | if data is not None: |
| 297 | # len(data) is broken if data doesn't fit into Py_ssize_t |
| 298 | # add the header ourself to avoid OverflowError |
| 299 | size = data.__len__() |
| 300 | self.ui.debug("sending %s bytes\n" % size) |
| 301 | req.add_unredirected_header('Content-Length', '%d' % size) |
| 302 | try: |
| 303 | resp = self.urlopener.open(req) |
| 304 | except urllib2.HTTPError, inst: |
| 305 | if inst.code == 401: |
| 306 | raise util.Abort(_('authorization failed')) |
| 307 | raise |
| 308 | except httplib.HTTPException, inst: |
| 309 | self.ui.debug('http error while sending %s command\n' % cmd) |
| 310 | self.ui.traceback() |
| 311 | raise IOError(None, inst) |
| 312 | except IndexError: |
| 313 | # this only happens with Python 2.3, later versions raise URLError |
| 314 | raise util.Abort(_('http error, possibly caused by proxy setting')) |
| 315 | # record the url we got redirected to |
| 316 | resp_url = resp.geturl() |
| 317 | if resp_url.endswith(qs): |
| 318 | resp_url = resp_url[:-len(qs)] |
| 319 | if self._url.rstrip('/') != resp_url.rstrip('/'): |
| 320 | self.ui.status(_('real URL is %s\n') % resp_url) |
| 321 | self._url = resp_url |
| 322 | try: |
| 323 | proto = resp.getheader('content-type') |
| 324 | except AttributeError: |
| 325 | proto = resp.headers['content-type'] |
| 326 | |
| 327 | safeurl = url.hidepassword(self._url) |
| 328 | # accept old "text/plain" and "application/hg-changegroup" for now |
| 329 | if not (proto.startswith('application/mercurial-') or |
| 330 | proto.startswith('text/plain') or |
| 331 | proto.startswith('application/hg-changegroup')): |
| 332 | self.ui.debug("requested URL: '%s'\n" % url.hidepassword(cu)) |
| 333 | raise error.RepoError( |
| 334 | _("'%s' does not appear to be an hg repository:\n" |
| 335 | "---%%<--- (%s)\n%s\n---%%<---\n") |
| 336 | % (safeurl, proto, resp.read())) |
| 337 | |
| 338 | if proto.startswith('application/mercurial-'): |
| 339 | try: |
| 340 | version = proto.split('-', 1)[1] |
| 341 | version_info = tuple([int(n) for n in version.split('.')]) |
| 342 | except ValueError: |
| 343 | raise error.RepoError(_("'%s' sent a broken Content-Type " |
| 344 | "header (%s)") % (safeurl, proto)) |
| 345 | if version_info > (0, 1): |
| 346 | raise error.RepoError(_("'%s' uses newer protocol %s") % |
| 347 | (safeurl, version)) |
| 348 | |
| 349 | return resp |
| 350 | |
| 351 | httprepo.httprepository.do_cmd = _forests_do_cmd |
| 352 | |
| 353 | |
| 354 | |
| 355 | def _forests_do_read(self, cmd, **args): |
| 356 | fp = self.do_cmd(cmd, **args) |
| 357 | try: |
| 358 | return fp.read() |
| 359 | finally: |
| 360 | # if using keepalive, allow connection to be reused |
| 361 | fp.close() |
| 362 | |
| 363 | httprepo.httprepository.do_read = _forests_do_read |
| 364 | |
| 365 | |
| 366 | |