private void handlePostBlob(HttpServletRequest request,
            HttpServletResponse response, InputStream is, BlobStore blobStore,
            String containerName)
            throws IOException, S3Exception {
        String boundaryHeader = request.getHeader(HttpHeaders.CONTENT_TYPE);
        if (boundaryHeader == null ||
                !boundaryHeader.startsWith("multipart/form-data; boundary=")) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }
        String boundary =
                boundaryHeader.substring(boundaryHeader.indexOf('=') + 1);

        String blobName = null;
        String contentType = null;
        String identity = null;
        // TODO: handle policy
        byte[] policy = null;
        String signature = null;
        String algorithm = null;
        byte[] payload = null;
        var multipartStream = MultipartInput.builder()
                .setBoundary(boundary.getBytes(StandardCharsets.UTF_8))
                .setInputStream(is)
                .get();
        boolean nextPart = multipartStream.skipPreamble();
        while (nextPart) {
            String header = multipartStream.readHeaders();
            try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
                multipartStream.readBodyData(baos);
                if (isField(header, "acl")) {
                    // TODO: acl
                } else if (isField(header, "AWSAccessKeyId") ||
                        isField(header, "X-Amz-Credential")) {
                    identity = new String(baos.toByteArray());
                } else if (isField(header, "Content-Type")) {
                    contentType = new String(baos.toByteArray());
                } else if (isField(header, "file")) {
                    // TODO: buffers entire payload
                    payload = baos.toByteArray();
                } else if (isField(header, "key")) {
                    blobName = new String(baos.toByteArray());
                } else if (isField(header, "policy")) {
                    policy = baos.toByteArray();
                } else if (isField(header, "signature") ||
                        isField(header, "X-Amz-Signature")) {
                    signature = new String(baos.toByteArray());
                } else if (isField(header, "X-Amz-Algorithm")) {
                    algorithm = new String(baos.toByteArray());
                }
            }
            nextPart = multipartStream.readBoundary();
        }


        if (blobName == null || policy == null) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }

        String headerAuthorization = null;
        S3AuthorizationHeader authHeader = null;
        boolean signatureVersion4;
        if (algorithm == null) {
            if (identity == null || signature == null) {
                throw new S3Exception(S3ErrorCode.ACCESS_DENIED);
            }
            signatureVersion4 = false;
            headerAuthorization = "AWS " + identity + ":" + signature;
        } else if (algorithm.equals("AWS4-HMAC-SHA256")) {
            if (identity == null || signature == null) {
                throw new S3Exception(S3ErrorCode.ACCESS_DENIED);
            }
            signatureVersion4 = true;
            headerAuthorization = "AWS4-HMAC-SHA256" +
                    " Credential=" + identity +
                    ", Signature=" + signature;
        } else {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }

        try {
            authHeader = new S3AuthorizationHeader(headerAuthorization);
        } catch (IllegalArgumentException iae) {
            throw new S3Exception(S3ErrorCode.INVALID_ARGUMENT, iae);
        }

        switch (authHeader.getAuthenticationType()) {
        case AWS_V2:
            switch (authenticationType) {
            case AWS_V2:
            case AWS_V2_OR_V4:
            case NONE:
                break;
            default:
                throw new S3Exception(S3ErrorCode.ACCESS_DENIED);
            }
            break;
        case AWS_V4:
            switch (authenticationType) {
            case AWS_V4:
            case AWS_V2_OR_V4:
            case NONE:
                break;
            default:
                throw new S3Exception(S3ErrorCode.ACCESS_DENIED);
            }
            break;
        case NONE:
            break;
        default:
            throw new IllegalArgumentException("Unhandled type: " +
                    authHeader.getAuthenticationType());
        }

        Map.Entry<String, BlobStore> provider =
                blobStoreLocator.locateBlobStore(authHeader.getIdentity(), null,
                        null);
        if (provider == null) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            return;
        }
        String credential = provider.getKey();

        if (signatureVersion4) {
            byte[] kSecret = ("AWS4" + credential).getBytes(
                    StandardCharsets.UTF_8);
            byte[] kDate = hmac("HmacSHA256",
                    authHeader.getDate().getBytes(StandardCharsets.UTF_8),
                    kSecret);
            byte[] kRegion = hmac("HmacSHA256",
                    authHeader.getRegion().getBytes(StandardCharsets.UTF_8),
                    kDate);
            byte[] kService = hmac("HmacSHA256",
                    authHeader.getService().getBytes(StandardCharsets.UTF_8),
                    kRegion);
            byte[] kSigning = hmac("HmacSHA256",
                    "aws4_request".getBytes(StandardCharsets.UTF_8), kService);
            String expectedSignature = BaseEncoding.base16().lowerCase().encode(
                    hmac("HmacSHA256", policy, kSigning));
            if (!constantTimeEquals(signature, expectedSignature)) {
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                return;
            }
        } else {
            String expectedSignature = Base64.getEncoder().encodeToString(
                    hmac("HmacSHA1", policy,
                            credential.getBytes(StandardCharsets.UTF_8)));
            if (!constantTimeEquals(signature, expectedSignature)) {
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                return;
            }
        }

        BlobBuilder.PayloadBlobBuilder builder = blobStore
                .blobBuilder(blobName)
                .payload(payload);
        if (contentType != null) {
            builder.contentType(contentType);
        }
        Blob blob = builder.build();
        blobStore.putBlob(containerName, blob);

        response.setStatus(HttpServletResponse.SC_NO_CONTENT);

        addCorsResponseHeader(request, response);
    }
Map XML ACLs to a canned policy if an exact tranformation exists.
src/main/java/org/gaul/s3proxy/S3ProxyHandler.java