~antmak/duplicity/0.7-par2-fix

« back to all changes in this revision

Viewing changes to duplicity/backends/webdavbackend.py

  • Committer: Michael Terry
  • Date: 2014-04-28 02:49:39 UTC
  • mto: This revision was merged to the branch mainline in revision 981.
  • Revision ID: michael.terry@canonical.com-20140428024939-p2fbckcm35uh0ogs
further fixes

Show diffs side-by-side

added added

removed removed

Lines of Context:
82
82
            # create new socket
83
83
            sock = socket.create_connection((self.host, self.port),
84
84
                                            self.timeout)
85
 
            if self._tunnel_host:
 
85
            if self.tunnel_host:
86
86
                self.sock = sock
87
 
                self._tunnel()
 
87
                self.tunnel()
88
88
 
89
89
            # wrap the socket in ssl using verification
90
90
            self.sock = ssl.wrap_socket(sock,
125
125
 
126
126
        self.username = parsed_url.username
127
127
        self.password = self.get_password()
128
 
        self.directory = self._sanitize_path(parsed_url.path)
 
128
        self.directory = self.sanitize_path(parsed_url.path)
129
129
 
130
130
        log.Info("Using WebDAV protocol %s" % (globals.webdav_proto,))
131
131
        log.Info("Using WebDAV host %s port %s" % (parsed_url.hostname, parsed_url.port))
133
133
 
134
134
        self.conn = None
135
135
 
136
 
    def _sanitize_path(self,path):
 
136
    def sanitize_path(self,path):
137
137
        if path:
138
138
            foldpath = re.compile('/+')
139
139
            return foldpath.sub('/', path + '/' )
140
140
        else:
141
141
            return '/'
142
142
 
143
 
    def _getText(self,nodelist):
 
143
    def getText(self,nodelist):
144
144
        rc = ""
145
145
        for node in nodelist:
146
146
            if node.nodeType == node.TEXT_NODE:
147
147
                rc = rc + node.data
148
148
        return rc
149
149
 
150
 
    def _connect(self, forced=False):
 
150
    def _retry_cleanup(self):
 
151
        self.connect(forced=True)
 
152
 
 
153
    def connect(self, forced=False):
151
154
        """
152
155
        Connect or re-connect to the server, updates self.conn
153
156
        # reconnect on errors as a precaution, there are errors e.g.
154
157
        # "[Errno 32] Broken pipe" or SSl errors that render the connection unusable
155
158
        """
156
 
        if self.retry_count<=1 and self.conn \
 
159
        if not forced and self.conn \
157
160
            and self.conn.host == self.parsed_url.hostname: return
158
161
 
159
 
        log.Info("WebDAV create connection on '%s' (retry %s) " % (self.parsed_url.hostname,self.retry_count) )
 
162
        log.Info("WebDAV create connection on '%s'" % (self.parsed_url.hostname))
160
163
        if self.conn: self.conn.close()
161
164
        # http schemes needed for redirect urls from servers
162
165
        if self.parsed_url.scheme in ['webdav','http']:
177
180
        Wraps the connection.request method to retry once if authentication is
178
181
        required
179
182
        """
180
 
        self._connect()
 
183
        self.connect()
181
184
 
182
185
        quoted_path = urllib.quote(path,"/:~")
183
186
 
198
201
                if redirected > 10:
199
202
                    raise FatalBackendException("WebDAV redirected 10 times. Giving up.")
200
203
                self.parsed_url = duplicity.backend.ParsedUrl(redirect_url)
201
 
                self.directory = self._sanitize_path(self.parsed_url.path)
 
204
                self.directory = self.sanitize_path(self.parsed_url.path)
202
205
                return self.request(method,self.directory,data,redirected+1)
203
206
            else:
204
207
                raise FatalBackendException("WebDAV missing location header in redirect response.")
285
288
            dom = xml.dom.minidom.parseString(document)
286
289
            result = []
287
290
            for href in dom.getElementsByTagName('d:href') + dom.getElementsByTagName('D:href'):
288
 
                filename = self.__taste_href(href)
 
291
                filename = self.taste_href(href)
289
292
                if filename:
290
293
                    result.append(filename)
291
294
            return result
304
307
        for i in range(1,len(dirs)):
305
308
            d="/".join(dirs[0:i+1])+"/"
306
309
 
307
 
            self.close() # or we get previous request's data or exception
 
310
            self._close() # or we get previous request's data or exception
308
311
            self.headers['Depth'] = "1"
309
312
            response = self.request("PROPFIND", d)
310
313
            del self.headers['Depth']
313
316
 
314
317
            if response.status == 404:
315
318
                log.Info("Creating missing directory %s" % d)
316
 
                self.close() # or we get previous request's data or exception
 
319
                self._close() # or we get previous request's data or exception
317
320
 
318
321
                res = self.request("MKCOL", d)
319
322
                if res.status != 201:
320
323
                    raise BackendException("WebDAV MKCOL %s failed: %s %s" % (d,res.status,res.reason))
321
 
                self.close()
 
324
                self._close()
322
325
 
323
 
    def __taste_href(self, href):
 
326
    def taste_href(self, href):
324
327
        """
325
328
        Internal helper to taste the given href node and, if
326
329
        it is a duplicity file, collect it as a result file.
327
330
 
328
331
        @return: A matching filename, or None if the href did not match.
329
332
        """
330
 
        raw_filename = self._getText(href.childNodes).strip()
 
333
        raw_filename = self.getText(href.childNodes).strip()
331
334
        parsed_url = urlparse.urlparse(urllib.unquote(raw_filename))
332
335
        filename = parsed_url.path
333
336
        log.Debug("webdav path decoding and translation: "