⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpserver.py

📁 xen 3.2.2 源码
💻 PY
字号:
#============================================================================# This library is free software; you can redistribute it and/or# modify it under the terms of version 2.1 of the GNU Lesser General Public# License as published by the Free Software Foundation.## This library is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU# Lesser General Public License for more details.## You should have received a copy of the GNU Lesser General Public# License along with this library; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#============================================================================# Copyright (C) 2005 Mike Wray <mike.wray@hp.com># Copyright (C) 2006 XenSource Ltd.#============================================================================import threadingimport stringimport socketimport typesfrom urllib import quote, unquoteimport osimport os.pathimport fcntlfrom xen.xend import sxpfrom xen.xend.Args import ArgErrorfrom xen.xend.XendError import XendErrorimport httpimport unixfrom resource import Resource, ErrorPagefrom SrvDir import SrvDirclass ThreadRequest:    """A request to complete processing using a thread.    """        def __init__(self, processor, req, fn, args, kwds):        self.processor = processor        self.req = req        self.fn = fn        self.args = args        self.kwds = kwds            def run(self):        self.processor.setInThread()        thread = threading.Thread(target=self.main)        thread.setDaemon(True)        thread.start()    def call(self):        try:            self.fn(*self.args, **self.kwds)        except SystemExit:            raise        except Exception, ex:            self.req.resultErr(ex)        self.req.finish()    def main(self):        self.call()        self.processor.process()       class RequestProcessor:    """Processor for requests on a connection to an http server.    Requests are executed synchonously unless they ask for a thread by returning    a ThreadRequest.    """    done = False    inThread = False    def __init__(self, server, sock, addr):        self.server = server        self.sock = sock        self.srd = sock.makefile('rb')        self.srw = sock.makefile('wb')        self.srvaddr = server.getServerAddr()    def isInThread(self):        return self.inThread    def setInThread(self):        self.inThread = True    def getServer(self):        return self.server    def getRequest(self):        return HttpServerRequest(self, self.srvaddr, self.srd, self.srw)    def close(self):        try:            self.sock.close()        except:            pass    def finish(self):        self.done = True        self.close()    def process(self):        while not self.done:            req = self.getRequest()            res = req.process()            if isinstance(res, ThreadRequest):                if self.isInThread():                    res.call()                else:                    res.run()                    break            else:                req.finish()                                        class HttpServerRequest(http.HttpRequest):    """A single request to an http server.    """    def __init__(self, processor, addr, srd, srw):        self.processor = processor        self.prepath = ''        http.HttpRequest.__init__(self, addr, srd, srw)    def getServer(self):        return self.processor.getServer()    def process(self):        """Process the request. If the return value is a ThreadRequest        it is evaluated in a thread.        """        try:            self.prepath = []            self.postpath = map(unquote, string.split(self.request_path[1:], '/'))            resource = self.getResource()            return self.render(resource)        except SystemExit:            raise        except Exception, ex:            self.processError(ex)    def processError(self, ex):        import traceback; traceback.print_exc()        self.sendError(http.INTERNAL_SERVER_ERROR, msg=str(ex))        self.setCloseConnection('close')    def finish(self):        self.sendResponse()        if self.close_connection:            self.processor.finish()    def prePathURL(self):        url_host = self.getRequestHostname()        port = self.getPort()        if self.isSecure():            url_proto = "https"            default_port = 443        else:            url_proto = "http"            default_port = 80        if port != default_port:            url_host += (':%d' % port)        url_path = quote(string.join(self.prepath, '/'))        return ('%s://%s/%s' % (url_proto, url_host, url_path))    def getResource(self):        return self.getServer().getResource(self)    def render(self, resource):        val = None        if resource is None:            self.sendError(http.NOT_FOUND)        else:            try:                while True:                    val = resource.render(self)                    if not isinstance(val, Resource):                        break                val = self.result(val)            except SystemExit:                raise            except Exception, ex:                self.resultErr(ex)        return val    def threadRequest(self, _fn, *_args, **_kwds):        """Create a request to finish request processing in a thread.        Use this to create a ThreadRequest to return from rendering a        resource if you need a thread to complete processing.        """        return ThreadRequest(self.processor, self, _fn, _args, _kwds)                def result(self, val):        if isinstance(val, Exception):            return self.resultErr(val)        else:            return self.resultVal(val)    def resultVal(self, val):        """Callback to complete the request.        @param val: the value        """        if val is None:            return val        elif isinstance(val, ThreadRequest):            return val        elif self.useSxp():            self.setHeader("Content-Type", sxp.mime_type)            sxp.show(val, out=self)        else:            self.write('<html><head></head><body>')            self.printPath()            if isinstance(val, types.ListType):                self.write('<code><pre>')                PrettyPrint.prettyprint(val, out=self)                self.write('</pre></code>')            else:                self.write(str(val))            self.write('</body></html>')        return None    def resultErr(self, err):        """Error callback to complete a request.        @param err: the error        """        if not isinstance(err, (ArgError, sxp.ParseError, XendError)):            raise        #log.exception("op=%s: %s", op, str(err))        if self.useSxp():            self.setHeader("Content-Type", sxp.mime_type)            sxp.show(['xend.err', str(err)], out=self)        else:            self.setHeader("Content-Type", "text/plain")            self.write('Error ')            self.write(': ')            self.write(str(err))        return None    def useSxp(self):        """Determine whether to send an SXP response to a request.        Uses SXP if there is no User-Agent, no Accept, or application/sxp is in Accept.        returns 1 for SXP, 0 otherwise        """        ok = 0        user_agent = self.getHeader('User-Agent')        accept = self.getHeader('Accept')        if (not user_agent) or (not accept) or (accept.find(sxp.mime_type) >= 0):            ok = 1        return ok    def printPath(self):        pathlist = [x for x in self.prepath if x != '' ]        s = "/"        self.write('<h1><a href="/">/</a>')        for x in pathlist:            s += x + "/"            self.write(' <a href="%s">%s</a>/' % (s, x))        self.write("</h1>")class HttpServerClient:    def __init__(self, server, sock, addr):        self.server = server        self.sock = sock        self.addr = addr    def process(self):        thread = threading.Thread(target=self.doProcess)        thread.setDaemon(True)        thread.start()    def doProcess(self):        try:            rp = RequestProcessor(self.server, self.sock, self.addr)            rp.process()        except SystemExit:            raise        except Exception, ex:            print 'HttpServer>processRequest> exception: ', ex            try:                self.sock.close()            except:                passclass HttpServer:    backlog = 5    def __init__(self, root, interface, port=8080):        self.root = root        self.interface = interface        self.port = port        # ready indicates when we are ready to begin accept connections        # it should be set after a successful bind        self.ready = False        self.closed = False    def run(self):        self.bind()        self.listen()        self.ready = True        while not self.closed:            (sock, addr) = self.accept()            cl = HttpServerClient(self, sock, addr)            cl.process()    def stop(self):        self.close()    def bind(self):        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        flags = fcntl.fcntl(self.socket.fileno(), fcntl.F_GETFD)        flags |= fcntl.FD_CLOEXEC        fcntl.fcntl(self.socket.fileno(), fcntl.F_SETFD, flags)        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)        self.socket.bind((self.interface, self.port))    def listen(self):        self.socket.listen(self.backlog)    def accept(self):        return self.socket.accept()    def close(self):        self.closed = True        self.ready = False        # shutdown socket explicitly to allow reuse        try:            self.socket.shutdown(2)        except socket.error:            pass        try:            self.socket.close()        except socket.error:            pass    def getServerAddr(self):        return (socket.gethostname(), self.port)    def getResource(self, req):        return self.root.getRequestResource(req)    def shutdown(self):        self.close()class UnixHttpServer(HttpServer):    def __init__(self, root, path):        HttpServer.__init__(self, root, 'localhost')        self.path = path            def bind(self):        self.socket = unix.bind(self.path)        flags = fcntl.fcntl(self.socket.fileno(), fcntl.F_GETFD)        flags |= fcntl.FD_CLOEXEC        fcntl.fcntl(self.socket.fileno(), fcntl.F_SETFD, flags)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -