[Git][security-tracker-team/security-tracker][helmutg/web-adapter] web tracker: refactor service class hierarchy
Helmut Grohne (@helmutg)
helmutg at debian.org
Tue Aug 11 12:27:37 BST 2026
Helmut Grohne pushed to branch helmutg/web-adapter at Debian Security Tracker / security-tracker
Commits:
69566480 by Helmut Grohne at 2026-08-11T13:27:25+02:00
web tracker: refactor service class hierarchy
The hierarchy was weird. The lowest level is WebServiceBase and mainly
is a URL router. From there we go to WebServiceHTTP (and earlier also
WebService) implementing the network facing side. Then TrackerService
inherits from one of the services. Until WebService was removed, the
class hierarchy was dependent on command line arguments. This is a
coding smell of using a wrong pattern.
The ability to swap out the base class of TrackerService hints at it not
integrating tightly with its direct base class. Indeed, the
TrackerService doesn't need to know anything about how requests arrive
at the url router or are delivered from there. We can reparent it to
WebServiceBase with little loss. What is lost in the process is the
ability to actually service any requests.
The former base class WebServiceHTTP needs to reenter the picture
somehow. The WebServiceHTTP does not directly interface with
TrackerService as all of the interaction is handled via the
WebServiceBase URL router. Instead of inheriting from WebServiceBase,
WebServiceHTTP can be passed a WebServiceBase instance and redirect some
attribute lookups. In effect, we replace inheritance with composition.
To reflect this, I also rename WebServiceHTTP to WebServiceHTTPAdapter.
This results in the class hierarchy becoming static. Even if WebService
were not removed yet, TrackerService would only inherit from
WebServiceBase. Consequently, the caller of TrackerService now has to
separately instantiate WebServiceHTTPAdapter and in doing so can choose
the adapter without changing the class hierarchy.
The real goal behind this refactoring is the ability to provide more
adapter classes. Thus we can experiment with another adapter supporting
HTTP/1.1 without interfering with the existing deployment. In
particular, it seems possible to adapt the service to WSGI which opens a
door to a lot of deployment strategies.
- - - - -
2 changed files:
- bin/tracker_service.py
- lib/python/web_support.py
Changes:
=====================================
bin/tracker_service.py
=====================================
@@ -98,7 +98,8 @@ class BugFilter:
"""Returns True for postponedissues if filtered."""
return no_dsa_reason == 'postponed' and not self.params['nopostponed']
-class TrackerService(WebServiceHTTP):
+
+class TrackerService(WebServiceBase):
nvd_text = P('''If a "**" is included, the urgency field was automatically
assigned by the NVD (National Vulnerability Database). Note that this
rating is automatically derived from a set of known factors about the
@@ -107,8 +108,8 @@ class TrackerService(WebServiceHTTP):
determining the values of these factors, but the rating itself comes
from a fully automated formula.''')
- def __init__(self, socket_name, db_name):
- WebServiceHTTP.__init__(self, socket_name)
+ def __init__(self, db_name):
+ WebServiceBase.__init__(self)
self.db = security_db.DB(db_name)
self.stable_releases = config.get_supported_releases()
@@ -1526,4 +1527,4 @@ Debian bug number.'''),
return SPAN(contents, _class="dangerous")
if __name__ == "__main__":
- TrackerService(socket_name, db_name).run()
+ WebServiceHTTPAdapter(TrackerService(db_name), socket_name).run()
=====================================
lib/python/web_support.py
=====================================
@@ -618,33 +618,31 @@ class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
RE_BASE_URL = re.compile(r'^(https?)://([^/]+)(.*)')
-class WebServiceHTTP(WebServiceBase):
- def __init__(self, socket_name):
- WebServiceBase.__init__(self)
+
+class WebServiceHTTPAdapter:
+ def __init__(self, service: WebServiceBase, socket_name):
+ self.service = service
(base_url, address, port) = socket_name
self.lock = threading.Lock()
self.__parse_base_url(base_url)
- service_self = self
+ adapter_self = self
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
(method, path, remaining, params) = self.route()
if path is None:
return
- url = URLFactory(service_self.server_name,
- service_self.script_name,
+ url = URLFactory(adapter_self.service.server_name,
+ adapter_self.service.script_name,
path, params,
- secure=service_self.secure)
+ secure=adapter_self.service.secure)
- service_self.lock.acquire()
- try:
+ with adapter_self.lock:
r = method(remaining, params, url)
assert isinstance(r, Result), repr(r)
result = r.flatten_later()
- finally:
- service_self.lock.release()
result(self)
do_HEAD = do_GET
@@ -660,14 +658,14 @@ class WebServiceHTTP(WebServiceBase):
def route(self):
(path, params) = self.__parse_path()
- prefix_len = len(service_self.script_name)
+ prefix_len = len(adapter_self.service.script_name)
prefix = path[0:prefix_len]
result = None
- if prefix == service_self.script_name:
+ if prefix == adapter_self.service.script_name:
suffix = path[prefix_len:]
try:
(method, remaining) = \
- service_self.router.get(suffix)
+ adapter_self.service.router.get(suffix)
return (method, suffix, remaining, params)
except InvalidPath:
pass
@@ -683,9 +681,9 @@ class WebServiceHTTP(WebServiceBase):
m = RE_BASE_URL.match(url)
if m is None:
raise ValueError("invalid base URL: " + url)
- self.secure = m.group(1) == "https"
- self.server_name = m.group(2)
- self.script_name = m.group(3)
+ self.service.secure = m.group(1) == "https"
+ self.service.server_name = m.group(2)
+ self.service.script_name = m.group(3)
def __test():
View it on GitLab: https://salsa.debian.org/security-tracker-team/security-tracker/-/commit/695664807342b9ff3ccd1d44113694abebcefa3f
--
View it on GitLab: https://salsa.debian.org/security-tracker-team/security-tracker/-/commit/695664807342b9ff3ccd1d44113694abebcefa3f
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-security-tracker-commits/attachments/20260811/99f05030/attachment-0001.htm>
More information about the debian-security-tracker-commits
mailing list