import subprocess as sp import http import requests import socket import pytest import time host = "127.0.0.1" port = "6994" executable = "./httpd" def spawn_httpd(stdout_filename, args=[]): with open(stdout_filename,"w") as f: httpd_proc = sp.Popen([executable,"--pid_file","/tmp/HTTPd.pid","--ip",host,"--port", port, "--root_dir","test_root_dir/","--server_name","httpd"] if args == [] else [executable] + args, stdout=f,stderr=sp.PIPE,bufsize=0) time.sleep(0.2) return httpd_proc def kill_httpd(proc): #proc.send_signal(sp.SIGINT) proc.kill() # @pytest.mark.timeout(2) def test_bad_config(): proc = spawn_httpd("out.log", ["hello","world"]) proc.wait(1) try: assert proc.returncode == 2 finally: kill_httpd(proc) # @pytest.mark.timeout(2) def test_get_index(): proc = spawn_httpd("out.log") req = requests.get(f"http://{host}:{port}/index.html") assert req.status_code == 200 with open("./test_root_dir/index.html","r") as f: try: assert f.read() == req.text finally: kill_httpd(proc) # @pytest.mark.timeout(2) def test_get_default(): proc = spawn_httpd("out.log") req = requests.get(f"http://{host}:{port}/") assert req.status_code == 200 with open("./test_root_dir/index.html","r") as f: try: assert f.read() == req.text finally: kill_httpd(proc) # @pytest.mark.timeout(2) def test_no_file(): proc = spawn_httpd("out.log") req = requests.get(f"http://{host}:{port}/notindex.html") assert req.status_code == 404 # @pytest.mark.timeout(2) def test_bad_request(): proc = spawn_httpd("out.log") sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((host,int(port))) request = f"GET /index.html FTP/1.1\r\nHOST: {host}:{port}\r\nConnection: close\r\n\r\n" sock.sendall(request.encode()) resp = sock.recv(1024) resp_decoded = resp.decode() try: assert "400 Bad Request" in resp_decoded finally: kill_httpd(proc) # @pytest.mark.timeout(2) def test_invalid_method(): proc = spawn_httpd("out.log") sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((host,int(port))) request = f"PUT /index.html HTTP/1.1\r\nHOST: {host}:{port}\r\nConnection: close\r\n\r\n" sock.sendall(request.encode()) response = http.client.HTTPResponse(sock) response.begin() try: assert response.status == 405 finally: kill_httpd(proc) # @pytest.mark.timeout(2) def test_invalid_version(): proc = spawn_httpd("out.log") sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((host,int(port))) request = f"GET /index.html HTTP/1.2\r\nHOST: {host}:{port}\r\nConnection: close\r\n\r\n" sock.sendall(request.encode()) response = http.client.HTTPResponse(sock) response.begin() try: assert response.status == 505 finally: kill_httpd(proc) # @pytest.mark.timeout(2) def test_bad_request(): proc = spawn_httpd("out.log") sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((host,int(port))) request = f"GET /index.html FTP/1.1\r\nHOST: {host}:{port}\r\nConnection: close\r\n\r\n" sock.sendall(request.encode()) response = http.client.HTTPResponse(sock) response.begin() try: assert response.status == 400 finally: kill_httpd(proc) @pytest.mark.timeout(2) def test_head_index(): proc = spawn_httpd("out.log") try: req = requests.head(f"http://{host}:{port}/index.html") assert req.status_code == 200 assert req.text == "" finally: kill_httpd(proc) @pytest.mark.timeout(2) def test_missing_host(): proc = spawn_httpd("out.log") sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((host,int(port))) request = f"GET /index.html HTTP/1.1\r\nConnection: close\r\n\r\n" sock.sendall(request.encode()) response = http.client.HTTPResponse(sock) response.begin() try: assert response.status == 400 finally: kill_httpd(proc) @pytest.mark.timeout(2) def test_directory_traversal(): proc = spawn_httpd("out.log") sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((host,int(port))) request = f"GET /../test_suite.py HTTP/1.1\r\nHOST: {host}:{port}\r\nConnection: close\r\n\r\n" sock.sendall(request.encode()) response = http.client.HTTPResponse(sock) response.begin() try: assert response.status in [400, 403, 404] finally: kill_httpd(proc)