Κάθε API που εκτίθεται στο διαδίκτυο δέχεται δεδομένα από πηγές που δεν ελέγχει πλήρως. Για παράδειγμα, ένα απλό JSON endpoint που περιμένει λίγα KB μπορεί να δεχτεί ένα payload δεκάδων MB. Αν αυτό το request φτάσει μέχρι το parsing ή το model binding, το σύστημα έχει ήδη πληρώσει κόστος σε μνήμη και CPU. Αυτό σημαίνει ότι το σύστημα πρέπει να είναι προετοιμασμένο όχι μόνο για “σωστά” requests, αλλά και για:
- λανθασμένα payloads
- υπερβολικά μεγάλα δεδομένα
- κακόβουλη χρήση
Ένα από τα βασικά εργαλεία για την αντιμετώπιση αυτών των περιπτώσεων είναι τα request size limits.
Δεν πρόκειται για απλή ρύθμιση. Είναι μηχανισμός προστασίας που πρέπει να τοποθετηθεί σωστά στην αρχιτεκτονική.
Η ανάγκη για όρια
Αν δεν υπάρχει κανένα όριο στο μέγεθος ενός request, το σύστημα εκτίθεται σε πραγματικά προβλήματα.
Πρώτον, υπάρχει ο κίνδυνος εξάντλησης πόρων. Ένα μεγάλο request μπορεί να καταναλώσει μνήμη και CPU, ειδικά όταν πρόκειται για JSON που πρέπει να γίνει parsing ή για αρχεία που πρέπει να διαβαστούν.
Δεύτερον, υπάρχει ο κίνδυνος επιθέσεων. Ένα API χωρίς limits μπορεί να δεχτεί συνεχόμενα μεγάλα requests και να οδηγηθεί σε κατάσταση όπου δεν μπορεί να εξυπηρετήσει νόμιμους χρήστες.
Τρίτον, ακόμα και χωρίς κακή πρόθεση, ένας client μπορεί να στείλει λάθος δεδομένα λόγω bug. Το σύστημα πρέπει να προστατεύεται και από αυτό.
Τέλος, υπάρχει και η επιχειρησιακή διάσταση. Δεν έχουν όλα τα endpoints τις ίδιες ανάγκες. Ένα endpoint για avatar δεν πρέπει να δέχεται το ίδιο μέγεθος δεδομένων με ένα endpoint για document upload.
Τι είναι το request size limit
Είναι ένα όριο στο μέγεθος του body ενός HTTP request. Αν το request ξεπεράσει αυτό το όριο, απορρίπτεται πριν επεξεργαστεί περαιτέρω.
Η απόρριψη γίνεται με HTTP status:
413 Payload Too Large
Το σημαντικό δεν είναι μόνο ότι απορρίπτεται, αλλά πού απορρίπτεται.
Η έννοια των layers
Ένα request δεν φτάνει απευθείας στον controller. Περνά από πολλαπλά επίπεδα.
Client
↓
Reverse Proxy / Gateway (IIS, Azure, nginx)
↓
Kestrel (web server)
↓
ASP.NET pipeline (Middleware)
↓
API endpoint
↓
Controller
Κάθε επίπεδο έχει τη δυνατότητα να εφαρμόσει limit.
Η σωστή αρχιτεκτονική δεν βασίζεται σε ένα σημείο, αλλά σε διαδοχικά επίπεδα ελέγχου.
Τα επίπεδα και ο ρόλος τους
Reverse Proxy / Gateway
Αυτό είναι το εξωτερικό όριο του συστήματος.
Σε αυτό το σημείο το request μπορεί να απορριφθεί πριν φτάσει καν στην εφαρμογή. Αυτό σημαίνει ότι δεν καταναλώνονται application resources.
Είναι το πιο αποδοτικό σημείο για να απορρίπτονται υπερβολικά μεγάλα requests.
Kestrel (server level)
Ο Kestrel είναι ο web server που τρέχει την ASP.NET Core εφαρμογή.
Σε αυτό το επίπεδο ορίζεται ένα γενικό όριο για όλη την εφαρμογή, λειτουργώντας ως μηχανισμός προστασίας:
- αποτρέπει μεγάλα requests πριν μπουν στο pipeline
- καλύπτει όλα τα endpoints
- λειτουργεί ως safety net
Το όριο αυτό εκφράζει το τι μπορεί να αντέξει τεχνικά το σύστημα, όχι απαραίτητα το τι επιτρέπεται επιχειρησιακά.
Ωστόσο, σε cloud περιβάλλοντα όπως το Azure, οι περιορισμοί του Kestrel δεν αποτελούν πάντα το τελικό σημείο ελέγχου. Ένα request μπορεί να έχει ήδη περάσει από upstream managed layers (π.χ. gateways, front ends) που εφαρμόζουν δικούς τους περιορισμούς, ενώ σε ορισμένα hosting μοντέλα (όπως Azure Functions in-process) το HTTP pipeline δεν ελέγχεται άμεσα από τον προγραμματιστή.
Συνεπώς, τα application-level limits θα πρέπει να αντιμετωπίζονται ως ένα επιπλέον επίπεδο προστασίας και όχι ως η μοναδική γραμμή άμυνας.
ASP.NET / API επίπεδο
Σε αυτό το επίπεδο βρίσκονται τα endpoints.
Εδώ εφαρμόζονται limits μέσω μηχανισμών όπως:
[RequestSizeLimit(...)]
Τα limits αυτά εκφράζουν επιχειρησιακούς κανόνες χρήσης και όχι τεχνικούς περιορισμούς του συστήματος. Δηλαδή καθορίζουν τι επιτρέπεται ανά endpoint, ανεξάρτητα από το τι μπορεί να αντέξει συνολικά η εφαρμογή.
Παραδείγματα:
- avatar upload: 3 MB
- document upload: 25 MB
- JSON request: 512 KB
Τα endpoint-level limits λειτουργούν συμπληρωματικά με τα υπόλοιπα επίπεδα (π.χ. Kestrel, gateway), επιτρέποντας πιο granular έλεγχο ανά use case.
Ωστόσο, όπως και με τα application-level limits, οι περιορισμοί αυτοί δεν εγγυώνται ότι το request θα φτάσει στο endpoint, καθώς μπορεί να απορριφθεί νωρίτερα από upstream layers.
Hosting Model & Azure Plan: Ποιος ελέγχει πραγματικά το pipeline;
Σε Azure περιβάλλοντα, ειδικά όταν χρησιμοποιούνται Azure Functions, το ποιος ελέγχει το HTTP request pipeline δεν είναι πάντα προφανές και εξαρτάται από δύο βασικούς παράγοντες: το hosting model και το deployment plan.
Στο in-process model, το application εκτελείται μέσα στο ίδιο process με το Functions runtime. Αυτό σημαίνει ότι το HTTP pipeline διαχειρίζεται πλήρως από την πλατφόρμα και δεν υπάρχει άμεσος έλεγχος στον underlying server (π.χ. Kestrel). Οι ρυθμίσεις που θα εφαρμόζονταν σε ένα τυπικό ASP.NET Core application δεν έχουν απαραίτητα το ίδιο αποτέλεσμα.
Αντίθετα, στο isolated worker model, το application τρέχει σε ξεχωριστό process και μπορεί να αξιοποιήσει ASP.NET Core integration. Σε αυτή την περίπτωση, υπάρχει δυνατότητα ελέγχου του request pipeline (middleware, filters, limits), προσεγγίζοντας τη συμπεριφορά ενός κλασικού Web API.
Βασικές διαφορές στην πράξη (isolated vs in-process)
Η ουσιαστική διαφορά μεταξύ των δύο μοντέλων δεν είναι μόνο το process isolation, αλλά το επίπεδο ελέγχου και παραμετροποίησης του HTTP pipeline. Στο in-process model, το request περνά αποκλειστικά μέσα από το Functions runtime, το οποίο ορίζει τη ροή εκτέλεσης και επιβάλλει περιορισμούς πριν το application code αποκτήσει έλεγχο. Αυτό σημαίνει ότι δεν υπάρχει πραγματικό ASP.NET Core pipeline, ούτε δυνατότητα χρήσης middleware, και κατά συνέπεια οι έννοιες όπως Kestrel-level limits ή request filtering δεν εφαρμόζονται με τον ίδιο τρόπο. Αντίθετα, στο isolated model, το application μπορεί να “χτίσει” το δικό του pipeline μέσω ASP.NET Core integration, επιτρέποντας την εισαγωγή middleware, custom handling και πιο granular έλεγχο στη ροή των requests. Παρ’ όλα αυτά, ακόμη και σε αυτή την περίπτωση, το pipeline δεν είναι πλήρως αυτόνομο, καθώς προηγούνται πάντα managed layers της πλατφόρμας που ενδέχεται να επιβάλλουν δικούς τους περιορισμούς.
Ωστόσο, το Azure plan επηρεάζει σημαντικά το επίπεδο ελέγχου:
Στο Consumption plan, το request περνάει από managed infrastructure layers της πλατφόρμας πριν φτάσει στο application, επιβάλλοντας περιορισμούς ανεξάρτητα από το application configuration.
Στα Premium ή App Service plans, το περιβάλλον είναι πιο κοντά σε παραδοσιακό hosting, επιτρέποντας μεγαλύτερο έλεγχο στο HTTP pipeline και καλύτερη αξιοποίηση του ASP.NET Core stack.
Σε κάθε περίπτωση, είναι σημαντικό να σημειωθεί ότι τα upstream layers (Azure infrastructure, reverse proxies, gateways) ενδέχεται να εφαρμόζουν αυστηρότερους περιορισμούς από αυτούς που ορίζονται στο application. Αυτό σημαίνει ότι ένα request μπορεί να απορριφθεί πριν φτάσει ποτέ στο ASP.NET Core pipeline, ανεξάρτητα από τις ρυθμίσεις που έχουν οριστεί σε επίπεδο middleware ή API.
Κατά συνέπεια, πριν βασιστούμε σε application-level περιορισμούς, είναι απαραίτητο να κατανοήσουμε αν το περιβάλλον εκτέλεσης μας επιτρέπει πραγματικά να τους εφαρμόσουμε και ποιο layer έχει τον τελικό έλεγχο στην αποδοχή ή απόρριψη ενός request.
Σημείωση για συμβατικά Web Applications (App Service)
Σε αντίθεση με τα serverless σενάρια (π.χ. Azure Functions), σε ένα τυπικό ASP.NET Core Web Application που φιλοξενείται στο Azure App Service, η εφαρμογή εκτελείται πάντα πάνω στον Kestrel. Ακόμη και όταν υπάρχει IIS (σε Windows environments) ή άλλο reverse proxy μπροστά, αυτά λειτουργούν ως ενδιάμεσο layer που προωθεί τα requests, ενώ ο Kestrel παραμένει ο πραγματικός web server που εκτελεί το ASP.NET Core pipeline. Συνεπώς, server-level ρυθμίσεις (όπως request size limits) εξακολουθούν να υφίστανται στο application runtime, ακόμη και αν δεν είναι πάντα άμεσα ορατές ή πλήρως ελέγξιμες από τον προγραμματιστή.
Ρόλος του Azure Front Door στο request pipeline
Σε cloud αρχιτεκτονικές, ένα επιπλέον επίπεδο που συχνά προηγείται του application είναι το Azure Front Door. Το Front Door λειτουργεί ως global entry point και reverse proxy, δρομολογώντας τα requests προς τα backend services. Σε αυτό το επίπεδο μπορούν να εφαρμοστούν περιορισμοί όπως request size limits, rate limiting, WAF κανόνες και άλλοι μηχανισμοί προστασίας. Καθώς βρίσκεται πριν από το application και τον web server, έχει τη δυνατότητα να απορρίπτει requests πολύ νωρίς, μειώνοντας σημαντικά το load που φτάνει στο σύστημα. Ωστόσο, όπως και με κάθε upstream layer, οι περιορισμοί του Front Door υπερισχύουν των downstream ρυθμίσεων, καθώς ένα request που απορρίπτεται σε αυτό το επίπεδο δεν φτάνει ποτέ στο ASP.NET Core pipeline.
Πώς συνεργάζονται τα επίπεδα
[ Internet ]
│
[ CDN / WAF ]
"Early rejection"
│
[ Reverse Proxy ]
"HTTP body/header limits"
│
[ Kestrel/IIS ]
"Transport/server limits"
│
[ Middleware ]
"Request inspection & logging"
│
[ MVC / Controllers ]
"Business validation"
│
[ Services ]
Το request περνά διαδοχικά από τα επίπεδα και σταματά στο πρώτο που θα παραβιάσει.
Αν ένα request είναι μεγαλύτερο από το όριο του proxy, δεν φτάνει ποτέ στον Kestrel.
Αν περάσει τον proxy αλλά είναι μεγαλύτερο από το Kestrel limit, απορρίπτεται εκεί.
Αν περάσει και τα δύο αλλά παραβιάζει το endpoint limit, απορρίπτεται στο API επίπεδο.
Αυτό δημιουργεί μια αλυσίδα προστασίας.
Στην πράξη, το πιο περιοριστικό upstream layer είναι αυτό που καθορίζει το τελικό αποδεκτό μέγεθος request, ανεξάρτητα από τις ρυθμίσεις των downstream επιπέδων.
Γιατί δεν αρκεί ένα μόνο επίπεδο
Αν βάλουμε limit μόνο στο API:
- το request έχει ήδη φτάσει στον server
- έχουν δεσμευτεί πόροι
- η προστασία έρχεται αργά
Αν βάλουμε μόνο στο Kestrel:
- προστατεύεται το σύστημα
- αλλά δεν εκφράζονται business rules
Αν βάλουμε μόνο στο proxy:
- προστατεύεται η είσοδος
- αλλά δεν υπάρχει έλεγχος ανά endpoint
Καμία μεμονωμένη λύση δεν καλύπτει πλήρως το πρόβλημα.
Η σωστή προσέγγιση είναι ο συνδυασμός επιπέδων, όπου κάθε layer αναλαμβάνει διαφορετικό ρόλο: προστασία υποδομής, έλεγχος πόρων και εφαρμογή επιχειρησιακών κανόνων.
Όσο πιο νωρίς απορριφθεί ένα υπερβολικό request, τόσο λιγότερους πόρους καταναλώνει το σύστημα.
Ένα request που απορρίπτεται στο edge ή στο reverse proxy δεν φτάνει ποτέ σε parsing, model binding ή business logic.
Διαχωρισμός ευθυνών
Η αρχιτεκτονική γίνεται πιο καθαρή όταν ξεχωρίζουμε τι ανήκει πού.
Το Kestrel limit είναι infrastructure concern. Εξαρτάται από:
- το περιβάλλον εκτέλεσης
- το διαθέσιμο memory/CPU budget
- το expected load του συστήματος
Για αυτό τον λόγο πρέπει να είναι configurable και environment-specific, συνήθως μέσω ρυθμίσεων όπως το appsettings.
Αντίθετα, τα API-level limits αποτελούν business rules. Ορίζονται στο application layer και εκφράζουν τι επιτρέπεται λειτουργικά ανά endpoint ή use case, ανεξάρτητα από το υποκείμενο infrastructure.
Ο σωστός διαχωρισμός είναι αυτός που επιτρέπει στο σύστημα να παραμένει σταθερό τεχνικά, ενώ οι επιχειρησιακοί κανόνες εξελίσσονται ανεξάρτητα από την υποδομή.
Μην βασίζεσαι αποκλειστικά στο frontend validation.
Κάθε layer πρέπει να θεωρεί το request μη έμπιστο.
Τι προστατεύουν οι περιορισμοί μεγέθους
Οι περιορισμοί μεγέθους δεν προστατεύουν μόνο από μεγάλα uploads.
Προστατεύουν επίσης από:
- memory exhaustion
- υπερβολικό JSON parsing
- επιθέσεις μέσω oversized payloads
- κατάχρηση file uploads
- αυξημένη κατανάλωση CPU και bandwidth
Logging και Filtering: Middleware vs Controller Layer
Η τοποθέτηση του logging και των request validations (όπως έλεγχοι μεγέθους ή απορρίψεις requests) αποτελεί κρίσιμη αρχιτεκτονική απόφαση. Σε γενικές γραμμές, οι cross-cutting concerns όπως το logging, το error handling και οι βασικοί τεχνικοί περιορισμοί (π.χ. request size limits) ανήκουν στο επίπεδο του middleware. Σε αυτό το σημείο του pipeline, το request μπορεί να καταγραφεί και να απορριφθεί νωρίς, πριν ενεργοποιηθούν μηχανισμοί όπως routing, model binding ή controllers, μειώνοντας το κόστος επεξεργασίας και βελτιώνοντας την απόδοση του συστήματος.
Σε αυτό το στάδιο έχουμε ήδη πρόσβαση σε HTTP metadata όπως headers, Content-Length και stream δεδομένων, χωρίς να έχει εκτελεστεί ακόμα model binding ή business logic.
Αυτό επιτρέπει την έγκαιρη απόρριψη προβληματικών requests πριν καταναλωθούν επιπλέον πόροι της εφαρμογής.
Αντίθετα, η υλοποίηση αυτών των ελέγχων σε επίπεδο controller ή filter έχει νόημα όταν απαιτείται γνώση του συγκεκριμένου endpoint ή επιχειρησιακών κανόνων, όπως διαφορετικά όρια ανά use case ή domain-specific validation. Ωστόσο, σε αυτή την περίπτωση το request έχει ήδη διανύσει σημαντικό μέρος του pipeline, γεγονός που καθιστά την απόρριψη λιγότερο αποδοτική από πλευράς πόρων.
Συνεπώς, η βέλτιστη προσέγγιση είναι ο διαχωρισμός ευθυνών: το middleware αναλαμβάνει τους τεχνικούς και οριζόντιους ελέγχους (logging, βασικά limits, error handling), ενώ το application layer επικεντρώνεται στους επιχειρησιακούς κανόνες. Σε περιβάλλοντα με αυξημένες απαιτήσεις (π.χ. cloud deployments με πολλαπλά ingress layers), αυτός ο διαχωρισμός συμβάλλει σε καλύτερη απόδοση, καθαρότερη αρχιτεκτονική και ευκολότερη συντήρηση.
Ένα σωστό παράδειγμα
Reverse proxy / Azure: 100 MB
Kestrel: 100 MB
Endpoints:
avatar: 3 MB
document: 25 MB
import: 50 MB
JSON: 512 KB
Σε αυτή τη διάταξη:
- το σύστημα προστατεύεται συνολικά
- κάθε endpoint έχει σαφή όρια
- τα layers συνεργάζονται σωστά
Τι επιστρέφει το API όταν απορρίπτει ένα request
Στις περισσότερες περιπτώσεις, όταν ένα αίτημα υπερβαίνει το επιτρεπτό μέγεθος, το API ή το reverse proxy επιστρέφει:
- HTTP 413 Payload Too Large
Σε application-level validations μπορεί να χρησιμοποιηθούν και άλλα status codes, όπως:
- 400 Bad Request
- 422 Unprocessable Entity
ανάλογα με το είδος του περιορισμού.
Να θυμάσαι..
Το request size δεν ελέγχεται από ένα σημείο, αλλά από μια αλυσίδα επιπέδων όπου κάθε layer μπορεί να επιβάλει τα δικά του όρια.
Δεν έχει σημασία μόνο το τι έχεις ορίσει στον κώδικά σου, αλλά και το πού εκτελείται η εφαρμογή και ποια infrastructure layers προηγούνται.
Στην πράξη, ο πραγματικός έλεγχος του request size είναι πάντα συνδυασμός:
- infrastructure constraints
- runtime behavior
- application-level business rules
Ο σωστός σχεδιασμός δεν είναι να επιλέξεις ένα επίπεδο, αλλά να τα ευθυγραμμίσεις ώστε να συνεργάζονται χωρίς αντιφάσεις.
Δεν αρκεί να υπάρχει limit.
Σημασία έχει σε ποιο layer εφαρμόζεται.
Πηγές
Microsoft – Kestrel limits (core reference)
Microsoft – Default limits & layering
Microsoft – RequestSizeLimitAttribute (API layer)
IIS / Hosting layer (proxy level)
Σημαντικό τεχνικό insight (override behavior)


Top comments (0)