@@ -9,6 +9,7 @@ internal sealed class HttpSegmentedStream : Stream
9
9
private readonly HttpClient _httpClient ;
10
10
private Stream ? _httpStream ;
11
11
private bool _positionChanged ;
12
+ private long _chunkPosition ;
12
13
13
14
private HttpSegmentedStream (
14
15
IDownloadUrlHandler downloadUrlHandler ,
@@ -67,11 +68,21 @@ public override async ValueTask<int> ReadAsync(
67
68
CancellationToken cancellationToken = default
68
69
)
69
70
{
70
- if ( _httpStream is null || _positionChanged )
71
+ if (
72
+ _httpStream is null
73
+ || _positionChanged
74
+ && Position < _chunkPosition
75
+ && Position > ( _chunkPosition + _httpStream ? . Length )
76
+ )
71
77
{
72
78
await ReadNextChunk ( cancellationToken ) ;
73
79
_positionChanged = false ;
74
80
}
81
+ else if ( _positionChanged )
82
+ {
83
+ _httpStream ? . Seek ( Math . Abs ( Position - _chunkPosition ) , SeekOrigin . Begin ) ;
84
+ _positionChanged = false ;
85
+ }
75
86
76
87
int bytesLeftToRead ;
77
88
var totalRead = 0 ;
@@ -153,13 +164,17 @@ private async Task ReadNextChunk(CancellationToken cancellationToken)
153
164
if ( _httpStream is not null )
154
165
await _httpStream . DisposeAsync ( ) ;
155
166
156
- _httpStream = await _httpClient . GetStreamAsync (
167
+ var response = await _httpClient . GetAsync (
157
168
AppendRangeToUrl (
158
169
await _downloadUrlHandler . GetUrl ( ) ,
159
170
Position ,
160
171
Position + BufferSize - 1
161
172
) ,
173
+ HttpCompletionOption . ResponseContentRead ,
162
174
cancellationToken
163
175
) ;
176
+
177
+ _httpStream = await response . Content . ReadAsStreamAsync ( cancellationToken ) ;
178
+ _chunkPosition = Position ;
164
179
}
165
180
}
0 commit comments