15 Commits

Author SHA1 Message Date
45d197add4 updated nixpkgs 2024-07-05 20:12:49 +02:00
c191f983fe added header and small fixes 2024-07-05 20:10:03 +02:00
9e83da6b1a added await 2024-04-12 18:02:14 +02:00
c952bd921f updated 2024-04-12 17:37:51 +02:00
1a4d4997da set content type 2024-04-12 17:25:49 +02:00
34d6aa5a36 made async 2024-04-12 17:11:27 +02:00
90e9b9bb05 removed async 2024-04-12 17:05:27 +02:00
44c4f4045f more error handling 2024-04-12 15:17:40 +02:00
95c6ecf8b4 clearer numbers 2024-04-12 15:13:28 +02:00
f34cd88de1 allow multiple binds 2024-04-12 12:44:30 +02:00
a999024ddf changed back, since dash are corrected to underscores by urls 2024-04-12 09:15:26 +02:00
9ef9c8454b use hyphen for query parameter 2024-04-11 23:18:51 +02:00
8f2a575010 typo 2024-04-11 23:18:37 +02:00
654f2982de removed unneeded file 2024-04-11 23:13:17 +02:00
f0230bbbc3 disabled docs 2024-04-11 23:13:11 +02:00
6 changed files with 61 additions and 39 deletions

View File

@ -4,8 +4,9 @@
```json
{
"host": "127.0.0.1",
"port": 9250,
"binds": [
"127.0.0.1:9250"
],
"log": "-",
"buffer-size": "4KiB",
"max-size": "2GB",
@ -13,6 +14,6 @@
"TESTKEY"
],
"max-data": "10GB",
"database": "databse.json"
"database": "database.json"
}
```

30
flake.lock generated
View File

