def _response(self, response, body=None, headers=None, chunked=False, write_body=None): r_headers = {} for key, val in self._headers.items(): key = '-'.join(p.capitalize() for p in key.split('-')) r_headers[key] = val encoding = self._headers.get('content-encoding', '').lower() if 'gzip' in encoding: # pragma: no cover cmod = 'gzip' elif 'deflate' in encoding: cmod = 'deflate' else: cmod = '' resp = { 'method': self._method, 'version': '%s.%s' % self._version, 'path': self._uri, 'headers': r_headers, 'origin': self._transport.get_extra_info('addr', ' ')[0], 'query': self._query, 'form': {}, 'compression': cmod, 'multipart-data': [] } if body: # pragma: no cover resp['content'] = body else: resp['content'] = self._body.decode('utf-8', 'ignore') ct = self._headers.get('content-type', '').lower() # application/x-www-form-urlencoded if ct == 'application/x-www-form-urlencoded': resp['form'] = urllib.parse.parse_qs(self._body.decode('latin1')) # multipart/form-data elif ct.startswith('multipart/form-data'): # pragma: no cover out = io.BytesIO() for key, val in self._headers.items(): out.write(bytes('{}: {}\r\n'.format(key, val), 'latin1')) out.write(b'\r\n') out.write(self._body) out.write(b'\r\n') out.seek(0) message = email.parser.BytesParser().parse(out) if message.is_multipart(): for msg in message.get_payload(): if msg.is_multipart(): logging.warning('multipart msg is not expected') else: key, params = cgi.parse_header( msg.get('content-disposition', '')) params['data'] = msg.get_payload() params['content-type'] = msg.get_content_type() cte = msg.get('content-transfer-encoding') if cte is not None: resp['content-transfer-encoding'] = cte resp['multipart-data'].append(params) body = json.dumps(resp, indent=4, sort_keys=True) # default headers hdrs = [('Connection', 'close'), ('Content-Type', 'application/json')] if chunked: hdrs.append(('Transfer-Encoding', 'chunked')) else: hdrs.append(('Content-Length', str(len(body)))) # extra headers if headers: hdrs.extend(headers.items()) if chunked: response.enable_chunked_encoding() # headers response.add_headers(*hdrs) response.send_headers() # write payload if write_body: try: write_body(response, body) except: return else: response.write(helpers.str_to_bytes(body)) response.write_eof() # keep-alive if response.keep_alive(): self._srv.keep_alive(True)
def _response(self, response, body=None, headers=None, chunked=False, write_body=None): r_headers = {} for key, val in self._headers.items(): key = '-'.join(p.capitalize() for p in key.split('-')) r_headers[key] = val encoding = self._headers.get('content-encoding', '').lower() if 'gzip' in encoding: # pragma: no cover cmod = 'gzip' elif 'deflate' in encoding: cmod = 'deflate' else: cmod = '' resp = { 'method': self._method, 'version': '%s.%s' % self._version, 'path': self._uri, 'headers': r_headers, 'origin': self._transport.get_extra_info('addr', ' ')[0], 'query': self._query, 'form': {}, 'compression': cmod, 'multipart-data': [] } if body: # pragma: no cover resp['content'] = body else: resp['content'] = self._body.decode('utf-8') ct = self._headers.get('content-type', '').lower() # application/x-www-form-urlencoded if ct == 'application/x-www-form-urlencoded': resp['form'] = urllib.parse.parse_qs(self._body.decode('latin1')) # multipart/form-data elif ct.startswith('multipart/form-data'): # pragma: no cover out = io.BytesIO() for key, val in self._headers.items(): out.write(bytes('{}: {}\r\n'.format(key, val), 'latin1')) out.write(b'\r\n') out.write(self._body) out.write(b'\r\n') out.seek(0) message = email.parser.BytesParser().parse(out) if message.is_multipart(): for msg in message.get_payload(): if msg.is_multipart(): logging.warning('multipart msg is not expected') else: key, params = cgi.parse_header( msg.get('content-disposition', '')) params['data'] = msg.get_payload() params['content-type'] = msg.get_content_type() resp['multipart-data'].append(params) body = json.dumps(resp, indent=4, sort_keys=True) # default headers hdrs = [('Connection', 'close'), ('Content-Type', 'application/json')] if chunked: hdrs.append(('Transfer-Encoding', 'chunked')) else: hdrs.append(('Content-Length', str(len(body)))) # extra headers if headers: hdrs.extend(headers.items()) if chunked: response.force_chunked() # headers response.add_headers(*hdrs) response.send_headers() # write payload if write_body: try: write_body(response, body) except: return else: response.write(helpers.str_to_bytes(body)) response.write_eof() # keep-alive if response.keep_alive(): self._srv.keep_alive(True)