Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ repos:
rev: v1.10.0
hooks:
- id: mypy
exclude: 'tests'

# run local pylint in venv
- repo: local
Expand All @@ -50,7 +51,7 @@ repos:
- --max-line-length=120
- --ignore-imports=yes
- -d duplicate-code
- -d C0111,W0621,R0913,R1705, W0201
- -d C0111,W0621,R0913,R1705,W0201,W0613


- repo: https://github.com/asottile/pyupgrade
Expand Down
9 changes: 9 additions & 0 deletions homework_07/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Задача
Реализовать сервер, частично реализующий протокол HTTP, в частности методы GET и HEAD, добиться того, что код проходит предоставленные функциональны тесты. Архитектуру выбрать на свое усмотрение, исходя из вариантов, рассмотренных на занятии. Провести нагрузочное тестирование с помощью ab или wrk

# Запуск тестов
```
sh ab -n 1000 -c 10 http://localhost:8080/index.html

wrk -t12 -c400 -d30s http://localhost:8080/index.html
```
184 changes: 184 additions & 0 deletions homework_07/poetry.lock

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions homework_07/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[tool.poetry]
name = "homework-07"
version = "0.1.0"
description = "Реализовать сервер, частично реализующий протокол HTTP. Провести нагрузочное тестирование"
authors = ["Vladislav Kozlov <vlad.kv.2002@gmail.com>"]
license = "MIT"
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.32.3"
types-requests = "^2.32.0.20250328"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
2 changes: 2 additions & 0 deletions homework_07/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# flake8: noqa
import web_server
26 changes: 26 additions & 0 deletions homework_07/tests/test_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import threading
import time

import pytest
import requests
from web_server import HOST, PORT, start_server


@pytest.fixture(scope="module")
def server():
server_thread = threading.Thread(target=start_server)
server_thread.start()
time.sleep(1) # start delay
yield


def test_index_page(server):
response = requests.get(f"http://{HOST}:{PORT}/", timeout=1)
assert response.status_code == 200
assert "index.html" in response.text


def test_not_found_page(server):
response = requests.get(f"http://{HOST}:{PORT}/noexist_page.html", timeout=1)
assert response.status_code == 404
assert "File Not Found" in response.text
57 changes: 57 additions & 0 deletions homework_07/web_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import os
import socket
import threading

HOST = "localhost"
PORT = 8080
DOCUMENT_ROOT = "./www"


def handle_request(client_socket):
request = ""
try:
# while True:
request = client_socket.recv(1024).decode()
# 2. get headers
headers = request.split("\r\n")
# 3. split headers to methods
method, path, protocol = headers[0].split(" ")
# 4. give back response
if method in ["GET", "HEAD"]:
if path == "/":
path = os.path.join(DOCUMENT_ROOT, "index.html")
if os.path.exists(path):
with open(path, "rb") as f:
content = f.read()
response = (
f"{protocol} 200 OK\r\nContent-Length: {len(content)}\r\n".encode()
)
if method == "GET":
response = response + content
else:
response = b"HTTP/1.1 404 Not Found\r\nFile Not Found"

client_socket.sendall(response)
finally:
client_socket.close()


def start_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = (HOST, PORT)
server_socket.bind(server_address)
server_socket.listen(5) # Allows up to 5 queued connections
print(f"Server listening on {server_address}")
try:
while True:
client_socket, _ = server_socket.accept()
client_thread = threading.Thread(
target=handle_request, args=(client_socket,)
)
client_thread.start()
finally:
server_socket.close()


if __name__ == "__main__":
start_server()
10 changes: 10 additions & 0 deletions homework_07/www/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title> Hello from a simple web server! </title>
</head>
<body>

</body>
</html>