def __init__(self, sock, addr): Acore.__init__(self) self.addr = addr self.ahttp = AHTTP(sock, user=self)
class WsgiHandler(Acore): app = None env = {'SERVER_NAME': 'yeast asvr 0.1', #'GATEWAY_INTERFACE'] = 'CGI/1.1' 'SERVER_PORT': '8080', 'SCRIPT_NAME': '', } def __init__(self, sock, addr): Acore.__init__(self) self.addr = addr self.ahttp = AHTTP(sock, user=self) def setup_env(self): env = self.environ = self.env.copy() http_dict = self.ahttp.http_dict hs = http_dict['headers'] env['yeast.SELF'] = self env['yeast.AHTTP'] = self.ahttp #env['HTTP_HEADERS'] = hs env['REMOTE_ADDR'] = self.addr[0] env['REMOTE_PORT'] = self.addr[1] if hs.typeheader is None: env['CONTENT_TYPE'] = hs.type else: env['CONTENT_TYPE'] = hs.typeheader l = hs.getheader('content-length') if l: env['CONTENT_LENGTH'] = l env['SERVER_PROTOCOL'] = http_dict['version'] env['REQUEST_METHOD'] = http_dict['action'] env['REQUEST_PATH'] = path = http_dict['path'] pq = path.split('?', 1) p, q = pq[0], pq[1] if len(pq) == 2 else '' env['PATH_INFO'] = urllib.unquote(p) env['QUERY_STRING'] = q for k, v in hs.items(): k = k.replace('-', '_').upper() v = v.strip() if k in env: continue # skip content length, type,etc. if 'HTTP_' + k in env: env['HTTP_' + k] += ',' + v # comma-separate multiple headers else: env['HTTP_' + k] = v def wsgi_write(self, data): self._buf.write(data) self.sent_size += len(data) def start_response(self, status, headers, exc_info=None): self._buf = StringIO() self.sent_size = 0 self.app_status = status self.app_headers = headers return self.wsgi_write def handle_error(self): #self.start_response() pass def get_body(self): #print int(self.environ.get('CONTENT_LENGTH', 0)) if int(self.environ.get('CONTENT_LENGTH', 0)) > 0: for y in self.ahttp.get_body(): yield y #else: # self.ahttp.http_dict['body'] = StringIO() def _run(self): #assert isinstance(self.app, callable) try: for y in self.ahttp.get_head(): yield y except SocketClosed: self.ahttp.sock.close() logging.debug("%s SocketClosed" % str(self.addr)) return self.setup_env() for y in self.get_body(): yield y self.result = self.app(self.environ, self.start_response) #print repr(self.result) for x in self.result: if isinstance(x, Aact): yield x else: self.wsgi_write(x) # process http status and headers msg = StringIO() msg.write("%s %d OK\r\n" % ( self.ahttp.http_dict['version'], self.app_status)) # FIXME? is this the right way? self.app_headers['Content-Length'] = self.sent_size for h, v in self.app_headers.iteritems(): msg.write("%s: %s\r\n" % (h, v)) msg.write('\r\n') for y in self.ahttp.write_all(msg.getvalue()): yield y # http body for y in self.ahttp.write_all(self._buf.getvalue()): yield y # FIXME self.ahttp.sock.close() def run(self): try: for y in self._run(): yield y except Exception, e: logging.error("self.addr = %s" % str(self.addr)) logexc()