blob: 522139944522dcaf759ab708333224aeebc51fdd [file] [log] [blame]
Chengyu Fanb07788a2014-03-31 12:15:36 -06001#!/usr/bin/env python2.7
2
3from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
4from SocketServer import ThreadingMixIn
5import sys
6import commands
7import StringIO
8import urlparse
9import logging
10import cgi
11import argparse
12
13
14class StatusHandler(BaseHTTPRequestHandler):
15 """ The handler class to handle requests."""
16 def do_GET(self):
17 # get the url info to decide how to respond
18 parsedPath = urlparse.urlparse(self.path)
19 resultMessage = ""
20 if parsedPath.path == "/robots.txt":
21 if self.server.robots == False:
22 # return User-agent: * Disallow: / to disallow robots
23 resultMessage = "User-agent: * \nDisallow: /\n"
24 self.send_response(200)
25 self.send_header("Content-type", "text/plain")
26 elif parsedPath.path == "/":
27 # get current nfd status, and use it as result message
28 resultMessage = self.getNfdStatus()
29 self.send_response(200)
30 self.send_header("Content-type", "text/html; charset=UTF-8")
31 else:
32 # non-existing content
33 resultMessage = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 '\
34 + 'Transitional//EN" '\
35 + '"http://www.w3.org/TR/html4/loose.dtd">\n'\
36 + '<html><head><title>Object not '\
37 + 'found!</title><meta http-equiv="Content-type" ' \
38 + 'content="text/html;charset=UTF-8"></head>\n'\
39 + '<body><h1>Object not found!</h1>'\
40 + '<p>The requested URL was not found on this server.</p>'\
41 + '<h2>Error 404</h2>'\
42 + '</body></html>'
43 self.send_response(404)
44 self.send_header("Content-type", "text/html; charset=UTF-8")
45
46 self.end_headers()
47 self.wfile.write(resultMessage)
48
49 def do_HEAD(self):
50 self.send_response(405)
51 self.send_header("Content-type", "text/plain")
52 self.end_headers()
53
54 def do_POST(self):
55 self.send_response(405)
56 self.send_header("Content-type", "text/plain")
57 self.end_headers()
58
59 def log_message(self, format, *args):
60 if self.server.verbose:
61 logging.info("%s - [%s] %s\n" % (self.address_string(),
62 self.log_date_time_string(), format % args))
63
64 def getNfdStatus(self):
65 """
66 This function tries to call nfd-status command
67 to get nfd's current status, after convert it
68 to html format, return it to the caller
69 """
70 (res, output) = commands.getstatusoutput('nfd-status')
71
72 htmlStr = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional'\
73 + '//EN" "http://www.w3.org/TR/html4/loose.dtd">\n'\
74 + '<html><head><title>NFD status</title>'\
75 + '<meta http-equiv="Content-type" content="text/html;'\
76 + 'charset=UTF-8"></head>\n<body>'
77 if res == 0:
78 # parse the output
79 buf = StringIO.StringIO(output)
80 firstLine = 0
81 for line in buf:
82 if line.endswith(":\n"):
83 if firstLine != 0:
84 htmlStr += "</ul>\n"
85 firstLine += 1
86 htmlStr += "<b>" + cgi.escape(line.strip()) + "</b><br>\n"\
87 + "<ul>\n"
88 continue
89 line = line.strip()
90 htmlStr += "<li>" + cgi.escape(line) + "</li>\n"
91 buf.close()
92 htmlStr += "</ul>\n"
93 else:
94 # return connection error code
95 htmlStr = htmlStr + "<p>Cannot connect to NFD,"\
96 + " Code = " + str(res) + "</p>\n"
97 htmlStr = htmlStr + "</body></html>"
98 return htmlStr
99
100
101class ThreadHTTPServer(ThreadingMixIn, HTTPServer):
102 """ Handle requests using threads"""
103 def __init__(self, server, handler, verbose=False, robots=False):
104 try:
105 HTTPServer.__init__(self, server, handler)
106 except Exception as e:
107 logging.error(str(e))
108 sys.exit(2)
109 self.verbose = verbose
110 self.robots = robots
111
112
113# main function to start
114def httpServer():
115 parser = argparse.ArgumentParser()
116 parser.add_argument("-p", type=int, metavar="port number",
117 help="Specify the HTTP server port number, default is 8080.",
118 dest="port", default=8080)
119 # if address is not specified, using empty str
120 # so it can bind to local address
121 parser.add_argument("-a", default="localhost", metavar="IP address", dest="addr",
122 help="Specify the HTTP server IP address.")
123 parser.add_argument("-r", default=False, dest="robots", action="store_true",
124 help="Enable HTTP robots to crawl; disabled by default.")
125 parser.add_argument("-v", default=False, dest="verbose", action="store_true",
126 help="Verbose mode.")
127
128 args = vars(parser.parse_args())
129 localPort = args["port"]
130 localAddr = args["addr"]
131 verbose = args["verbose"]
132 robots = args["robots"]
133
134 # setting log message format
135 logging.basicConfig(format='%(asctime)s [%(levelname)s] %(message)s',
136 level=logging.INFO)
137
138 # if port is not valid, exit
139 if localPort <= 0 or localPort > 65535:
140 logging.error("Specified port number is invalid")
141 sys.exit(2)
142
143 httpd = ThreadHTTPServer((localAddr, localPort), StatusHandler,
144 verbose, robots)
145
146 logging.info("Server Starts - at http://%s:%s" % httpd.server_address)
147
148 try:
149 httpd.serve_forever()
150 except KeyboardInterrupt:
151 pass
152
153 logging.info("Server stopping ...")
154 httpd.server_close()
155
156 logging.info("Server Stopped - at http://%s:%s" % httpd.server_address)
157
158
159if __name__ == '__main__':
160 httpServer()