resp
}
- MC::UploadBundle { game, hash, kind } => {
+ MC::UploadBundle { game, size, hash, kind } => {
let (upload, auth) = {
let ag = AccountsGuard::lock();
let gref = Instance::lookup_by_name_unauth(&game)?;
let upload = bundles.start_upload(ig, kind)?;
(upload, auth)
};
- let uploaded = upload.bulk(&mut bulk_upload, &hash, &mut for_response)?;
+ let uploaded = upload.bulk(&mut bulk_upload, size,
+ &hash, &mut for_response)?;
{
let gref = Instance::lookup_by_name(&game, auth)?;
let mut bundles = gref.lock_bundles();
let f = File::open(&args.bundle_file)
.with_context(|| args.bundle_file.clone())
.context("open bundle file")?;
+ let size = f
+ .metadata().context("fstat bundle file")?
+ .len()
+ .try_into().map_err(|_| anyhow!("bundle file far too large"))?;
let mut f = BufReader::new(f);
let hash = bundles::DigestWrite::of(&mut f)
.context("read bundle file (for hash)")?;
let kind = bundles::Kind::only();
f.rewind().context("rewind bundle file")?;
let cmd = MC::UploadBundle {
+ size,
game: instance_name.clone(),
hash: bundles::Hash(hash.into()), kind,
};
impl Uploading {
#[throws(MgmtError)]
- pub fn bulk<R,PW>(self, data: &mut R, expected: &Hash,
+ pub fn bulk<R,PW>(self, data: &mut R, size: usize, expected: &Hash,
for_progress: &mut ResponseWriter<PW>) -> Uploaded
where R: Read, PW: Write
{
let Uploading { id, mut file, instance } = self;
let tmp = id.path_tmp(&instance);
- io::copy(data, &mut file)
+ let copied_size = io::copy(data, &mut file)
.with_context(|| tmp.clone())
.context("copy").map_err(IE::from)?;
let (hash, file) = file.finish();
+ if copied_size != size as u64 { throw!(ME::UploadTruncated) }
+
let mut file = file.into_inner().map_err(|e| e.into_error())
.with_context(|| tmp.clone()).context("flush").map_err(IE::from)?;
if hash.as_slice() != &expected.0[..] { throw!(ME::UploadCorrupted) }
},*/
UploadBundle {
game: InstanceName,
+ size: usize,
hash: bundles::Hash,
kind: bundles::Kind,
},
TomlSyntaxError(String),
TomlStructureError(String),
RngIsReal,
+ UploadTruncated,
UploadCorrupted,
TooManyBundles,
BadBundle(String),