@@ -368,7 +368,7 @@ impl<A: Access> LayeredAccess for CompleteAccessor<A> {
368
368
369
369
async fn write ( & self , path : & str , args : OpWrite ) -> Result < ( RpWrite , Self :: Writer ) > {
370
370
let ( rp, w) = self . inner . write ( path, args. clone ( ) ) . await ?;
371
- let w = CompleteWriter :: new ( w) ;
371
+ let w = CompleteWriter :: new ( w, args . append ( ) ) ;
372
372
Ok ( ( rp, w) )
373
373
}
374
374
@@ -400,9 +400,10 @@ impl<A: Access> LayeredAccess for CompleteAccessor<A> {
400
400
}
401
401
402
402
fn blocking_write ( & self , path : & str , args : OpWrite ) -> Result < ( RpWrite , Self :: BlockingWriter ) > {
403
+ let append = args. append ( ) ;
403
404
self . inner
404
405
. blocking_write ( path, args)
405
- . map ( |( rp, w) | ( rp, CompleteWriter :: new ( w) ) )
406
+ . map ( |( rp, w) | ( rp, CompleteWriter :: new ( w, append ) ) )
406
407
}
407
408
408
409
fn blocking_stat ( & self , path : & str , args : OpStat ) -> Result < RpStat > {
@@ -487,16 +488,38 @@ impl<R: oio::BlockingRead> oio::BlockingRead for CompleteReader<R> {
487
488
488
489
pub struct CompleteWriter < W > {
489
490
inner : Option < W > ,
491
+ append : bool ,
490
492
size : u64 ,
491
493
}
492
494
493
495
impl < W > CompleteWriter < W > {
494
- pub fn new ( inner : W ) -> CompleteWriter < W > {
496
+ pub fn new ( inner : W , append : bool ) -> CompleteWriter < W > {
495
497
CompleteWriter {
496
498
inner : Some ( inner) ,
499
+ append,
497
500
size : 0 ,
498
501
}
499
502
}
503
+
504
+ fn check ( & self , content_length : u64 ) -> Result < ( ) > {
505
+ if self . append || content_length == 0 {
506
+ return Ok ( ( ) ) ;
507
+ }
508
+
509
+ match self . size . cmp ( & content_length) {
510
+ Ordering :: Equal => Ok ( ( ) ) ,
511
+ Ordering :: Less => Err (
512
+ Error :: new ( ErrorKind :: Unexpected , "writer got too little data" )
513
+ . with_context ( "expect" , content_length)
514
+ . with_context ( "actual" , self . size ) ,
515
+ ) ,
516
+ Ordering :: Greater => Err (
517
+ Error :: new ( ErrorKind :: Unexpected , "writer got too much data" )
518
+ . with_context ( "expect" , content_length)
519
+ . with_context ( "actual" , self . size ) ,
520
+ ) ,
521
+ }
522
+ }
500
523
}
501
524
502
525
/// Check if the writer has been closed or aborted while debug_assertions
@@ -534,6 +557,7 @@ where
534
557
// we must return `Err` before setting inner to None; otherwise,
535
558
// we won't be able to retry `close` in `RetryLayer`.
536
559
let mut ret = w. close ( ) . await ?;
560
+ self . check ( ret. content_length ( ) ) ?;
537
561
if ret. content_length ( ) == 0 {
538
562
ret = ret. with_content_length ( self . size ) ;
539
563
}
@@ -576,6 +600,7 @@ where
576
600
} ) ?;
577
601
578
602
let mut ret = w. close ( ) ?;
603
+ self . check ( ret. content_length ( ) ) ?;
579
604
if ret. content_length ( ) == 0 {
580
605
ret = ret. with_content_length ( self . size ) ;
581
606
}
0 commit comments