Refactor logging, add some defaults to pathod argument help.

This commit is contained in:
Aldo Cortesi 2015-04-23 08:43:57 +12:00
parent ce6147ec35
commit 2306a7ab6d
2 changed files with 41 additions and 27 deletions

View File

@ -211,14 +211,14 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr):
dest='port', dest='port',
default=9999, default=9999,
type=int, type=int,
help='Port. Specify 0 to pick an arbitrary empty port.' help='Port. Specify 0 to pick an arbitrary empty port. (9999)'
) )
parser.add_argument( parser.add_argument(
"-l", "-l",
dest='address', dest='address',
default="127.0.0.1", default="127.0.0.1",
type=str, type=str,
help='Listening address.' help='Listening address. (127.0.0.1)'
) )
parser.add_argument( parser.add_argument(
"-a", "-a",
@ -234,7 +234,7 @@ def args_pathod(argv, stdout=sys.stdout, stderr=sys.stderr):
) )
parser.add_argument( parser.add_argument(
"-c", dest='craftanchor', default="/p/", type=str, "-c", dest='craftanchor', default="/p/", type=str,
help='Anchorpoint for URL crafting commands.' help='Anchorpoint for URL crafting commands. (/p/)'
) )
parser.add_argument( parser.add_argument(
"--confdir", "--confdir",

View File

@ -97,10 +97,15 @@ class PathodHandler(tcp.BaseHandler):
again: True if request handling should continue. again: True if request handling should continue.
log: A dictionary, or None log: A dictionary, or None
""" """
if self.server.logreq:
self.rfile.start_log()
if self.server.logresp:
self.wfile.start_log()
line = http.get_request_line(self.rfile) line = http.get_request_line(self.rfile)
if not line: if not line:
# Normal termination # Normal termination
return False, None return False
m = utils.MemBool() m = utils.MemBool()
if m(http.parse_init_connect(line)): if m(http.parse_init_connect(line)):
@ -126,8 +131,9 @@ class PathodHandler(tcp.BaseHandler):
except tcp.NetLibError, v: except tcp.NetLibError, v:
s = str(v) s = str(v)
self.info(s) self.info(s)
return False, dict(type="error", msg=s) self.addlog(dict(type="error", msg=s))
return True, None return False
return True
elif m(http.parse_init_proxy(line)): elif m(http.parse_init_proxy(line)):
method, _, _, _, path, httpversion = m.v method, _, _, _, path, httpversion = m.v
elif m(http.parse_init_http(line)): elif m(http.parse_init_http(line)):
@ -135,13 +141,15 @@ class PathodHandler(tcp.BaseHandler):
else: else:
s = "Invalid first line: %s" % repr(line) s = "Invalid first line: %s" % repr(line)
self.info(s) self.info(s)
return False, dict(type="error", msg=s) self.addlog(dict(type="error", msg=s))
return False
headers = http.read_headers(self.rfile) headers = http.read_headers(self.rfile)
if headers is None: if headers is None:
s = "Invalid headers" s = "Invalid headers"
self.info(s) self.info(s)
return False, dict(type="error", msg=s) self.addlog(dict(type="error", msg=s))
return False
clientcert = None clientcert = None
if self.clientcert: if self.clientcert:
@ -178,13 +186,15 @@ class PathodHandler(tcp.BaseHandler):
except http.HttpError, s: except http.HttpError, s:
s = str(s) s = str(s)
self.info(s) self.info(s)
return False, dict(type="error", msg=s) self.addlog(dict(type="error", msg=s))
return False
for i in self.server.anchors: for i in self.server.anchors:
if i[0].match(path): if i[0].match(path):
self.info("crafting anchor: %s" % path) self.info("crafting anchor: %s" % path)
again, retlog["response"] = self.serve_crafted(i[1]) again, retlog["response"] = self.serve_crafted(i[1])
return again, retlog self.addlog(retlog)
return again
if not self.server.nocraft and path.startswith(self.server.craftanchor): if not self.server.nocraft and path.startswith(self.server.craftanchor):
spec = urllib.unquote(path)[len(self.server.craftanchor):] spec = urllib.unquote(path)[len(self.server.craftanchor):]
@ -198,14 +208,16 @@ class PathodHandler(tcp.BaseHandler):
"Error parsing response spec: %s\n" % v.msg + v.marked() "Error parsing response spec: %s\n" % v.msg + v.marked()
) )
again, retlog["response"] = self.serve_crafted(crafted) again, retlog["response"] = self.serve_crafted(crafted)
return again, retlog self.addlog(retlog)
return again
elif self.server.noweb: elif self.server.noweb:
crafted = language.make_error_response("Access Denied") crafted = language.make_error_response("Access Denied")
language.serve(crafted, self.wfile, self.server.settings) language.serve(crafted, self.wfile, self.server.settings)
return False, dict( self.addlog(dict(
type="error", type="error",
msg="Access denied: web interface disabled" msg="Access denied: web interface disabled"
) ))
return False
else: else:
self.info("app: %s %s" % (method, path)) self.info("app: %s %s" % (method, path))
req = wsgi.Request("http", method, path, headers, content) req = wsgi.Request("http", method, path, headers, content)
@ -218,7 +230,7 @@ class PathodHandler(tcp.BaseHandler):
version.NAMEVERSION version.NAMEVERSION
) )
a.serve(flow, self.wfile) a.serve(flow, self.wfile)
return True, None return True
def _log_bytes(self, header, data, hexdump): def _log_bytes(self, header, data, hexdump):
s = [] s = []
@ -231,6 +243,20 @@ class PathodHandler(tcp.BaseHandler):
s.append(netlib.utils.cleanBin(data)) s.append(netlib.utils.cleanBin(data))
self.info("\n".join(s)) self.info("\n".join(s))
def addlog(self, log):
# FIXME: The bytes in the log should not be escaped. We do this at the
# moment because JSON encoding can't handle binary data, and I don't
# want to base64 everything.
if self.server.logreq:
bytes = self.rfile.get_log().encode("string_escape")
self._log_bytes("Request", bytes, self.server.hexdump)
log["request_bytes"] = bytes
if self.server.logresp:
bytes = self.wfile.get_log().encode("string_escape")
self._log_bytes("Response", bytes, self.server.hexdump)
log["response_bytes"] = bytes
self.server.add_log(log)
def handle(self): def handle(self):
if self.server.ssl: if self.server.ssl:
try: try:
@ -254,19 +280,7 @@ class PathodHandler(tcp.BaseHandler):
return return
self.settimeout(self.server.timeout) self.settimeout(self.server.timeout)
while not self.finished: while not self.finished:
if self.server.logreq: again = self.handle_request()
self.rfile.start_log()
if self.server.logresp:
self.wfile.start_log()
again, log = self.handle_request()
if log:
if self.server.logreq:
log["request_bytes"] = self.rfile.get_log().encode("string_escape")
self._log_bytes("Request", log["request_bytes"], self.server.hexdump)
if self.server.logresp:
log["response_bytes"] = self.wfile.get_log().encode("string_escape")
self._log_bytes("Response", log["response_bytes"], self.server.hexdump)
self.server.add_log(log)
if not again: if not again:
return return