Invoer controleren: maxlength is geen controle
In een formulier kun je met maxlength een grens zetten op een veld. De
browser laat je dan niet verder typen. Maar die grens is een hulp voor wie zich
vergist, geen controle. Met een script zie je waarom, en hoe ver het gaat.
Deed je de uitbreiding JavaScript al, dan ken je het idee uit
Server of browser?; deze les kun je ook
zonder die uitbreiding volgen.
Doe het na, op je eigen server
Start je server uit les 1,
en open het formulier uit de map static:
http://127.0.0.1:8000/static/formulier.html. Typ een lang bericht in het vak
bericht: na 280 tekens gaat er niets meer bij, want maxlength houdt je tegen.
Nu een scriptje groot.py, naast main.py, dat níét via het formulier gaat,
maar rechtstreeks naar het endpoint:
import httpx
adres = "http://127.0.0.1:8000/bericht"
bericht = "a" * 1_000_000
antwoord = httpx.post(adres, data={"naam": "Sara", "bericht": bericht})
print(antwoord.json())
- Regel 5:
Een bericht van een miljoen keer de letter
a. In het formulier kreeg je dit er nooit in.1_000_000is hetzelfde getal als1000000; het liggende streepje maakt het leesbaar. - Regel 6:
Hetzelfde verzoek dat de browser zou sturen, maar zonder de grens uit de HTML.
Draai het met python groot.py, en daarna lees_database.py uit les 1.
Alle miljoen tekens staan in je database. maxlength zat in de HTML, en die
HTML draaide in de browser die je nu hebt overgeslagen. Het endpoint zag alleen
het verzoek, en dat had geen grens.
Eén bericht van een miljoen tekens is al vervelend, en een script dat dat duizend keer doet, vult je schijf.
Eén ruwe grens
Helemaal zonder grens is je server niet. Maak naast groot.py een tweede
script, te_groot.py, met tien miljoen tekens en onderaan ook de statuscode.
groot.py zelf laat je zoals hij is: die heb je in de opdrachten en in les 3
nog nodig.
import httpx
adres = "http://127.0.0.1:8000/bericht"
bericht = "a" * 10_000_000
antwoord = httpx.post(adres, data={"naam": "Sara", "bericht": bericht})
print(antwoord.json())
print(antwoord.status_code)
Uitvoer:
{'detail': 'Field exceeded maximum size of 1024KB.'}
400
Starlette, het deel van FastAPI dat formulieren leest, weigert zelf een veld dat groter is dan een megabyte, ongeveer een miljoen tekens. Het bericht van precies een miljoen kwam er nog net door. Die grens beschermt je tegen het ergste, maar een bericht in een gastenboek hoort geen megabyte te zijn. De echte grens zet je zelf, in les 3.
Er gaat iets mis
Field required in plaats van de lengte
groot.py print geen lengte, maar een melding zoals deze:
{'detail': [{'type': 'missing', 'loc': ['body', 'bericht'], 'msg': 'Field required', 'input': None}]}
Oorzaak: je stuurt geen naam of bericht mee, of de namen in data
komen niet overeen met de Form-parameters, zoals berichten in plaats van
bericht. FastAPI mist dan een verplicht veld en antwoordt met een 422.
Oplossing: stuur beide velden mee, met precies de namen naam en bericht,
net als het formulier.
Wat er in zo'n 422 staat, lees je in les 4. Alle
statuscodes van deze route staan op de startpagina.
Opdrachten
Opdracht 1: Predict - 300 tekens
In het formulier kom je niet verder dan 280 tekens. Je stuurt met een script een bericht van 300 tekens.
Vraag: wat antwoordt de server?
Antwoord
{'lengte': 300}. De server kent de grens van 280 niet: die staat alleen in
de HTML.
Opdracht 2: Investigate - Vijf keer
Draai groot.py, met het bericht van 1_000_000 tekens, vijf keer achter
elkaar, en daarna lees_database.py. Veranderde je groot.py voor opdracht 1,
zet het bericht dan eerst terug op 1_000_000. Hoeveel tekens staan er nu in je
database?
Tip
Tel ook het bericht mee dat er al stond.
Antwoord
Onder je berichten uit het formulier staan zes regels
[Sara] 1000000 tekens: het bericht van daarnet en de vijf nieuwe.
Stuurde je in opdracht 1 echt 300 tekens, dan staat daartussen ook
[Sara] 300 tekens. Het bericht van te_groot.py staat er niet bij: dat
weigerde de server. Samen zes miljoen tekens, en het bestand gastenboek.db is ongeveer zes
megabyte. Elke keer dat het script draait, groeit het. Een script dat niet
stopt, maakt je schijf vol.
Door naar les 3: grenzen in Form.