From a3a1f8c0d4d0b6b7657c94513a2d42b5a8337e34 Mon Sep 17 00:00:00 2001 From: Stephane Bortzmeyer Date: Wed, 7 Jul 2021 11:13:36 +0200 Subject: [PATCH] Lock the cache file --- ianardap.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/ianardap.py b/ianardap.py index a718bc5..6e976d4 100644 --- a/ianardap.py +++ b/ianardap.py @@ -12,6 +12,7 @@ import datetime import json import os import sys +import fcntl IANABASE = "https://data.iana.org/rdap/dns.json" CACHE = os.environ["HOME"] + "/.ianardapcache.json" @@ -22,7 +23,9 @@ class IanaRDAPDatabase(): def __init__(self, maxage=MAXAGE, cachefile=CACHE): """ Retrieves the IANA databse, if not already cached. maxage is in hours. """ cache_valid = False - # TODO we should lock it + self.cachefile = cachefile + self.lockname = self.cachefile + ".lock" + self.lock() if os.path.exists(cachefile) and \ datetime.datetime.fromtimestamp(os.path.getmtime(cachefile)) >= \ (datetime.datetime.utcnow() - datetime.timedelta(hours = maxage)): @@ -30,7 +33,9 @@ class IanaRDAPDatabase(): content = cache.read() cache.close() cache_valid = True + self.unlock() else: + self.unlock() response = requests.get(IANABASE) if response.status_code != 200: raise Exception("Invalid HTTPS return code when trying to get %s: %s" % (IANABASE, response.status_code)) @@ -45,11 +50,20 @@ class IanaRDAPDatabase(): for server in service[1]: self.services[tld] = server if not cache_valid: - # TODO we should lock it + self.lock() cache = open(cachefile, "wb") cache.write(content) cache.close() + self.unlock() + def lock(self): + self.lockhandle = open(self.lockname, 'w') + fcntl.lockf(self.lockhandle, fcntl.LOCK_EX) + + def unlock(self): + fcntl.lockf(self.lockhandle, fcntl.LOCK_UN) + self.lockhandle.close() + def find(self, domain): """ Get the RDAP server for a given domain name. None if there is none.""" labels = domain.split(".")