@@ -65,6 +65,8 @@ impl<'a> GetBlobBuilder<'a> {
6565 None ,
6666 ) ?;
6767
68+ debug ! ( "request == {:#?}" , request) ;
69+
6870 let expected_status_code = if self . range . is_some ( ) {
6971 http:: StatusCode :: PARTIAL_CONTENT
7072 } else {
@@ -91,15 +93,21 @@ impl<'a> GetBlobBuilder<'a> {
9193 End ,
9294 }
9395
94- let complete_range = Range :: new ( 0 , u64:: MAX ) ;
96+ // this can either be the range requested by the caller or the complete file.
97+ let requested_range = self . range . unwrap_or ( Range :: new ( 0 , u64:: MAX ) ) ;
9598
9699 futures:: stream:: unfold ( States :: Init , move |state| async move {
97- let remaining = match state {
98- States :: Init => self . range . unwrap_or ( complete_range ) ,
100+ let mut remaining = match state {
101+ States :: Init => requested_range ,
99102 States :: Progress ( range) => range,
100103 States :: End => return None ,
101104 } ;
102105
106+ debug ! (
107+ "remaining.start == {}, chunk_size == {}, remaining.end == {}" ,
108+ remaining. start, chunk_size, remaining. end
109+ ) ;
110+
103111 let range = if remaining. start + chunk_size > remaining. end {
104112 Range :: new ( remaining. start , remaining. end )
105113 } else {
@@ -113,41 +121,16 @@ impl<'a> GetBlobBuilder<'a> {
113121 Err ( err) => return Some ( ( Err ( err) , States :: End ) ) ,
114122 } ;
115123
124+ debug ! ( "response.content_range == {:?}" , response. content_range) ;
125+
126+ // now that we know what the remote blob size is, let's update the
127+ // boundary. We do this only if it's smaller than the requested size because the could
128+ // have specified a smaller range.
129+ remaining. end =
130+ std:: cmp:: min ( requested_range. end , response. content_range . total_length ( ) ) ;
131+
116132 let next_state = if remaining. end > range. end {
117- if self . range . is_some ( ) {
118- States :: Progress ( Range :: new ( range. end , remaining. end ) )
119- } else {
120- // if we are here it means the user have not specified a
121- // range and we didn't get the whole blob in one passing.
122- // We specified u64::MAX as the first range but now
123- // we need to find the correct size to avoid requesting data
124- // outside the valid range.
125- debug ! ( "content-range == {:?}" , response. content_range) ;
126- // this unwrap should always be safe since we did not
127- // get the whole blob in the previous call.
128- let content_range = response. content_range . clone ( ) . unwrap ( ) ;
129- let ridx = match content_range. find ( '/' ) {
130- Some ( ridx) => ridx,
131- None => {
132- return Some ( (
133- Err ( "The returned content-range is invalid: / is not present"
134- . into ( ) ) ,
135- States :: End ,
136- ) )
137- }
138- } ;
139- let total =
140- match str:: parse ( & content_range[ ridx + 1 ..] ) {
141- Ok ( total) => total,
142- Err ( _err) => return Some ( (
143- Err ( "The returned content-range is invalid: after / there is a non valid number"
144- . into ( ) ) ,
145- States :: End ,
146- ) ) ,
147- } ;
148-
149- States :: Progress ( Range :: new ( range. end , total) )
150- }
133+ States :: Progress ( Range :: new ( range. end , remaining. end ) )
151134 } else {
152135 States :: End
153136 } ;
0 commit comments