Rev 4559: (mbp) workaround for ftp servers without APPE in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Wed Jul 22 11:01:39 BST 2009
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 4559 [merge]
revision-id: pqm at pqm.ubuntu.com-20090722100136-z7hpflqttygepstr
parent: pqm at pqm.ubuntu.com-20090722090335-m1okio1ev9bwytui
parent: mbp at sourcefrog.net-20090722075750-qrysvi0t3lk7ixhz
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2009-07-22 11:01:36 +0100
message:
(mbp) workaround for ftp servers without APPE
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/transport/ftp/__init__.py ftp.py-20051116161804-58dc9506548c2a53
=== modified file 'NEWS'
--- a/NEWS 2009-07-22 06:00:45 +0000
+++ b/NEWS 2009-07-22 10:01:36 +0000
@@ -48,6 +48,10 @@
* ``bzr revert .`` no longer generates an InconsistentDelta error when
there are missing subtrees. (Robert Collins, #367632)
+* Cope with FTP servers that don't support restart/append by falling back
+ to reading and then rewriting the whole file, such as TahoeLAFS. (This
+ fallback may be slow for some access patterns.) (Nils Durner, #294709)
+
* Fixed a NameError that occurs when merging or pulling from a URL that
causes a redirection loop when bzr tries to read a URL as a bundle.
(Andrew Bennetts, #400847)
=== modified file 'bzrlib/transport/ftp/__init__.py'
--- a/bzrlib/transport/ftp/__init__.py 2009-04-27 16:10:10 +0000
+++ b/bzrlib/transport/ftp/__init__.py 2009-07-22 06:51:13 +0000
@@ -99,6 +99,9 @@
self.is_active = True
else:
self.is_active = False
+
+ # Most modern FTP servers support the APPE command. If ours doesn't, we (re)set this flag accordingly later.
+ self._has_append = True
def _get_FTP(self):
"""Return the ftplib.FTP instance for this object."""
@@ -387,6 +390,8 @@
"""Append the text in the file-like object into the final
location.
"""
+ text = f.read()
+
abspath = self._remote_path(relpath)
if self.has(relpath):
ftp = self._get_FTP()
@@ -394,8 +399,11 @@
else:
result = 0
- mutter("FTP appe to %s", abspath)
- self._try_append(relpath, f.read(), mode)
+ if self._has_append:
+ mutter("FTP appe to %s", abspath)
+ self._try_append(relpath, text, mode)
+ else:
+ self._fallback_append(relpath, text, mode)
return result
@@ -416,8 +424,16 @@
self._setmode(relpath, mode)
ftp.getresp()
except ftplib.error_perm, e:
- self._translate_perm_error(e, abspath, extra='error appending',
- unknown_exc=errors.NoSuchFile)
+ # Check whether the command is not supported (reply code 502)
+ if str(e).startswith('502 '):
+ warning("FTP server does not support file appending natively. " \
+ "Performance may be severely degraded! (%s)", e)
+ self._has_append = False
+ self._fallback_append(relpath, text, mode)
+ else:
+ self._translate_perm_error(e, abspath, extra='error appending',
+ unknown_exc=errors.NoSuchFile)
+
except ftplib.error_temp, e:
if retries > _number_of_retries:
raise errors.TransportError("FTP temporary error during APPEND %s." \
@@ -427,6 +443,13 @@
self._reconnect()
self._try_append(relpath, text, mode, retries+1)
+ def _fallback_append(self, relpath, text, mode = None):
+ remote = self.get(relpath)
+ remote.seek(0, 2)
+ remote.write(text)
+ remote.seek(0, 0)
+ return self.put_file(relpath, remote, mode)
+
def _setmode(self, relpath, mode):
"""Set permissions on a path.
More information about the bazaar-commits
mailing list