2012-04-28 00:42:03 +00:00
|
|
|
#!/usr/bin/env python
|
2012-07-27 02:03:15 +00:00
|
|
|
import argparse, sys, logging, logging.handlers
|
2012-07-29 04:10:22 +00:00
|
|
|
from libpathod import pathod, utils, version, rparse
|
2012-04-28 00:42:03 +00:00
|
|
|
|
2012-06-21 02:29:49 +00:00
|
|
|
if __name__ == "__main__":
|
2012-06-24 09:10:10 +00:00
|
|
|
parser = argparse.ArgumentParser(description='A pathological HTTP/S daemon.')
|
2012-06-21 02:29:49 +00:00
|
|
|
parser.add_argument("-p", dest='port', default=9999, type=int, help='Port. Specify 0 to pick an arbitrary empty port.')
|
|
|
|
parser.add_argument("-l", dest='address', default="0.0.0.0", type=str, help='Listening address.')
|
|
|
|
parser.add_argument(
|
2012-06-24 04:38:32 +00:00
|
|
|
"-a", dest='anchors', default=[], type=str, action="append", metavar="ANCHOR",
|
2012-06-21 02:29:49 +00:00
|
|
|
help='Add an anchor. Specified as a string with the form pattern=pagespec'
|
|
|
|
)
|
2012-07-24 09:51:43 +00:00
|
|
|
parser.add_argument(
|
|
|
|
"-c", dest='craftanchor', default="/p/", type=str,
|
|
|
|
help='Anchorpoint for URL crafting commands.'
|
|
|
|
)
|
2012-06-21 02:29:49 +00:00
|
|
|
parser.add_argument(
|
|
|
|
"-d", dest='staticdir', default=None, type=str,
|
|
|
|
help='Directory for static files.'
|
|
|
|
)
|
2012-07-27 02:03:15 +00:00
|
|
|
parser.add_argument(
|
|
|
|
"-f", dest='logfile', default=None, type=str,
|
|
|
|
help='Log file.'
|
|
|
|
)
|
2012-06-24 09:40:31 +00:00
|
|
|
parser.add_argument(
|
2012-07-23 07:55:33 +00:00
|
|
|
"--debug", dest='debug', default=False, action="store_true",
|
2012-06-24 09:40:31 +00:00
|
|
|
help='Enable debug output.'
|
|
|
|
)
|
2012-06-21 02:29:49 +00:00
|
|
|
parser.add_argument(
|
2012-07-23 07:55:33 +00:00
|
|
|
"-s", dest='ssl', default=False, action="store_true",
|
2012-06-21 02:29:49 +00:00
|
|
|
help='Serve with SSL.'
|
|
|
|
)
|
2012-07-23 03:03:56 +00:00
|
|
|
parser.add_argument(
|
2012-07-23 07:55:33 +00:00
|
|
|
"--limit-size", dest='sizelimit', default=None, type=str,
|
2012-07-23 03:03:56 +00:00
|
|
|
help='Size limit of served responses. Understands size suffixes, i.e. 100k.'
|
|
|
|
)
|
2012-07-23 11:31:26 +00:00
|
|
|
parser.add_argument(
|
|
|
|
"--noapi", dest='noapi', default=False, action="store_true",
|
|
|
|
help='Disable API.'
|
|
|
|
)
|
2012-07-26 08:01:51 +00:00
|
|
|
parser.add_argument(
|
|
|
|
"--nohang", dest='nohang', default=False, action="store_true",
|
|
|
|
help='Disable pauses during crafted response generation.'
|
|
|
|
)
|
2012-06-21 02:29:49 +00:00
|
|
|
parser.add_argument(
|
2012-07-23 07:55:33 +00:00
|
|
|
"--noweb", dest='noweb', default=False, action="store_true",
|
2012-07-23 11:31:26 +00:00
|
|
|
help='Disable both web interface and API.'
|
2012-07-23 07:55:33 +00:00
|
|
|
)
|
2012-07-23 09:39:31 +00:00
|
|
|
parser.add_argument(
|
|
|
|
"--nocraft", dest='nocraft', default=False, action="store_true",
|
|
|
|
help='Disable response crafting. If anchors are specified, they still work.'
|
|
|
|
)
|
2012-07-23 07:55:33 +00:00
|
|
|
parser.add_argument(
|
|
|
|
"--keyfile", dest='ssl_keyfile', default=None, type=str,
|
2012-06-21 02:29:49 +00:00
|
|
|
help='SSL key file. If not specified, a default key is used.'
|
|
|
|
)
|
|
|
|
parser.add_argument(
|
2012-07-23 07:55:33 +00:00
|
|
|
"--certfile", dest='ssl_certfile', default=None, type=str,
|
2012-06-21 02:29:49 +00:00
|
|
|
help='SSL cert file. If not specified, a default cert is used.'
|
|
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
sl = [args.ssl_keyfile, args.ssl_certfile]
|
|
|
|
if any(sl) and not all(sl):
|
|
|
|
parser.error("Both --certfile and --keyfile must be specified.")
|
|
|
|
|
|
|
|
if args.ssl:
|
|
|
|
ssl = dict(
|
|
|
|
keyfile = args.ssl_keyfile or utils.data.path("resources/server.key"),
|
|
|
|
certfile = args.ssl_certfile or utils.data.path("resources/server.crt"),
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
ssl = None
|
|
|
|
|
2012-06-24 04:38:32 +00:00
|
|
|
alst = []
|
|
|
|
for i in args.anchors:
|
|
|
|
parts = utils.parse_anchor_spec(i)
|
|
|
|
if not parts:
|
|
|
|
parser.error("Invalid anchor specification: %s"%i)
|
|
|
|
alst.append(parts)
|
|
|
|
|
2012-06-24 09:40:31 +00:00
|
|
|
root = logging.getLogger()
|
|
|
|
if root.handlers:
|
|
|
|
for handler in root.handlers:
|
|
|
|
root.removeHandler(handler)
|
|
|
|
logging.basicConfig(
|
|
|
|
format='%(asctime)s: %(message)s',
|
|
|
|
datefmt='%d-%m-%y %I:%M:%S',
|
|
|
|
level=logging.DEBUG
|
|
|
|
)
|
|
|
|
if not args.debug:
|
|
|
|
logging.disable(logging.DEBUG)
|
2012-07-27 02:03:15 +00:00
|
|
|
if args.logfile:
|
|
|
|
ch = logging.handlers.WatchedFileHandler(args.logfile)
|
|
|
|
root.addHandler(ch)
|
|
|
|
|
2012-06-24 09:40:31 +00:00
|
|
|
|
2012-07-23 03:03:56 +00:00
|
|
|
sizelimit = None
|
|
|
|
if args.sizelimit:
|
|
|
|
try:
|
|
|
|
sizelimit = utils.parse_size(args.sizelimit)
|
|
|
|
except ValueError, v:
|
|
|
|
parser.error(v)
|
|
|
|
|
2012-06-24 04:38:32 +00:00
|
|
|
try:
|
|
|
|
pd = pathod.Pathod(
|
|
|
|
(args.address, args.port),
|
2012-07-24 09:51:43 +00:00
|
|
|
craftanchor = args.craftanchor,
|
2012-06-24 04:38:32 +00:00
|
|
|
ssloptions = ssl,
|
|
|
|
staticdir = args.staticdir,
|
2012-07-23 03:03:56 +00:00
|
|
|
anchors = alst,
|
|
|
|
sizelimit = sizelimit,
|
2012-07-23 09:39:31 +00:00
|
|
|
noweb = args.noweb,
|
2012-07-23 11:31:26 +00:00
|
|
|
nocraft = args.nocraft,
|
2012-07-27 02:03:15 +00:00
|
|
|
noapi = args.noapi,
|
2012-07-26 08:01:51 +00:00
|
|
|
nohang = args.nohang
|
2012-06-24 04:38:32 +00:00
|
|
|
)
|
|
|
|
except pathod.PathodError, v:
|
|
|
|
parser.error(str(v))
|
2012-07-29 04:10:22 +00:00
|
|
|
except rparse.FileAccessDenied, v:
|
|
|
|
parser.error("%s You probably want to a -d argument."%str(v))
|
|
|
|
|
2012-06-21 02:29:49 +00:00
|
|
|
try:
|
|
|
|
print "%s listening on port %s"%(version.NAMEVERSION, pd.port)
|
|
|
|
pd.serve_forever()
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
pass
|