Subir a s3 con curl usando URL pre-firmada (obteniendo 403)

Estoy usando curl para llamar a una API Java ReST para recuperar una URL. Luego, Java genera una URL previamente firmada para la carga de S3 usando mis credenciales de S3, y la devuelve en la respuesta ReST. Curl toma la URL y la usa para cargar a S3, pero S3 devuelve 403 "La firma de solicitud que calculamos no coincide con la firma que proporcionó. Verifique su clave y método de firma".

Aquí está el código que estoy usando para generar la URL previamente firmada:

public class S3Util {
    static final AmazonS3 s3 = new AmazonS3Client( new AWSCredentials() {
        @Override
        public String getAWSAccessKeyId() {
            return "XXXXXXX";
        }
        @Override
        public String getAWSSecretKey() {
            return "XXXXXXXXXXXXXX";
        }
    });
    static final String BUCKET = "XXXXXXXXXXXXXXXXXXXXXXXXXXX";

    static public URL getMediaChunkURL( MediaChunk mc, HttpMethod method ) {
        String key = ...
        //way in the future (for testing)...
        Date expiration = new Date( System.currentTimeMillis() + CalendarUtil.ONE_MINUTE_IN_MILLISECONDS*60*1000 );

        GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(BUCKET, key, method);
        req.setExpiration(expiration);
        req.addRequestParameter("Content-Type", "application/octet-stream");

        //this gets passed to the end user:
        return s3.generatePresignedUrl(req);
    }
}

y en curl, corro desde bash, ejecuto esto:

echo Will try to upload chunk to ${location}
curl -i -X POST \
        -F 'Content-Type=application/octet-stream' \
        -F "file=@${fileName}" \
        ${location} || (echo upload chunk failed. ; exit 1 )

Entre otras cosas, probé PUT y probé "Content-type" (T minúscula). Me doy cuenta de que me falta algo (o algo) obvio, pero después de leer los documentos apropiados, buscar en Google y mirar muchas preguntas similares, no estoy seguro de qué es eso. Veo muchas sugerencias sobre los encabezados requeridos, pero pensé que se suponía que la URL renunciada eliminaría esas necesidades. ¿Tal vez no

TIA!

Actualizar

Solo para que quede claro, he probado descargas, y eso funciona bien.

Java se parece a:

GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(BUCKET, key, HttpMethod.GET);
req.setExpiration(expiration);

y curl es simplemente:

curl -i ${location}

Respuestas a la pregunta(8)

Su respuesta a la pregunta