aboutsummaryrefslogtreecommitdiff
path: root/rpki/http.py
diff options
context:
space:
mode:
Diffstat (limited to 'rpki/http.py')
-rw-r--r--rpki/http.py137
1 files changed, 52 insertions, 85 deletions
diff --git a/rpki/http.py b/rpki/http.py
index 64af0d4d..7127bbde 100644
--- a/rpki/http.py
+++ b/rpki/http.py
@@ -282,26 +282,6 @@ class http_response(http_message):
def __repr__(self):
return rpki.log.log_repr(self, self.code, self.reason)
-# This probably ought to be using logging.LoggerAdapter or some such,
-# and the level check should be converted to whatever the natural
-# thing is with the logging package, but for now just preserve the old
-# structure for now while transitioning from our homegrown logging
-# code to Python logging package.
-#
-# So it turns out that, as used in the current code, all invocations
-# of this are either with the default logging.DEBUG or with
-# logging.WARNING, we don't use any other settings. This suggets that
-# we could clean up this mess and get rid of the extra argument just
-# by providing two methods instead of one, assuming that the
-# LoggingAdapter doesn't just solve the whole problem for us.
-
-def log_method(self, msg, level = logging.DEBUG):
- """
- Logging method used in several different classes.
- """
- if debug_http or level > logging.DEBUG:
- logging.log(level, "%r: %s", self, msg)
-
def addr_to_string(addr):
"""
Convert socket addr tuple to printable string. Assumes 2-element
@@ -320,8 +300,6 @@ class http_stream(asynchat.async_chat):
Virtual class representing an HTTP message stream.
"""
- log = log_method
-
def __repr__(self):
status = ["connected"] if self.connected else []
try:
@@ -331,6 +309,7 @@ class http_stream(asynchat.async_chat):
return rpki.log.log_repr(self, *status)
def __init__(self, sock = None):
+ self.logger = logging.LoggerAdapter(logger, dict(context = self))
asynchat.async_chat.__init__(self, sock)
self.buffer = []
self.timer = rpki.async.timer(self.handle_timeout)
@@ -352,10 +331,10 @@ class http_stream(asynchat.async_chat):
it.
"""
if self.timeout is not None:
- self.log("Setting timeout %s" % self.timeout)
+ self.logger.debug("Setting timeout %s" % self.timeout)
self.timer.set(self.timeout)
else:
- self.log("Clearing timeout")
+ self.logger.debug("Clearing timeout")
self.timer.cancel()
def collect_incoming_data(self, data):
@@ -414,7 +393,7 @@ class http_stream(asynchat.async_chat):
the process of exiting the chunk decoder.
"""
n = int(self.get_buffer().partition(";")[0], 16)
- self.log("Chunk length %s" % n)
+ self.logger.debug("Chunk length %s" % n)
if n:
self.chunk_handler = self.chunk_body
self.set_terminator(n)
@@ -428,7 +407,7 @@ class http_stream(asynchat.async_chat):
body of a chunked message (sic). Save it, and prepare to move on
to the next chunk.
"""
- self.log("Chunk body")
+ self.logger.debug("Chunk body")
self.msg.body += self.buffer
self.buffer = []
self.chunk_handler = self.chunk_discard_crlf
@@ -439,7 +418,7 @@ class http_stream(asynchat.async_chat):
Consume the CRLF that terminates a chunk, reinitialize chunk
decoder to be ready for the next chunk.
"""
- self.log("Chunk CRLF")
+ self.logger.debug("Chunk CRLF")
s = self.get_buffer()
assert s == "", "%r: Expected chunk CRLF, got '%s'" % (self, s)
self.chunk_handler = self.chunk_header
@@ -449,7 +428,7 @@ class http_stream(asynchat.async_chat):
Consume chunk trailer, which should be empty, then (finally!) exit
the chunk decoder and hand complete message off to the application.
"""
- self.log("Chunk trailer")
+ self.logger.debug("Chunk trailer")
s = self.get_buffer()
assert s == "", "%r: Expected end of chunk trailers, got '%s'" % (self, s)
self.chunk_handler = None
@@ -472,16 +451,15 @@ class http_stream(asynchat.async_chat):
etype = sys.exc_info()[0]
if etype in (SystemExit, rpki.async.ExitNow):
raise
- rpki.log.traceback(logger)
if etype is not rpki.exceptions.HTTPClientAborted:
- self.log("Closing due to error", logging.WARNING)
+ self.logger.exception("Closing due to error")
self.close()
def handle_timeout(self):
"""
Inactivity timer expired, close connection with prejudice.
"""
- self.log("Timeout, closing")
+ self.logger.debug("Timeout, closing")
self.close()
def handle_close(self):
@@ -489,7 +467,7 @@ class http_stream(asynchat.async_chat):
Wrapper around asynchat connection close handler, so that we can
log the event, cancel timer, and so forth.
"""
- self.log("Close event in HTTP stream handler")
+ self.logger.debug("Close event in HTTP stream handler")
self.timer.cancel()
asynchat.async_chat.handle_close(self)
@@ -510,7 +488,7 @@ class http_server(http_stream):
self.handlers = handlers
http_stream.__init__(self, sock = sock)
self.expect_close = not want_persistent_server
- self.log("Starting")
+ self.logger.debug("Starting")
def handle_no_content_length(self):
"""
@@ -536,7 +514,7 @@ class http_server(http_stream):
Content-Type, look for a handler, and if everything looks right,
pass the message body, path, and a reply callback to the handler.
"""
- self.log("Received request %r" % self.msg)
+ self.logger.debug("Received request %r" % self.msg)
if not self.msg.persistent:
self.expect_close = True
handler = self.find_handler(self.msg.path)
@@ -553,7 +531,7 @@ class http_server(http_stream):
except (rpki.async.ExitNow, SystemExit):
raise
except Exception, e:
- rpki.log.traceback(logger)
+ self.logger.exception("Unhandled exception while handling HTTP request")
self.send_error(500, reason = "Unhandled exception %s: %s" % (e.__class__.__name__, e))
else:
self.send_error(code = error[0], reason = error[1])
@@ -577,7 +555,7 @@ class http_server(http_stream):
listen for next message; otherwise, queue up a close event for
this stream so it will shut down once the reply has been sent.
"""
- self.log("Sending response %s %s" % (code, reason))
+ self.logger.debug("Sending response %s %s" % (code, reason))
if code >= 400:
self.expect_close = True
msg = http_response(code = code, reason = reason, body = body,
@@ -585,11 +563,11 @@ class http_server(http_stream):
Connection = "Close" if self.expect_close else "Keep-Alive")
self.push(msg.format())
if self.expect_close:
- self.log("Closing")
+ self.logger.debug("Closing")
self.timer.cancel()
self.close_when_done()
else:
- self.log("Listening for next message")
+ self.logger.debug("Listening for next message")
self.restart()
class http_listener(asyncore.dispatcher):
@@ -597,8 +575,6 @@ class http_listener(asyncore.dispatcher):
Listener for incoming HTTP connections.
"""
- log = log_method
-
def __repr__(self):
try:
status = (addr_to_string(self.addr),)
@@ -607,6 +583,7 @@ class http_listener(asyncore.dispatcher):
return rpki.log.log_repr(self, *status)
def __init__(self, handlers, addrinfo):
+ self.logger = logging.LoggerAdapter(logger, dict(context = self))
asyncore.dispatcher.__init__(self)
self.handlers = handlers
try:
@@ -622,11 +599,10 @@ class http_listener(asyncore.dispatcher):
self.bind(sockaddr)
self.listen(5)
except Exception, e:
- self.log("Couldn't set up HTTP listener: %s" % e, logging.WARNING)
- rpki.log.traceback(logger)
+ self.logger.exception("Couldn't set up HTTP listener")
self.close()
for h in handlers:
- self.log("Handling %s" % h[0])
+ self.logger.debug("Handling %s" % h[0])
def handle_accept(self):
"""
@@ -635,12 +611,12 @@ class http_listener(asyncore.dispatcher):
"""
try:
s, c = self.accept()
- self.log("Accepting connection from %s" % addr_to_string(c))
+ self.logger.debug("Accepting connection from %s" % addr_to_string(c))
http_server(sock = s, handlers = self.handlers)
except (rpki.async.ExitNow, SystemExit):
raise
except Exception, e:
- self.log("Unable to accept connection: %s" % e)
+ self.logger.debug("Unable to accept connection: %s" % e)
self.handle_error()
def handle_error(self):
@@ -649,8 +625,7 @@ class http_listener(asyncore.dispatcher):
"""
if sys.exc_info()[0] in (SystemExit, rpki.async.ExitNow):
raise
- self.log("Error in HTTP listener", logging.WARNING)
- rpki.log.traceback(logger)
+ self.logger.exception("Error in HTTP listener")
class http_client(http_stream):
"""
@@ -670,8 +645,8 @@ class http_client(http_stream):
state = None
def __init__(self, queue, hostport):
- self.log("Creating new connection to %s" % addr_to_string(hostport))
http_stream.__init__(self)
+ self.logger.debug("Creating new connection to %s" % addr_to_string(hostport))
self.queue = queue
self.host = hostport[0]
self.port = hostport[1]
@@ -683,14 +658,14 @@ class http_client(http_stream):
Create socket and request a connection.
"""
if not use_adns:
- self.log("Not using ADNS")
+ self.logger.debug("Not using ADNS")
self.gotaddrinfo([(socket.AF_INET, self.host)])
elif self.host == "localhost":
- self.log("Bypassing DNS for localhost")
+ self.logger.debug("Bypassing DNS for localhost")
self.gotaddrinfo(localhost_addrinfo())
else:
families = supported_address_families(enable_ipv6_clients)
- self.log("Starting ADNS lookup for %s in families %r" % (self.host, families))
+ self.logger.debug("Starting ADNS lookup for %s in families %r" % (self.host, families))
rpki.adns.getaddrinfo(self.gotaddrinfo, self.dns_error, self.host, families)
def dns_error(self, e):
@@ -706,7 +681,7 @@ class http_client(http_stream):
"""
try:
self.af, self.address = random.choice(addrinfo)
- self.log("Connecting to AF %s host %s port %s addr %s" % (self.af, self.host, self.port, self.address))
+ self.logger.debug("Connecting to AF %s host %s port %s addr %s" % (self.af, self.host, self.port, self.address))
self.create_socket(self.af, socket.SOCK_STREAM)
self.connect((self.address, self.port))
if self.addr is None:
@@ -721,7 +696,7 @@ class http_client(http_stream):
"""
Asyncore says socket has connected.
"""
- self.log("Socket connected")
+ self.logger.debug("Socket connected")
self.set_state("idle")
assert self.queue.client is self
self.queue.send_request()
@@ -730,7 +705,7 @@ class http_client(http_stream):
"""
Set HTTP client connection state.
"""
- self.log("State transition %s => %s" % (self.state, state))
+ self.logger.debug("State transition %s => %s" % (self.state, state))
self.state = state
def handle_no_content_length(self):
@@ -746,7 +721,7 @@ class http_client(http_stream):
"""
Queue up request message and kickstart connection.
"""
- self.log("Sending request %r" % msg)
+ self.logger.debug("Sending request %r" % msg)
assert self.state == "idle", "%r: state should be idle, is %s" % (self, self.state)
self.set_state("request-sent")
msg.headers["Connection"] = "Close" if self.expect_close else "Keep-Alive"
@@ -763,7 +738,7 @@ class http_client(http_stream):
arrange for the stream to shut down.
"""
- self.log("Message received, state %s" % self.state)
+ self.logger.debug("Message received, state %s" % self.state)
if not self.msg.persistent:
self.expect_close = True
@@ -771,16 +746,16 @@ class http_client(http_stream):
if self.state != "request-sent":
if self.state == "closing":
assert not self.msg.body
- self.log("Ignoring empty response received while closing")
+ self.logger.debug("Ignoring empty response received while closing")
return
raise rpki.exceptions.HTTPUnexpectedState, "%r received message while in unexpected state %s" % (self, self.state)
if self.expect_close:
- self.log("Closing")
+ self.logger.debug("Closing")
self.set_state("closing")
self.close_when_done()
else:
- self.log("Idling")
+ self.logger.debug("Idling")
self.set_state("idle")
self.update_timeout()
@@ -803,7 +778,7 @@ class http_client(http_stream):
sent, signal the error.
"""
http_stream.handle_close(self)
- self.log("State %s" % self.state)
+ self.logger.debug("State %s" % self.state)
if self.get_terminator() is None:
self.handle_body()
elif self.state == "request-sent":
@@ -818,7 +793,7 @@ class http_client(http_stream):
"""
bad = self.state not in ("idle", "closing")
if bad:
- self.log("Timeout while in state %s" % self.state, logging.WARNING)
+ self.logger.warning("Timeout while in state %s" % self.state)
http_stream.handle_timeout(self)
if bad:
try:
@@ -834,7 +809,7 @@ class http_client(http_stream):
down the connection and pass back the exception.
"""
eclass, edata = sys.exc_info()[0:2]
- self.log("Error on HTTP client connection %s:%s %s %s" % (self.host, self.port, eclass, edata), logging.WARNING)
+ self.logger.warning("Error on HTTP client connection %s:%s %s %s" % (self.host, self.port, eclass, edata))
http_stream.handle_error(self)
self.queue.return_result(self, edata, detach = True)
@@ -845,22 +820,21 @@ class http_queue(object):
stream itself, this class provides a slightly higher-level API.
"""
- log = log_method
-
def __repr__(self):
return rpki.log.log_repr(self, addr_to_string(self.hostport))
def __init__(self, hostport):
+ self.logger = logging.LoggerAdapter(logger, dict(context = self))
self.hostport = hostport
self.client = None
- self.log("Created")
+ self.logger.debug("Created")
self.queue = []
def request(self, *requests):
"""
Append http_request object(s) to this queue.
"""
- self.log("Adding requests %r" % requests)
+ self.logger.debug("Adding requests %r" % requests)
self.queue.extend(requests)
def restart(self):
@@ -875,13 +849,13 @@ class http_queue(object):
try:
if self.client is None:
self.client = http_client(self, self.hostport)
- self.log("Attached client %r" % self.client)
+ self.logger.debug("Attached client %r" % self.client)
self.client.start()
elif self.client.state == "idle":
- self.log("Sending request to existing client %r" % self.client)
+ self.logger.debug("Sending request to existing client %r" % self.client)
self.send_request()
else:
- self.log("Client %r exists in state %r" % (self.client, self.client.state))
+ self.logger.debug("Client %r exists in state %r" % (self.client, self.client.state))
except (rpki.async.ExitNow, SystemExit):
raise
except Exception, e:
@@ -902,7 +876,7 @@ class http_queue(object):
conditions.
"""
if client_ is self.client:
- self.log("Detaching client %r" % client_)
+ self.logger.debug("Detaching client %r" % client_)
self.client = None
def return_result(self, client, result, detach = False): # pylint: disable=W0621
@@ -914,7 +888,7 @@ class http_queue(object):
"""
if client is not self.client:
- self.log("Wrong client trying to return result. THIS SHOULD NOT HAPPEN. Dropping result %r" % result, logging.WARNING)
+ self.logger.warning("Wrong client trying to return result. THIS SHOULD NOT HAPPEN. Dropping result %r" % result)
return
if detach:
@@ -922,16 +896,16 @@ class http_queue(object):
try:
req = self.queue.pop(0)
- self.log("Dequeuing request %r" % req)
+ self.logger.debug("Dequeuing request %r" % req)
except IndexError:
- self.log("No caller. THIS SHOULD NOT HAPPEN. Dropping result %r" % result, logging.WARNING)
+ self.logger.warning("No caller. THIS SHOULD NOT HAPPEN. Dropping result %r" % result)
return
assert isinstance(result, http_response) or isinstance(result, Exception)
if isinstance(result, http_response):
try:
- self.log("Returning result %r to caller" % result)
+ self.logger.debug("Returning result %r to caller" % result)
req.callback(result.body)
except (rpki.async.ExitNow, SystemExit):
raise
@@ -940,21 +914,14 @@ class http_queue(object):
if isinstance(result, Exception):
try:
- self.log("Returning exception %r to caller: %s" % (result, result), logging.WARNING)
+ self.logger.warning("Returning exception %r to caller: %s" % (result, result))
req.errback(result)
except (rpki.async.ExitNow, SystemExit):
raise
except Exception:
- #
- # If we get here, we may have lost the event chain. Not
- # obvious what we can do about it at this point, but force a
- # traceback so that it will be somewhat obvious that something
- # really bad happened.
- #
- self.log("Exception in exception callback", logging.WARNING)
- rpki.log.traceback(logger, True)
-
- self.log("Queue: %r" % self.queue)
+ self.logger.exception("Exception in exception callback, may have lost event chain")
+
+ self.logger.debug("Queue: %r" % self.queue)
if self.queue:
self.restart()