Skip to content

Commit ce89ff6

Browse files
authored
Merge pull request #668 from alanmcgovern/add-validation-http-requests
Add validation http requests
2 parents 7bf8776 + 0abb8c0 commit ce89ff6

File tree

1 file changed

+35
-12
lines changed

1 file changed

+35
-12
lines changed

src/MonoTorrent.Client/MonoTorrent.Connections/HttpPeerConnection.cs

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
using System.Threading;
3636
using System.Threading.Tasks;
3737

38+
using MonoTorrent.Logging;
3839
using MonoTorrent.Messages;
3940
using MonoTorrent.Messages.Peer;
4041

@@ -44,6 +45,8 @@ namespace MonoTorrent.Connections.Peer
4445
{
4546
sealed class HttpPeerConnection : IPeerConnection
4647
{
48+
static readonly Logger Log = Logger.Create (nameof (HttpPeerConnection));
49+
4750
static readonly Uri PaddingFileUri = new Uri ("http://__paddingfile__");
4851

4952
class HttpRequestData
@@ -305,17 +308,20 @@ public async ReusableTask<int> SendAsync (Memory<byte> socketBuffer)
305308
{
306309
SendResult = new TaskCompletionSource<object?> ();
307310

311+
var info = TorrentData.TorrentInfo;
308312
List<BlockInfo> bundle = DecodeMessages (socketBuffer.Span);
309-
if (bundle.Count > 0) {
310-
RequestMessages.AddRange (bundle);
311-
// The RequestMessages are always sequential
312-
BlockInfo start = RequestMessages[0];
313-
BlockInfo end = RequestMessages[RequestMessages.Count - 1];
314-
CreateWebRequests (start, end);
315-
} else {
313+
314+
// If the messages in the send buffer are anything *other* than piece request messages,
315+
// just pretend the bytes were sent and everything was fine.
316+
if (bundle.Count == 0 || info == null)
316317
return socketBuffer.Length;
317-
}
318318

319+
// Otherwise, if there were 1 or more piece request messages, convert these to HTTP requests.
320+
// and only mark the bytes as successfully sent after all webrequests have run to completion
321+
// and the data has been received.
322+
RequestMessages.AddRange (bundle);
323+
ValidateWebRequests (info, RequestMessages.ToArray ());
324+
CreateWebRequestsForSequentialRange (RequestMessages[0], RequestMessages[RequestMessages.Count - 1]);
319325
ReceiveWaiter.Set ();
320326
await SendResult.Task;
321327
return socketBuffer.Length;
@@ -334,8 +340,26 @@ static List<BlockInfo> DecodeMessages (ReadOnlySpan<byte> buffer)
334340
return messages;
335341
}
336342

343+
static void ValidateWebRequests (ITorrentInfo torrentInfo, BlockInfo[] blocks)
344+
{
345+
if (blocks.Length > 0) {
346+
BlockInfo startBlock = blocks[0];
347+
BlockInfo currentBlock = startBlock;
348+
for (int i = 1; i < blocks.Length; i++) {
349+
BlockInfo previousBlock = blocks[i - 1];
350+
currentBlock = blocks[i];
351+
long endOffsetOfPreviousEndBlock = torrentInfo.PieceIndexToByteOffset (previousBlock.PieceIndex) + previousBlock.StartOffset + previousBlock.RequestLength;
352+
long startOffsetOfCurrentBlock = torrentInfo.PieceIndexToByteOffset (currentBlock.PieceIndex) + currentBlock.StartOffset;
353+
if (endOffsetOfPreviousEndBlock != startOffsetOfCurrentBlock) {
354+
var msg = "Piece requests made from HTTP peers must be a strictly sequential range of blocks. The range must be 1 or more blocks long.";
355+
Log.Error (msg);
356+
throw new InvalidOperationException (msg);
357+
}
358+
}
359+
}
360+
}
337361

338-
void CreateWebRequests (BlockInfo start, BlockInfo end)
362+
void CreateWebRequestsForSequentialRange (BlockInfo start, BlockInfo end)
339363
{
340364
Uri uri = Uri;
341365

@@ -354,11 +378,10 @@ void CreateWebRequests (BlockInfo start, BlockInfo end)
354378
if (count == 0)
355379
break;
356380

357-
var lengthWithPadding = file.Length + file.Padding;
358381
// If the first byte of data is from the next file, move to the next file immediately
359382
// and adjust start offset to be relative to that file.
360-
if (startOffset >= lengthWithPadding) {
361-
startOffset -= lengthWithPadding;
383+
if (startOffset >= file.Length + file.Padding) {
384+
startOffset -= file.Length + file.Padding;
362385
continue;
363386
}
364387

0 commit comments

Comments
 (0)