def test_http_1_1_compliance(self): """ Test Name: test_http_1_1_compliance\n\ Number Connections: 1 \n\ Procedure: Ensure a persistent connection by sending two consecutive\n\ requests to the server on one connection. """ #Make HTTP connection for the server self.http_connection = httplib.HTTPConnection(self.hostname, self.port) #Connect to the server self.http_connection.connect() for x in range(0, 2): #GET request for the object /loadavg self.http_connection.request("GET", "/loadavg") #Get the server's response server_response = self.http_connection.getresponse() #Check the response status code self.assertEqual(server_response.status, httplib.OK, "Server failed to respond") #Check the data included in the server's response self.assertTrue(server_check.check_loadavg_response(server_response.read()), \ "loadavg check failed") self.http_connection.close()
def test_file_descriptor_leak(self): """ Test Name: test_file_descriptor_leak\n\ Number Connections: 2000, but only one is connected at a time \n\ Procedure: 2000 connections are processed as follows: \n\ 1. Make the connection\n\ 2. Test a /loadavg request\n\ 3. Close the connection\n\ IMPORTANT NOTE: May also thread/fork-bomb your server! """ for x in range(2000): http_connection = httplib.HTTPConnection(hostname, port) # avoid TCP listen overflows http_connection.connect() http_connection.sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 1)) #GET request for the object /loadavg http_connection.request("GET", "/loadavg") #Get the server's response server_response = http_connection.getresponse() #Check the response status code assert server_response.status == httplib.OK, "Server failed to respond" #Check the data included in the server's response assert server_check.check_loadavg_response(server_response.read()), \ "loadavg check failed" http_connection.close()
def test_file_descriptor_leak(self): """ Test Name: test_file_descriptor_leak\n\ Number Connections: 2000, but only one is connected at a time \n\ Procedure: 2000 connections are processed as follows: \n\ 1. Make the connection\n\ 2. Test a /loadavg request\n\ 3. Close the connection\n\ IMPORTANT NOTE: May also thread/fork-bomb your server! """ start = time.time() for x in range(2000): http_connection = httplib.HTTPConnection(hostname, port) # avoid TCP listen overflows http_connection.connect() http_connection.sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 1)) #GET request for the object /loadavg http_connection.request("GET", "/loadavg") #Get the server's response server_response = http_connection.getresponse() #Check the response status code assert server_response.status == httplib.OK, "Server failed to respond" #Check the data included in the server's response assert server_check.check_loadavg_response(server_response.read()), \ "loadavg check failed" http_connection.close() if time.time() - start > 60: raise Error, "Timeout - took more than 60 seconds"
def test_http_1_1_compliance(self): """ Test Name: test_http_1_1_compliance\n\ Number Connections: 1 \n\ Procedure: Ensure a persistent connection by sending two consecutive\n\ requests to the server on one connection. """ #Make HTTP connection for the server self.http_connection = httplib.HTTPConnection(self.hostname, self.port) #Connect to the server self.http_connection.connect() for x in range(0, 2): #GET request for the object /loadavg self.http_connection.request("GET", "/loadavg") #Get the server's response server_response = self.http_connection.getresponse() #Check that the server did not close the connection self.assertEqual(server_response._check_close(),False,\ "Server closed the connection") #Check the response status code self.assertEqual(server_response.status, httplib.OK, "Server failed to respond") #Check the data included in the server's response self.assertTrue(server_check.check_loadavg_response(server_response.read()), \ "loadavg check failed") self.http_connection.close()
def test_byte_wise_request(self): """ Test Name: test_byte_wise_request\n\ Number Connections: 1\n\ Procedure: Send a request for GET /loadavg HTTP/1.1 byte by byte.\n\ """ #Make the low-level connection sock = server_check.get_socket_connection(self.hostname, self.port) for x in "GET /loadavg HTTP/1.0\r\nHost: " + self.hostname + "\r\n": sock.send(x) time.sleep(0.1) sock.settimeout(1) msg_buffer = '' try: if sock.recv(4096, socket.MSG_PEEK) != '': self.fail("Data was returned before the extra \r\n") #We want nothing back until after we've sent the last \r\n except socket.timeout: pass if msg_buffer != '': self.fail("The server responded before the full request was sent.") sock.send("\r") sock.send("\n") time.sleep(0.1) #Collect the response try: while sock.recv(4096, socket.MSG_PEEK) != '': data = sock.recv(4096) msg_buffer = msg_buffer + data except socket.timeout: self.fail("The socket timed out on responding to the message.") #Check the response data = data.split("\r\n\r\n") if len(data) == 2 and server_check.check_loadavg_response(data[1]): pass elif len(data) != 2: self.fail("The server did not return the proper loadavg data") else: self.fail("A proper loadavg object was not returned.") sock.close()
def test_http_1_0_compliance(self): """ Test Name: test_http_1_0_compliance\n\ Number Connections: 1 \n\ Procedure: Writes "GET /loadavg HTTP/1.0\\r\\n" to the server, then \n\ checks nothing has been returned, and finishes with the \n\ extra "\\r\\n" and checking the data sent back from the \n\ server. """ #Make HTTP connection for the server sock = server_check.get_socket_connection(self.hostname, self.port) sock.send("GET /loadavg HTTP/1.0\r\n") sock.send("Host: " + self.hostname + "\r\n") sock.settimeout(1) time.sleep(.1) try: if sock.recv(4096, socket.MSG_PEEK) != '': self.fail("The http response was returned too early, before" +\ " the extra \r\n line.") except socket.timeout: pass sock.send("\r\n") #If there is a HTTP response, it should be a valid /loadavg #response. data = "" time.sleep(0.1) try: while sock.recv(4096, socket.MSG_PEEK) != '': msg_buffer = sock.recv(4096) data = data + msg_buffer #Connections close after responses for HTTP/1.0 , therefore a timeout #should not occur. except socket.timeout: self.fail( "The server did not respond and close the connection in sufficient time." ) data = data.split("\r\n\r\n") assert len(data) == 2, \ "The response could not be parsed, check your use of \\r\\n" assert server_check.check_loadavg_response(data[1]), \ "The /loadavg object was not properly returned." sock.close()
def test_http_1_0_compliance(self): """ Test Name: test_http_1_0_compliance\n\ Number Connections: 1 \n\ Procedure: Writes "GET /loadavg HTTP/1.0\\r\\n" to the server, then \n\ checks nothing has been returned, and finishes with the \n\ extra "\\r\\n" and checking the data sent back from the \n\ server. """ #Make HTTP connection for the server sock = server_check.get_socket_connection(self.hostname, self.port) sock.send("GET /loadavg HTTP/1.0\r\n") sock.send("Host: " + self.hostname + "\r\n") sock.settimeout(1) time.sleep(.1) try: if sock.recv(4096, socket.MSG_PEEK) != '': self.fail("The http response was returned too early, before" +\ " the extra \r\n line.") except socket.timeout: pass sock.send("\r\n") #If there is a HTTP response, it should be a valid /loadavg #response. data = "" time.sleep(0.1) try: while sock.recv(4096, socket.MSG_PEEK) != '': msg_buffer = sock.recv(4096) data = data + msg_buffer #Connections close after responses for HTTP/1.0 , therefore a timeout #should not occur. except socket.timeout: self.fail("The server did not respond and close the connection in sufficient time.") data = data.split("\r\n\r\n") assert len(data) == 2, \ "The response could not be parsed, check your use of \\r\\n" assert server_check.check_loadavg_response(data[1]), \ "The /loadavg object was not properly returned." sock.close()
def test_loadavg_no_callback(self): """ Test Name: test_loadavg_no_callback\n\ Number Connections: One \n\ Procedure: Simple GET request:\n\ GET /loadavg HTTP/1.1 """ #GET request for the object /loadavg self.http_connection.request("GET", "/loadavg") #Get the server's response server_response = self.http_connection.getresponse() #Check the response status code self.assertEqual(server_response.status, httplib.OK, "Server failed to respond") #Check the data included in the server's response self.assertTrue(server_check.check_loadavg_response(server_response.read()), \ "loadavg check failed")
def test_80_kb_URI(self): """ Test Name: test_80_kb_URI\n\ Number Connections: 1\n\ Procedure: Send a GET request for a URI object that is 80kb long.\n\ Then check that another connection and request can still\n\ be made. Also, ensure that an appropriate response is\n\ sent to the 80kb request.\n\ """ sock = server_check.get_socket_connection(self.hostname, self.port) sock.send("GET ") for x in range(1, 10240): sock.send("/loadavg") sock.send(" HTTP/1.1\r\n") sock.send("Host: " + self.hostname + "\r\n\r\n") #If there is a HTTP response, it should NOT be a valid /loadavg #response. All other responses are fine, including closing the #connection, so long as the server continues serving other connections sock.settimeout(1) data = "" time.sleep(0.1) try: while sock.recv(4096, socket.MSG_PEEK) != '': msg_buffer = sock.recv(4096) data = data + msg_buffer #Socket timeouts are not expected for HTTP/1.0 , therefore an open #connection is bad. except socket.timeout: pass data = data.split("\r\n\r\n") try: if len(data) >= 2 and server_check.check_loadavg_response(data[1]): self.fail("A valid /loadavg object was returned for an invalid request.") #If an error is generated, it comes from trying to an interpret a JSON #object that doesn't exist. except (AssertionError, ValueError): pass sock.close() #Make HTTP connection for the server self.http_connection = httplib.HTTPConnection(self.hostname, self.port) #Connect to the server self.http_connection.connect() #GET request for the object /loadavg self.http_connection.request("GET", "/loadavg") #Get the server's response server_response = self.http_connection.getresponse() #Check the response status code self.assertEqual(server_response.status, httplib.OK, "Server failed to respond") #Check the data included in the server's response self.assertTrue(server_check.check_loadavg_response(server_response.read()), \ "loadavg check failed") self.http_connection.close()
def test_80_kb_URI(self): """ Test Name: test_80_kb_URI\n\ Number Connections: 1\n\ Procedure: Send a GET request for a URI object that is 80kb long.\n\ Then check that another connection and request can still\n\ be made. Also, ensure that an appropriate response is\n\ sent to the 80kb request.\n\ """ sock = server_check.get_socket_connection(self.hostname, self.port) sock.send("GET ") data = '' try: for x in range(1, 10240): sock.send("/loadavg") sock.send(" HTTP/1.1\r\n") sock.send("Host: " + self.hostname + "\r\n\r\n") #If there is a HTTP response, it should NOT be a valid /loadavg #response. All other responses are fine, including closing the #connection, so long as the server continues serving other connections sock.settimeout(1) data = "" time.sleep(0.1) while sock.recv(4096, socket.MSG_PEEK) != '': msg_buffer = sock.recv(4096) data = data + msg_buffer #Socket timeouts are not expected for HTTP/1.0 , therefore an open #connection is bad. except socket.timeout: pass except SocketError as e: if e.errno != errno.ECONNRESET: raise data = data.split("\r\n\r\n") try: if len(data) >= 2 and server_check.check_loadavg_response(data[1]): self.fail( "A valid /loadavg object was returned for an invalid request." ) #If an error is generated, it comes from trying to an interpret a JSON #object that doesn't exist. except (AssertionError, ValueError): pass sock.close() #Make HTTP connection for the server self.http_connection = httplib.HTTPConnection(self.hostname, self.port) #Connect to the server self.http_connection.connect() #GET request for the object /loadavg self.http_connection.request("GET", "/loadavg") #Get the server's response server_response = self.http_connection.getresponse() #Check the response status code self.assertEqual(server_response.status, httplib.OK, "Server failed to respond") #Check the data included in the server's response self.assertTrue(server_check.check_loadavg_response(server_response.read()), \ "loadavg check failed") self.http_connection.close()