about summary refs log tree commit diff
path: root/src/APIv1.py
blob: f163c5baae7569f2e99580733439405c48ceaf8d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import random
from src.request import *
from src.status_code import *


API_FILE_RANDOM_MIN_SIZE_LIMIT = 1
API_FILE_RANDOM_MAX_SIZE_LIMIT = 2**30 * 2


def random_data_gen(size: int) -> bytes:
    """
    Generates SIZE bytes of random data in 64kib chunks
    :param size: bytes to generate
    :return: random bytes
    """

    data = bytearray()
    int_size = size // 65536
    for _ in range(int_size):
        data += random.randbytes(65536)
    data += random.randbytes((int_size * 65536) - size)

    return data


def decode_size(size: str) -> int:
    """
    Decodes size string like '128mib' and converts it to int size in bytes
    :param size: size string
    :return: number of bytes
    """

    # split string into number and size modifier
    int_string = ""
    size_modifier = ""
    integer = True
    for char in size:
        if not char.isdigit():
            integer = False
        if integer:
            int_string += char
        else:
            size_modifier += char
    size = int(int_string)

    # multiply size by size modifier
    match size_modifier:
        case "b":  # bytes
            pass
        case "kib":  # kibibytes
            size *= 2**10
        case "mib":  # mebibytes
            size *= 2**20
        case "gib":  # gibibytes
            size *= 2**30
        case _:
            pass

    return size


def api_call(client: SSLSocket, request: Request) -> Response:
    """
    Respond to clients API request
    """

    # decode API request
    split_path = request.path.split("/", maxsplit=16)[1:]

    # do something with it (oh god)
    if len(split_path) > 1 and split_path[1] == "file":
        if len(split_path) > 2 and split_path[2] == "random":
            # get size
            size_str = request.path_args.get("size", "16mib")
            size = decode_size(size_str)

            # check size
            if size < API_FILE_RANDOM_MIN_SIZE_LIMIT or size > API_FILE_RANDOM_MAX_SIZE_LIMIT:
                return Response(b'', STATUS_CODE_BAD_REQUEST)

            return Response(random_data_gen(size), STATUS_CODE_OK, compress=False)
        else:
            return Response(b'', STATUS_CODE_BAD_REQUEST)
    else:
        return Response(b'', STATUS_CODE_BAD_REQUEST)