def request(self, method, uri, headers=None, data=None): #print(method, uri) now = time.gmtime(time.time()) datetime = time.strftime("%Y%m%dT%H%M%SZ", now) date = time.strftime("%Y%m%d", now) if headers is None: headers = [] headers[:0] = [ ("Host", self.host), ("Date", datetime), ("x-amz-glacier-version", "2012-06-01"), ] if data is not None: headers.append(("Content-Length", str(len(data)))) headers.append(("x-amz-content-sha256", hashlib.sha256(data).hexdigest())) headers.append(("x-amz-sha256-tree-hash", sha256tree.treehash(data).hexdigest())) canonical_request, signed_headers = make_canonical_request(method, uri, headers, data=data) string_to_sign = make_string_to_sign(datetime, date, "us-east-1", "glacier", canonical_request) #print(repr(canonical_request)) #print(repr(string_to_sign)) headers.append(("Authorization", make_authorization_header(self.access, self.secret, date, "us-east-1", "glacier", signed_headers, string_to_sign))) req = urllib.request.Request("https://{}/{}".format(self.host, uri), headers=dict(headers)) req.get_method = lambda: method try: r = urllib.request.urlopen(req, data) except urllib.error.HTTPError as x: r = x.read().decode("UTF-8") e = json.loads(r) raise GlacierError(x.code, e["code"], e["message"], e["type"]) from x return r
def test_treehash(): for x in [0, 1, 1000, 1048575, 1048576, 1048577, 6815744, 10485760, 9999999]: data = open("/dev/urandom", "rb").read(x) assert len(data) == x sh = sha256tree.treehash_simple(data).digest() fh = sha256tree.treehash(data).digest() assert fh == sh, x th = sha256tree.TreeHash() while data: part = data[:random.randrange(2*1048576+1)] th.update(part) data = data[len(part):] ph = th.finish().digest() assert ph == sh, x