@ -23,11 +23,11 @@
"systems": "systems_2"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
@ -45,11 +45,11 @@
"spectrum": "spectrum"
},
"locked": {
"lastModified": 1712654305,
"narHash": "sha256-CNdpLnGOUZfIhBanAFVF7t1xstaQGL4w6sQPrVeLlus=",
"lastModified": 1720034501,
"narHash": "sha256-fzZpuVnhw5uOtA4OuXw3a+Otpy8C+QV0Uu5XfhGEPSg=",
"owner": "astro",
"repo": "microvm.nix",
"rev": "ee0068ca87bdabbde3cc39b7af807c0302d0304c",
"rev": "a808af7775f508a2afedd1e4940a382fe1194f21",
"type": "github"
},
"original": {
@ -81,11 +81,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1712608508,
"narHash": "sha256-vMZ5603yU0wxgyQeHJryOI+O61yrX2AHwY6LOFyV1gM=",
"lastModified": 1720031269,
"narHash": "sha256-rwz8NJZV+387rnWpTYcXaRNvzUSnnF9aHONoJIYmiUQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "4cba8b53da471aea2ab2b0c1f30a81e7c451f4b6",
"rev": "9f4128e00b0ae8ec65918efeba59db998750ead6",
"type": "github"
},
"original": {
@ -106,11 +106,11 @@
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1708589824,
"narHash": "sha256-2GOiFTkvs5MtVF65sC78KNVxQSmsxtk0WmV1wJ9V2ck=",
"lastModified": 1719850884,
"narHash": "sha256-UU/lVTHFx0GpEkihoLJrMuM9DcuhZmNe3db45vshSyI=",
"owner": "nix-community",
"repo": "poetry2nix",
"rev": "3c92540611f42d3fb2d0d084a6c694cd6544b609",
"rev": "42262f382c68afab1113ebd1911d0c93822d756e",
"type": "github"
},
"original": {
@ -194,11 +194,11 @@
]
},
"locked": {
"lastModified": 1708335038,
"narHash": "sha256-ETLZNFBVCabo7lJrpjD6cAbnE11eDOjaQnznmg/6hAE=",
"lastModified": 1719749022,
"narHash": "sha256-ddPKHcqaKCIFSFc/cvxS14goUhCOAwsM1PbMr0ZtHMg=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "e504621290a1fd896631ddbc5e9c16f4366c9f65",
"rev": "8df5ff62195d4e67e2264df0b7f5e8c9995fd0bd",
"type": "github"
},
"original": {

View File

@ -1,5 +1,5 @@
{
description = "PLACEHOLDER";
description = "A webserver to create files for tetsing purposes";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";

View File

@ -4,7 +4,7 @@ import argparse
import json
from os.path import exists
from fastapi import FastAPI, Request, HTTPException
from fastapi import FastAPI, Request, HTTPException, Query
from fastapi.responses import StreamingResponse
from fastapi import status
from hypercorn.config import Config
@ -32,7 +32,7 @@ if not exists(DATABASE):
save_database(DATABASE, {'data-used': 0})
api = FastAPI()
api = FastAPI(docs_url=None, redoc_url=None)
class MaxSizePerRequestError(Exception):
@ -44,7 +44,7 @@ class MinSizePerRequestError(Exception):
@api.get('/')
def test_data(api_key: str, size: str, request: Request) -> StreamingResponse:
async def test_data(api_key: str, size: str) -> StreamingResponse:
try:
if api_key not in AUTHORIZED_KEYS:
raise HTTPException(
@ -52,7 +52,13 @@ def test_data(api_key: str, size: str, request: Request) -> StreamingResponse:
detail='Invalid API Key.'
)
size = convert_to_bytes(size)
try:
size = convert_to_bytes(size)
except ValueError as err:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Invalid format format for size.'
) from err
if size < 0:
raise MinSizePerRequestError
@ -71,26 +77,30 @@ def test_data(api_key: str, size: str, request: Request) -> StreamingResponse:
return StreamingResponse(
status_code=status.HTTP_200_OK,
content=generate_data(size, BUFFER_SIZE)
content=generate_data(size, BUFFER_SIZE),
media_type='application/octet-stream',
headers={
'Content-Length': size
}
)
except MinSizePerRequestError:
except MinSizePerRequestError as err:
raise HTTPException(
status_code=status.HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE,
detail=f'Size has to be not-negative.'
)
except MaxSizePerRequestError:
detail='Size has to be not-negative.'
) from err
except MaxSizePerRequestError as err:
raise HTTPException(
status_code=status.HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE,
detail=f'Exceeded max size per request of {MAX_SIZE} Bytes.'
)
) from err
def main():
asyncio.run(serve(
api,
Config().from_mapping(
bind=[f"{CONFIG['host']}:{CONFIG['port']}"],
bind=CONFIG['binds'],
accesslog='-'
)
))

View File

View File

@ -1,14 +1,15 @@
import json
import asyncio
def convert_to_bytes(size: int | str) -> int:
try:
return int(size)
except ValueError: # treat as string
units = {
'TB': 10 ** 12, 'TiB': 2 ** 40,
'GB': 10 ** 9, 'GiB': 2 ** 30,
'MB': 10 ** 6, 'MiB': 2 ** 20,
'KB': 10 ** 3, 'KiB': 2 ** 10,
'TB': 1000 ** 4, 'TiB': 1024 ** 4,
'GB': 1000 ** 3, 'GiB': 1024 ** 3,
'MB': 1000 ** 2, 'MiB': 1024 ** 2,
'KB': 1000, 'KiB': 1024,
'B': 1
}
@ -17,15 +18,25 @@ def convert_to_bytes(size: int | str) -> int:
return int(float(size.removesuffix(unit)) * units[unit])
break
raise ValueError
async def generate_data(size: int, buffer_size: int = 4 * 1024) -> bytes:
size_left = size
while size_left > buffer_size:
size_left -= buffer_size
yield b'\0' * buffer_size
else:
yield b'\0' * size_left
# https://github.com/tiangolo/fastapi/issues/5183
# https://github.com/encode/starlette/discussions/1776#discussioncomment-3207518
try:
while size_left > buffer_size:
size_left -= buffer_size
yield b'\0' * buffer_size
await asyncio.sleep(0)
else:
yield b'\0' * size_left
await asyncio.sleep(0)
except asyncio.CancelledError:
raise GeneratorExit
def check_policies(ip: str) -> None: