Zero Bytes Accepted

An upload endpoint validates through a chain.

class Handler:
    def __init__(self, nxt=None): self.nxt = nxt
    def handle(self, req):
        rejection = self.check(req)             # a Response, or None
        if rejection is not None:
            return rejection
        return self.nxt.handle(req) if self.nxt else None

chain = SizeCheck(TypeCheck(VirusScan()))

def upload(req):
    rejection = chain.handle(req)
    return rejection if rejection else accept(req)

Four requests, and the response each one actually gets:

# size extension virus signature response
1 12 MB .png none 413
2 2 MB .gif none 415
3 2 MB .png matched 422
4 0 bytes .png none 202

Three of those rows are a handler doing its job. Which row exposes a flaw in the chain itself, and what is the flaw?

A

Row 2. A rejected file extension is a malformed request, so row 2 should be a 400 and returning 415 is the defect.

B

Row 4. Every handler in this chain can only produce a rejection, so None at the end means two different things: everything approved, and nobody looked. Nothing in the design asserts a positive outcome, so a 0-byte file is stored as a valid PNG.

C

Row 1. SizeCheck cannot know the size until the body has been buffered, so the 413 is returned only after 12 MB has already been read into memory.

D

Row 3. VirusScan is last in the chain, so by the time the signature matches, the file has already been written by the earlier handlers.