Kiln » Kiln Extensions
Clone URL:  
httpstore.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
'''HTTP-based store.''' import urlparse import urllib2 from mercurial import util, url as url_ from mercurial.i18n import _ import bfutil, basestore class httpstore(basestore.basestore): """A store accessed via HTTP""" def __init__(self, ui, repo, url): url = bfutil.urljoin(url, 'bfile') super(httpstore, self).__init__(ui, repo, url) self.rawurl, self.path = urlparse.urlsplit(self.url)[1:3] (baseurl, authinfo) = url_.getauthinfo(self.url) self.opener = url_.opener(self.ui, authinfo) def put(self, source, hash): self.sendfile(source, hash) self.ui.debug('put %s to remote store\n' % source) def exists(self, hash): return self._verify(hash) def sendfile(self, filename, hash): if self._verify(hash): return self.ui.debug('httpstore.sendfile(%s, %s)\n' % (filename, hash)) baseurl, authinfo = url_.getauthinfo(self.url) fd = None try: fd = url_.httpsendfile(filename, 'rb') request = urllib2.Request(bfutil.urljoin(baseurl, hash), fd) try: url = self.opener.open(request) self.ui.note(_('[OK] %s/%s\n') % (self.rawurl, url.geturl())) except urllib2.HTTPError, e: raise util.Abort(_('unable to POST: %s\n') % e.msg) except Exception, e: raise util.Abort(_('%s') % e) finally: if fd: fd.close() def _getfile(self, tmpfile, filename, hash): (baseurl, authinfo) = url_.getauthinfo(self.url) url = bfutil.urljoin(baseurl, hash) try: request = urllib2.Request(url) infile = self.opener.open(request) except urllib2.HTTPError, err: detail = _("HTTP error: %s %s") % (err.code, err.msg) raise basestore.StoreError(filename, hash, url, detail) except urllib2.URLError, err: # This usually indicates a connection problem, so don't # keep trying with the other files... they will probably # all fail too. reason = err[0][1] # assumes err[0] is a socket.error raise util.Abort('%s: %s' % (baseurl, reason)) return bfutil.copy_and_hash(bfutil.blockstream(infile), tmpfile) def _verify(self, hash): baseurl, authinfo = url_.getauthinfo(self.url) store_path = bfutil.urljoin(baseurl, hash) request = urllib2.Request(store_path) request.add_header('SHA1-Request', hash) try: url = self.opener.open(request) if 'Content-SHA1' in url.info() and hash == url.info()['Content-SHA1']: return True else: return False except: return False def _verifyfile(self, cctx, cset, contents, standin, verified): baseurl, authinfo = url_.getauthinfo(self.url) filename = bfutil.split_standin(standin) if not filename: return False fctx = cctx[standin] key = (filename, fctx.filenode()) if key in verified: return False expect_hash = fctx.data()[0:40] store_path = bfutil.urljoin(baseurl, expect_hash) verified.add(key) request = urllib2.Request(store_path) request.add_header('SHA1-Request',expect_hash) try: url = self.opener.open(request) if 'Content-SHA1' in url.info(): rhash = url.info()['Content-SHA1'] if rhash == expect_hash: return False else: self.ui.warn( _('changeset %s: %s: contents differ\n (%s)\n') % (cset, filename, store_path)) return True # failed else: self.ui.warn(_('remote did not send a hash, ' 'it probably does not understand this protocol\n')) return False except urllib2.HTTPError, e: if e.code == 404: self.ui.warn( _('changeset %s: %s missing\n (%s)\n') % (cset, filename, store_path)) return True # failed else: raise util.Abort(_('check failed, unexpected response' 'status: %d: %s') % (e.code, e.msg))