Use a BufferedInputStream for S3 uploads

Yes, significant chunks of large files may end up buffered into memory,
but doing this allows the AWS Java SDK's S3 client to take advantage of
its built in retry logic.

An alternative to this would be to use the S3 multipart upload
functionality.

This fixes errors where you receive the message:

ERROR: Failed to upload files
java.io.IOException: put Destination [bucketName=XXX, objectName=YYY/ZZZ.exe]: com.amazonaws.AmazonClientException: Encountered an exception and couldn't reset the stream to retry
        at hudson.plugins.s3.S3Profile.upload(S3Profile.java:140)
        at hudson.plugins.s3.S3BucketPublisher.perform(S3BucketPublisher.java:174)
        at hudson.tasks.BuildStepMonitor$2.perform(BuildStepMonitor.java:32)
        at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:804)
        at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:776)
        at hudson.model.Build$BuildExecution.post2(Build.java:183)
        at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:725)
        at hudson.model.Run.execute(Run.java:1701)
        at hudson.matrix.MatrixRun.run(MatrixRun.java:146)
        at hudson.model.ResourceController.execute(ResourceController.java:88)
        at hudson.model.Executor.run(Executor.java:231)