Support for uploading blobs with `Put` RPC call. This is the most complicated part of the service as it is stateful.
This is part 1 of 2
I implemented it slightly differently from the [C++ counterpart](https://github.com/CommE2E/comm/blob/master/services/blob/src/Reactors/server/PutReactor.h). I created a separate `PutHandler` struct to organize the code. A few notes on how it works:
- In each input stream message, client can send either `holder`, `blob hash` or `data chunk`.
- Put handler starts with a `PutAction::None` state and waits for both holder and hash to be provided (in any order, but each only once).
- When both of them exist, next state is determined:
- If `blob hash` already exists, the `AssignHolder` action is scheduled and the input stream is closed by the server.
- Otherwise, the `UploadNewBlob` action is initialized and handler is waiting for data chunks
> Here is where this diff ends, further actions are in the next diff
- //(next diff)// Messages containng data chunks can only be sent when handler is in the `UploadNewBlob` state. Chunks are uploaded to S3 if big enough. The Multipart upload session is initialized when first chunk is sent.
- //(next diff)// After input stream is closed, the `finish()` method is invoked, which consumes the handler and performs action depending on the enum value:
- If no action, just return
- For `AssignHolder` - just add a new row to the `reverse_index` table
- In case of `UploadNewBlob` - finishes the S3 upload and adds rows to both DB tables
Depends on D5702