• Sean McGivern's avatar
    Immediately unlink Puma temporary files · 704d44d5
    Sean McGivern authored
    Puma has a limit (`Puma::Const::MAX_BODY` - around 110 KiB) over which
    it will write request bodies to disk for handing off to the
    application. When it does this, the request body can be left on disk
    if the Puma process receives SIGKILL. Consider an extremely minimal
    `config.ru`:
    
        run(proc { [204, {}, []] })
    
    If we then:
    
    1. Start `puma`, noting the process ID.
    2. Start a slow file transfer, using `curl --limit-rate 100k` (for
       example) and `-T $PATH_TO_LARGE_FILE`.
    3. Watch `$TMPDIR/puma*`.
    
    We will see Puma start to write this temporary file. If we then send
    SIGKILL to Puma, the file won't be cleaned up. With this patch, it
    will.
    
    The patch itself is pretty unpleasant: as Puma has two quite long
    methods that set up the temporary files (`Puma::Client#setup_body` and
    `Puma::Client#setup_chunked_body`), we have to copy those methods and
    call `#unlink` in the correct spots in both. Also, as these are private
    methods, it's hard to write a test for them. We can test manually.
    Running `fswatch -t -x $TMPDIR | grep puma` while posting a large file
    shows this with this patch:
    
        Fri Mar 26 20:34:10 2021 ... Created Removed IsFile
        Fri Mar 26 20:34:21 2021 ... Updated IsFile
    
    Whereas without this patch we get:
    
        Fri Mar 26 20:32:57 2021 ... Created IsFile
        Fri Mar 26 20:33:05 2021 ... Created Removed Updated IsFile
    704d44d5
puma_client_tempfile_patch.rb 3.03 KB