Skip to content

Commit 859afed

Browse files
committed
Store etags and utilise them, cleanup the ubunutu VersionAPI
Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com>
1 parent 2c774a3 commit 859afed

1 file changed

Lines changed: 26 additions & 8 deletions

File tree

vulnerabilities/importers/ubuntu.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
@dataclasses.dataclass
4444
class UbuntuConfiguration(DataSourceConfiguration):
4545
releases: list
46+
etags: dict
4647

4748

4849
class UbuntuDataSource(OvalDataSource):
@@ -62,15 +63,32 @@ def _fetch(self):
6263
file_name = 'com.ubuntu.{}.cve.oval.xml.bz2'
6364
releases = self.config.releases
6465
for release in releases:
65-
print("getting ", release)
66-
resp = requests.get(base_url + file_name.format(release))
66+
file_url = base_url + file_name.format(release)
67+
if not self.create_etag(file_url):
68+
continue
69+
resp = requests.get(file_url)
6770
extracted = bz2.decompress(resp.content)
68-
print("done ")
69-
yield ({'type': 'deb'}, ET.ElementTree(ET.fromstring(extracted.decode('utf-8'))))
71+
yield (
72+
{'type': 'deb', 'namespace': 'ubuntu'},
73+
ET.ElementTree(ET.fromstring(extracted.decode('utf-8')))
74+
)
7075

7176
def set_api(self, packages):
7277
asyncio.run(self.pkg_manager_api.load_api(packages))
7378

79+
def create_etag(self, url):
80+
81+
etag = requests.head(url).headers.get('ETag')
82+
if not etag:
83+
# Kind of inaccurate to return True since etag is
84+
# not created
85+
return True
86+
elif url in self.config.etags:
87+
if self.config.etags[url] == etag:
88+
return False
89+
self.config.etags[url] = etag
90+
return True
91+
7492

7593
class VersionAPI:
7694
def __init__(self, cache: Mapping[str, Set[str]] = None):
@@ -80,13 +98,13 @@ def get(self, package_name: str) -> Set[str]:
8098
return self.cache[package_name]
8199

82100
async def load_api(self, pkg_set):
83-
# This is debatable
84-
timeout = ClientTimeout(total=None)
85-
async with ClientSession(raise_for_status=True, timeout=timeout) as session:
101+
async with ClientSession(raise_for_status=True) as session:
86102
await asyncio.gather(*[self.set_api(pkg, session)
87103
for pkg in pkg_set if pkg not in self.cache])
88104

89105
async def set_api(self, pkg, session):
106+
if pkg in self.cache:
107+
return
90108
url = ('https://api.launchpad.net/1.0/ubuntu/+archive/'
91109
'primary?ws.op=getPublishedSources&'
92110
'source_name={}&exact_match=true'.format(pkg))
@@ -105,5 +123,5 @@ async def set_api(self, pkg, session):
105123
else:
106124
break
107125
self.cache[pkg] = all_versions
108-
except ClientResponseError:
126+
except (ClientResponseError, asyncio.exceptions.TimeoutError):
109127
self.cache[pkg] = {}

0 commit comments

Comments
 (0)