~jflaker/duplicity/BugFix1325215

« back to all changes in this revision

Viewing changes to duplicity/backends/webdavbackend.py

  • Committer: Kenneth Loafman
  • Date: 2014-04-25 15:03:00 UTC
  • Revision ID: kenneth@loafman.com-20140425150300-uegwmjrnnehmgqm4
* Fixed bug #1312328 WebDAV backend can't understand 200 OK response to DELETE
  - Allow both 200 and 204 as valid response to delete

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
                import socket, ssl
56
56
            except ImportError:
57
57
                raise FatalBackendError("Missing socket or ssl libraries.")
58
 
            
 
58
 
59
59
            httplib.HTTPSConnection.__init__(self, *args, **kwargs)
60
 
            
 
60
 
61
61
            self.cacert_file = globals.ssl_cacert_file
62
62
            cacert_candidates = [ "~/.duplicity/cacert.pem", \
63
63
                             "~/duplicity_cacert.pem", \
64
64
                             "/etc/duplicity/cacert.pem" ]
65
 
            # 
 
65
            #
66
66
            if not self.cacert_file:
67
67
                for path in cacert_candidates :
68
68
                    path = os.path.expanduser(path)
72
72
            # still no cacert file, inform user
73
73
            if not self.cacert_file:
74
74
                raise FatalBackendError("""For certificate verification a cacert database file is needed in one of these locations: %s
75
 
Hints: 
76
 
  Consult the man page, chapter 'SSL Certificate Verification'. 
 
75
Hints:
 
76
  Consult the man page, chapter 'SSL Certificate Verification'.
77
77
  Consider using the options --ssl-cacert-file, --ssl-no-check-certificate .""" % ", ".join(cacert_candidates) )
78
78
            # check if file is accessible (libssl errors are not very detailed)
79
79
            if not os.access(self.cacert_file, os.R_OK):
92
92
                                        cert_reqs=ssl.CERT_REQUIRED,
93
93
                                        ca_certs=self.cacert_file,
94
94
                                        )
95
 
        
 
95
 
96
96
        def request(self, *args, **kwargs):
97
97
            try:
98
98
                return httplib.HTTPSConnection.request(self, *args, **kwargs)
147
147
            if node.nodeType == node.TEXT_NODE:
148
148
                rc = rc + node.data
149
149
        return rc
150
 
    
 
150
 
151
151
    def _connect(self, forced=False):
152
152
        """
153
153
        Connect or re-connect to the server, updates self.conn
154
 
        # reconnect on errors as a precaution, there are errors e.g. 
 
154
        # reconnect on errors as a precaution, there are errors e.g.
155
155
        # "[Errno 32] Broken pipe" or SSl errors that render the connection unusable
156
156
        """
157
157
        if self.retry_count<=1 and self.conn \
158
158
            and self.conn.host == self.parsed_url.hostname: return
159
 
        
 
159
 
160
160
        log.Info("WebDAV create connection on '%s' (retry %s) " % (self.parsed_url.hostname,self.retry_count) )
161
161
        if self.conn: self.conn.close()
162
162
        # http schemes needed for redirect urls from servers
212
212
            self.conn.request(method, quoted_path, data, self.headers)
213
213
            response = self.conn.getresponse()
214
214
            log.Info("WebDAV response2 status %s with reason '%s'." % (response.status,response.reason))
215
 
        
 
215
 
216
216
        return response
217
217
 
218
218
 
301
301
    def makedir(self):
302
302
        """Make (nested) directories on the server."""
303
303
        dirs = self.directory.split("/")
304
 
        # url causes directory to start with /, but it might be given 
 
304
        # url causes directory to start with /, but it might be given
305
305
        # with or without trailing / (which is required)
306
306
        if dirs[-1] == '':
307
307
            dirs=dirs[0:-1]
308
308
        for i in range(1,len(dirs)):
309
309
            d="/".join(dirs[0:i+1])+"/"
310
 
       
311
 
            self.close() # or we get previous request's data or exception       
 
310
 
 
311
            self.close() # or we get previous request's data or exception
312
312
            self.headers['Depth'] = "1"
313
313
            response = self.request("PROPFIND", d)
314
314
            del self.headers['Depth']
317
317
 
318
318
            if response.status == 404:
319
319
                log.Info("Creating missing directory %s" % d)
320
 
                self.close() # or we get previous request's data or exception   
 
320
                self.close() # or we get previous request's data or exception
321
321
 
322
322
                res = self.request("MKCOL", d)
323
323
                if res.status != 201:
421
421
            response = None
422
422
            try:
423
423
                response = self.request("DELETE", url)
424
 
                if response.status == 204:
 
424
                if response.status in [200, 204]:
425
425
                    response.read()
426
426
                    response.close()
427
427
                else: