Ticket #343: large_response.patch

File large_response.patch, 1.6 KB (added by gawel, 3 years ago)
  • wsgiproxy/exactproxy.py

     
    99    'transfer-encoding', 
    1010) 
    1111 
     12BLOCK_SIZE = 4096 * 16 
     13 
    1214def filter_paste_httpserver_proxy(app): 
    1315    """ 
    1416    Maps the ``paste.httpserver`` proxy environment keys to 
     
    9597    status = '%s %s' % (res.status, res.reason) 
    9698    start_response(status, headers_out) 
    9799    length = res.getheader('content-length') 
    98     # @@: This shouldn't really read in all the content at once 
    99100    if length is not None: 
    100         body = res.read(int(length)) 
     101        length = int(length) 
     102        if length > BLOCK_SIZE: 
     103            return iter(_BodyIter(conn, res, length)) 
     104        body = res.read(length) 
    101105    else: 
    102106        body = res.read() 
    103107    conn.close() 
    104108    return [body] 
    105109 
     110class _BodyIter(object): 
     111    """ 
     112    Allow to iter over large response body and close the connection when all 
     113    data is received. 
     114    """ 
     115 
     116    def __init__(self, conn, res, length): 
     117        self.conn = conn 
     118        self.res = res 
     119        self.length = length 
     120 
     121    def __iter__(self): 
     122        return self 
     123 
     124    def next(self): 
     125        if self.length > 0: 
     126            if self.length > BLOCK_SIZE: 
     127                data = self.res.read(BLOCK_SIZE) 
     128                self.length -= BLOCK_SIZE 
     129            else: 
     130                data = self.res.read(self.length) 
     131                self.length = 0 
     132            return data 
     133        self.conn.close() 
     134        raise StopIteration() 
     135 
    106136def parse_headers(message): 
    107137    """ 
    108138    Turn a Message object into a list of WSGI-style headers.