5 Copyright (c) 2014 Regents of the University of California,
6 Arizona Board of Regents,
7 Colorado State University,
8 University Pierre & Marie Curie, Sorbonne University,
9 Washington University in St. Louis,
10 Beijing Institute of Technology
12 This file is part of NFD (Named Data Networking Forwarding Daemon).
13 See AUTHORS.md for complete list of NFD authors and contributors.
15 NFD is free software: you can redistribute it and/or modify it under the terms
16 of the GNU General Public License as published by the Free Software Foundation,
17 either version 3 of the License, or (at your option) any later version.
19 NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
20 without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21 PURPOSE. See the GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License along with
24 NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
27 from BaseHTTPServer
import HTTPServer
28 from SimpleHTTPServer
import SimpleHTTPRequestHandler
29 from SocketServer
import ThreadingMixIn
42 """ The handler class to handle requests."""
45 parsedPath = urlparse.urlparse(self.path)
46 if parsedPath.path ==
"/":
49 self.send_response(200)
51 self.send_header(
"Content-type",
"text/xml; charset=UTF-8")
53 self.send_header(
"Content-type",
"text/html; charset=UTF-8")
56 self.wfile.write(resultMessage)
57 elif parsedPath.path ==
"/robots.txt" and self.server.robots ==
True:
59 self.send_response(200)
60 self.send_header(
"Content-type",
"text/plain")
62 self.wfile.write(resultMessage)
64 SimpleHTTPRequestHandler.do_GET(self)
67 if self.server.verbose:
68 logging.info(
"%s - %s\n" % (self.address_string(),
73 This function is to call nfd-status command
74 to get xml format output
76 sp = subprocess.Popen([
'nfd-status',
'-x'], stdout=subprocess.PIPE, close_fds=
True)
77 output = sp.communicate()[0]
78 if sp.returncode == 0:
80 newLineIndex = output.index(
'>') + 1
81 resultStr = output[:newLineIndex]\
82 +
"<?xml-stylesheet type=\"text/xsl\" href=\"nfd-status.xsl\"?>"\
83 + output[newLineIndex:]
84 return (sp.returncode, resultStr)
86 htmlStr =
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional'\
87 +
'//EN" "http://www.w3.org/TR/html4/loose.dtd">\n'\
88 +
'<html><head><title>NFD status</title>'\
89 +
'<meta http-equiv="Content-type" content="text/html;'\
90 +
'charset=UTF-8"></head>\n<body>'
92 htmlStr = htmlStr +
"<p>Cannot connect to NFD,"\
93 +
" Code = " + str(sp.returncode) +
"</p>\n"
94 htmlStr = htmlStr +
"</body></html>"
95 return (sp.returncode, htmlStr)
98 """ Handle requests using threads """
99 def __init__(self, server, handler, verbose=False, robots=False):
100 serverAddr = server[0]
103 if ipType == socket.AF_INET6:
105 elif ipType == socket.AF_INET:
108 logging.error(
"The input IP address is neither IPv6 nor IPv4")
112 HTTPServer.__init__(self, server, handler)
113 except Exception
as e:
114 logging.error(str(e))
120 """ Get ipAddr's address type """
123 socket.inet_pton(socket.AF_INET6, ipAddr)
124 return socket.AF_INET6
129 socket.inet_pton(socket.AF_INET, ipAddr)
130 return socket.AF_INET
137 parser = argparse.ArgumentParser()
138 parser.add_argument(
"-p", type=int, metavar=
"port number",
139 help=
"Specify the HTTP server port number, default is 8080.",
140 dest=
"port", default=8080)
142 parser.add_argument(
"-a", default=
"127.0.0.1", metavar=
"IP address", dest=
"addr",
143 help=
"Specify the HTTP server IP address.")
144 parser.add_argument(
"-r", default=
False, dest=
"robots", action=
"store_true",
145 help=
"Enable HTTP robots to crawl; disabled by default.")
146 parser.add_argument(
"-f", default=
"@DATAROOTDIR@/ndn", metavar=
"Server Directory", dest=
"serverDir",
147 help=
"Specify the working directory of nfd-status-http-server, default is @DATAROOTDIR@/ndn.")
148 parser.add_argument(
"-v", default=
False, dest=
"verbose", action=
"store_true",
149 help=
"Verbose mode.")
150 parser.add_argument(
"--version", default=
False, dest=
"version", action=
"store_true",
151 help=
"Show version and exit")
153 args = vars(parser.parse_args())
159 localPort = args[
"port"]
160 localAddr = args[
"addr"]
161 verbose = args[
"verbose"]
162 robots = args[
"robots"]
163 serverDirectory = args[
"serverDir"]
165 os.chdir(serverDirectory)
168 logging.basicConfig(format=
'%(asctime)s [%(levelname)s] %(message)s',
172 if localPort <= 0
or localPort > 65535:
173 logging.error(
"Specified port number is invalid")
179 if httpd.address_family == socket.AF_INET6:
180 httpServerAddr =
"http://[%s]:%s" % (httpd.server_address[0],
181 httpd.server_address[1])
183 httpServerAddr =
"http://%s:%s" % (httpd.server_address[0],
184 httpd.server_address[1])
186 logging.info(
"Server started - at %s" % httpServerAddr)
189 httpd.serve_forever()
190 except KeyboardInterrupt:
195 logging.info(
"Server stopped")
198 if __name__ ==
'__main__':
def log_message(self, format, args)
def getIpType(self, ipAddr)