Example #1
0
    def _process(self, method):
        url = urlparse(self.path)
        path = url.path.lstrip('/')
        for regex, processing in self.server.pathProcessing:
            match = regex.match(path)
            if match:
                uriRoot = path[:match.end()]
                if not uriRoot.endswith('/'): uriRoot += '/'

                assert isinstance(processing, Processing), 'Invalid processing %s' % processing
                req, reqCnt = processing.contexts['request'](), processing.contexts['requestCnt']()
                rsp, rspCnt = processing.contexts['response'](), processing.contexts['responseCnt']()

                assert isinstance(req, RequestHTTP), 'Invalid request %s' % req
                assert isinstance(reqCnt, RequestContentHTTPAsyncore), 'Invalid request content %s' % reqCnt
                assert isinstance(rsp, ResponseHTTP), 'Invalid response %s' % rsp
                assert isinstance(rspCnt, ResponseContentHTTP), 'Invalid response content %s' % rspCnt

                req.scheme, req.uriRoot, req.uri = 'http', uriRoot, path[match.end():]
                req.parameters = parse_qsl(url.query, True, False)
                break
        else:
            self.send_response(404)
            self.end_headers()
            self.close()
            return

        req.methodName = method
        req.headers = dict(self.headers)

        def respond():
            assert isinstance(rsp.code, int), 'Invalid response code %s' % rsp.code
    
            if ResponseHTTP.headers in rsp:
                for name, value in rsp.headers.items(): self.send_header(name, value)
    
            if ResponseHTTP.text in rsp: self.send_response(rsp.code, rsp.text)
            else: self.send_response(rsp.code)
    
            self.end_headers()
    
            if rspCnt.source is not None:
                if isinstance(rspCnt.source, IInputStream): source = readGenerator(rspCnt.source, self.bufferSize)
                else: source = rspCnt.source
    
                self._writeq.append((WRITE_ITER, iter(source)))
            self._writeq.append((WRITE_CLOSE, None))
            
        chain = Chain(processing)
        chain.process(request=req, requestCnt=reqCnt, response=rsp, responseCnt=rspCnt)
        chain.callBack(respond)
        
        while True:
            if not chain.do():
                self._next(3)  # Now we proceed to write stage
                break
            if reqCnt.contentReader is not None:
                self._next(2)  # Now we proceed to read stage
                self._reader = reqCnt.contentReader
                break