def test_rountdrip(self): from time import time from waitress.utilities import build_http_date, parse_http_date t = int(time()) self.assertEqual(t, parse_http_date(build_http_date(t)))
def test_rountdrip(self): from waitress.utilities import build_http_date, parse_http_date from time import time t = int(time()) self.assertEqual(t, parse_http_date(build_http_date(t)))
def build_response_header(self): version = self.version # Figure out whether the connection should be closed. connection = self.request.headers.get('CONNECTION', '').lower() response_headers = self.response_headers content_length_header = None date_header = None server_header = None connection_close_header = None for i, (headername, headerval) in enumerate(response_headers): headername = '-'.join( [x.capitalize() for x in headername.split('-')] ) if headername == 'Content-Length': content_length_header = headerval if headername == 'Date': date_header = headerval if headername == 'Server': server_header = headerval if headername == 'Connection': connection_close_header = headerval.lower() # replace with properly capitalized version response_headers[i] = (headername, headerval) if content_length_header is None and self.content_length is not None: content_length_header = str(self.content_length) self.response_headers.append( ('Content-Length', content_length_header) ) def close_on_finish(): if connection_close_header is None: response_headers.append(('Connection', 'close')) self.close_on_finish = True if version == '1.0': if connection == 'keep-alive': if not content_length_header: close_on_finish() else: response_headers.append(('Connection', 'Keep-Alive')) else: close_on_finish() elif version == '1.1': if connection == 'close': close_on_finish() if not content_length_header: response_headers.append(('Transfer-Encoding', 'chunked')) self.chunked_response = True if not self.close_on_finish: close_on_finish() # under HTTP 1.1 keep-alive is default, no need to set the header else: raise AssertionError('neither HTTP/1.0 or HTTP/1.1') # Set the Server and Date field, if not yet specified. This is needed # if the server is used as a proxy. ident = self.channel.server.adj.ident if not server_header: response_headers.append(('Server', ident)) else: response_headers.append(('Via', ident)) if not date_header: response_headers.append(('Date', build_http_date(self.start_time))) first_line = 'HTTP/%s %s' % (self.version, self.status) next_lines = ['%s: %s' % hv for hv in sorted(self.response_headers)] lines = [first_line] + next_lines res = '%s\r\n\r\n' % '\r\n'.join(lines) return tobytes(res)
def build_response_header(self): version = self.version # Figure out whether the connection should be closed. connection = self.request.headers.get('CONNECTION', '').lower() response_headers = self.response_headers content_length_header = None date_header = None server_header = None connection_close_header = None for i, (headername, headerval) in enumerate(response_headers): headername = '-'.join( [x.capitalize() for x in headername.split('-')]) if headername == 'Content-Length': content_length_header = headerval if headername == 'Date': date_header = headerval if headername == 'Server': server_header = headerval if headername == 'Connection': connection_close_header = headerval.lower() # replace with properly capitalized version response_headers[i] = (headername, headerval) if content_length_header is None and self.content_length is not None: content_length_header = str(self.content_length) self.response_headers.append( ('Content-Length', content_length_header)) def close_on_finish(): if connection_close_header is None: response_headers.append(('Connection', 'close')) self.close_on_finish = True if version == '1.0': if connection == 'keep-alive': if not content_length_header: close_on_finish() else: response_headers.append(('Connection', 'Keep-Alive')) else: close_on_finish() elif version == '1.1': if connection == 'close': close_on_finish() if not content_length_header: response_headers.append(('Transfer-Encoding', 'chunked')) self.chunked_response = True if not self.close_on_finish: close_on_finish() # under HTTP 1.1 keep-alive is default, no need to set the header else: raise AssertionError('neither HTTP/1.0 or HTTP/1.1') # Set the Server and Date field, if not yet specified. This is needed # if the server is used as a proxy. ident = self.channel.server.adj.ident if not server_header: response_headers.append(('Server', ident)) else: response_headers.append(('Via', ident)) if not date_header: response_headers.append(('Date', build_http_date(self.start_time))) first_line = 'HTTP/%s %s' % (self.version, self.status) # NB: sorting headers needs to preserve same-named-header order # as per RFC 2616 section 4.2; thus the key=lambda x: x[0] here; # rely on stable sort to keep relative position of same-named headers next_lines = [ '%s: %s' % hv for hv in sorted(self.response_headers, key=lambda x: x[0]) ] lines = [first_line] + next_lines res = '%s\r\n\r\n' % '\r\n'.join(lines) return tobytes(res)
def build_response_header(self): version = self.version # Figure out whether the connection should be closed. connection = self.request.headers.get("CONNECTION", "").lower() response_headers = self.response_headers content_length_header = None date_header = None server_header = None connection_close_header = None for i, (headername, headerval) in enumerate(response_headers): headername = "-".join([x.capitalize() for x in headername.split("-")]) if headername == "Content-Length": content_length_header = headerval if headername == "Date": date_header = headerval if headername == "Server": server_header = headerval if headername == "Connection": connection_close_header = headerval.lower() # replace with properly capitalized version response_headers[i] = (headername, headerval) if content_length_header is None and self.content_length is not None: content_length_header = str(self.content_length) self.response_headers.append(("Content-Length", content_length_header)) def close_on_finish(): if connection_close_header is None: response_headers.append(("Connection", "close")) self.close_on_finish = True if version == "1.0": if connection == "keep-alive": if not content_length_header: close_on_finish() else: response_headers.append(("Connection", "Keep-Alive")) else: close_on_finish() elif version == "1.1": if connection == "close": close_on_finish() if not content_length_header: response_headers.append(("Transfer-Encoding", "chunked")) self.chunked_response = True if not self.close_on_finish: close_on_finish() # under HTTP 1.1 keep-alive is default, no need to set the header else: raise AssertionError("neither HTTP/1.0 or HTTP/1.1") # Set the Server and Date field, if not yet specified. This is needed # if the server is used as a proxy. ident = self.channel.server.adj.ident if not server_header: response_headers.append(("Server", ident)) else: response_headers.append(("Via", ident)) if not date_header: response_headers.append(("Date", build_http_date(self.start_time))) first_line = "HTTP/%s %s" % (self.version, self.status) # NB: sorting headers needs to preserve same-named-header order # as per RFC 2616 section 4.2; thus the key=lambda x: x[0] here; # rely on stable sort to keep relative position of same-named headers next_lines = ["%s: %s" % hv for hv in sorted(self.response_headers, key=lambda x: x[0])] lines = [first_line] + next_lines res = "%s\r\n\r\n" % "\r\n".join(lines) return tobytes(res)