5 Copyright (c) 2014-2016, 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, 11 The University of Memphis. 13 This file is part of NFD (Named Data Networking Forwarding Daemon). 14 See AUTHORS.md for complete list of NFD authors and contributors. 16 NFD is free software: you can redistribute it and/or modify it under the terms 17 of the GNU General Public License as published by the Free Software Foundation, 18 either version 3 of the License, or (at your option) any later version. 20 NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 21 without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 22 PURPOSE. See the GNU General Public License for more details. 24 You should have received a copy of the GNU General Public License along with 25 NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>. 28 from BaseHTTPServer
import HTTPServer
29 from SimpleHTTPServer
import SimpleHTTPRequestHandler
30 from SocketServer
import ThreadingMixIn
41 """ The handler class to handle requests.""" 44 parsedPath = urlparse.urlparse(self.path)
45 if parsedPath.path ==
"/":
48 self.send_response(httpCode)
49 self.send_header(
"Content-Type", contentType)
51 self.wfile.write(body)
52 elif parsedPath.path ==
"/robots.txt" and self.server.robots ==
True:
53 self.send_response(200)
54 self.send_header(
"Content-Type",
"text/plain")
57 SimpleHTTPRequestHandler.do_GET(self)
60 if self.server.verbose:
61 logging.info(
"%s - %s\n" % (self.address_string(), format % args))
64 return '<!DOCTYPE html><title>NFD status</title><p>%s</p>' % text
67 """ Obtain XML-formatted NFD status report """ 69 sp = subprocess.Popen([
'nfdc',
'status',
'report',
'xml'], stdout=subprocess.PIPE, close_fds=
True)
70 output = sp.communicate()[0]
74 return (500,
"text/html; charset=UTF-8", html)
76 if sp.returncode == 0:
78 pos = output.index(
'>') + 1
80 +
'<?xml-stylesheet type="text/xsl" href="nfd-status.xsl"?>'\
82 return (200,
'text/xml; charset=UTF-8', xml)
85 return (504,
"text/html; charset=UTF-8", html)
88 """ Handle requests using threads """ 89 def __init__(self, server, handler, verbose=False, robots=False):
90 serverAddr = server[0]
93 if ipType == socket.AF_INET6:
95 elif ipType == socket.AF_INET:
98 logging.error(
"The input IP address is neither IPv6 nor IPv4")
102 HTTPServer.__init__(self, server, handler)
103 except Exception
as e:
104 logging.error(str(e))
110 """ Get ipAddr's address type """ 113 socket.inet_pton(socket.AF_INET6, ipAddr)
114 return socket.AF_INET6
119 socket.inet_pton(socket.AF_INET, ipAddr)
120 return socket.AF_INET
127 parser = argparse.ArgumentParser()
128 parser.add_argument(
"-p", type=int, metavar=
"port number",
129 help=
"Specify the HTTP server port number, default is 8080.",
130 dest=
"port", default=8080)
132 parser.add_argument(
"-a", default=
"127.0.0.1", metavar=
"IP address", dest=
"addr",
133 help=
"Specify the HTTP server IP address.")
134 parser.add_argument(
"-r", default=
False, dest=
"robots", action=
"store_true",
135 help=
"Enable HTTP robots to crawl; disabled by default.")
136 parser.add_argument(
"-f", default=
"@DATAROOTDIR@/ndn", metavar=
"Server Directory", dest=
"serverDir",
137 help=
"Specify the working directory of nfd-status-http-server, default is @DATAROOTDIR@/ndn.")
138 parser.add_argument(
"-v", default=
False, dest=
"verbose", action=
"store_true",
139 help=
"Verbose mode.")
140 parser.add_argument(
"--version", default=
False, dest=
"version", action=
"store_true",
141 help=
"Show version and exit")
143 args = vars(parser.parse_args())
149 localPort = args[
"port"]
150 localAddr = args[
"addr"]
151 verbose = args[
"verbose"]
152 robots = args[
"robots"]
153 serverDirectory = args[
"serverDir"]
155 os.chdir(serverDirectory)
158 logging.basicConfig(format=
'%(asctime)s [%(levelname)s] %(message)s',
162 if localPort <= 0
or localPort > 65535:
163 logging.error(
"Specified port number is invalid")
169 if httpd.address_family == socket.AF_INET6:
170 httpServerAddr =
"http://[%s]:%s" % (httpd.server_address[0],
171 httpd.server_address[1])
173 httpServerAddr =
"http://%s:%s" % (httpd.server_address[0],
174 httpd.server_address[1])
176 logging.info(
"Server started - at %s" % httpServerAddr)
179 httpd.serve_forever()
180 except KeyboardInterrupt:
185 logging.info(
"Server stopped")
188 if __name__ ==
'__main__':
def makeErrorResponseHtml(self, text)
def log_message(self, format, args)
def getIpType(self, ipAddr)
def __init__(self, server, handler, verbose=False, robots=False)