Skip to content

Commit 75c953e

Browse files
Extends DevToolsPlugin with logging streamed responses. Closes #1298
1 parent aeaed2e commit 75c953e

File tree

2 files changed

+125
-22
lines changed

2 files changed

+125
-22
lines changed

DevProxy.Plugins/Inspection/CDPModel.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
namespace DevProxy.Plugins.Inspection.CDP;
1111
#pragma warning restore IDE0130
1212

13-
public abstract class Message
13+
public class Message
1414
{
1515
[JsonPropertyName("id")]
1616
public int? Id { get; set; }
@@ -296,4 +296,38 @@ public class GetResponseBodyResultParams
296296
public string? Body { get; set; }
297297
[JsonPropertyName("base64Encoded")]
298298
public bool? Base64Encoded { get; set; }
299+
}
300+
301+
public class StreamResourceContentResult : MessageResult<StreamResourceContentResultParams>
302+
{
303+
}
304+
305+
public class StreamResourceContentResultParams
306+
{
307+
[JsonPropertyName("bufferedData")]
308+
public string? BufferedData { get; set; }
309+
}
310+
311+
public class DataReceivedMessage : Message<DataReceivedParams>
312+
{
313+
public DataReceivedMessage()
314+
{
315+
Method = "Network.dataReceived";
316+
}
317+
}
318+
319+
public class DataReceivedParams
320+
{
321+
[JsonPropertyName("data")]
322+
public string? Data { get; set; }
323+
[JsonPropertyName("dataLength")]
324+
public long? DataLength { get; set; }
325+
[JsonPropertyName("encodedDataLength")]
326+
public long? EncodedDataLength { get; set; }
327+
[JsonPropertyName("requestId")]
328+
public string? RequestId { get; set; }
329+
330+
[JsonPropertyName("timestamp")]
331+
public double? Timestamp { get; set; }
332+
299333
}

DevProxy.Plugins/Inspection/DevToolsPlugin.cs

Lines changed: 90 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
using System.Runtime.InteropServices;
1515
using System.Text.Json;
1616
using System.Globalization;
17+
using System.Text;
1718

1819
namespace DevProxy.Plugins.Inspection;
1920

@@ -191,6 +192,11 @@ public override async Task AfterResponseAsync(ProxyResponseArgs e, CancellationT
191192

192193
await _webSocket.SendAsync(responseReceivedMessage, cancellationToken);
193194

195+
if (e.Session.HttpClient.Response.ContentType == "text/event-stream")
196+
{
197+
await SendBodyAsDataReceivedAsync(requestId, body.Body, cancellationToken);
198+
}
199+
194200
var loadingFinishedMessage = new LoadingFinishedMessage
195201
{
196202
Params = new()
@@ -339,35 +345,98 @@ private void SocketMessageReceived(string msg)
339345

340346
try
341347
{
342-
var message = JsonSerializer.Deserialize<GetResponseBodyMessage>(msg, ProxyUtils.JsonSerializerOptions);
343-
if (message?.Method == "Network.getResponseBody")
348+
var message = JsonSerializer.Deserialize<Message>(msg, ProxyUtils.JsonSerializerOptions);
349+
switch (message?.Method)
344350
{
345-
var requestId = message.Params?.RequestId;
346-
if (requestId is null ||
347-
!_responseBody.TryGetValue(requestId, out var value) ||
348-
// should never happen because the message is sent from devtools
349-
// and Id is required on all socket messages but theoretically
350-
// it is possible
351-
message.Id is null)
352-
{
353-
return;
354-
}
355-
356-
var result = new GetResponseBodyResult
357-
{
358-
Id = (int)message.Id,
359-
Result = new()
351+
case "Network.getResponseBody":
352+
var getResponseBodyMessage = JsonSerializer.Deserialize<GetResponseBodyMessage>(msg, ProxyUtils.JsonSerializerOptions);
353+
if (getResponseBodyMessage is null)
360354
{
361-
Body = value.Body,
362-
Base64Encoded = value.Base64Encoded
355+
return;
363356
}
364-
};
365-
_ = _webSocket.SendAsync(result, _cancellationToken ?? CancellationToken.None);
357+
_ = HandleNetworkGetResponseBodyAsync(getResponseBodyMessage, _cancellationToken ?? CancellationToken.None);
358+
break;
359+
case "Network.streamResourceContent":
360+
_ = HandleNetworkStreamResourceContentAsync(message, _cancellationToken ?? CancellationToken.None);
361+
break;
362+
default:
363+
break;
366364
}
367365
}
368366
catch { }
369367
}
370368

369+
private async Task HandleNetworkStreamResourceContentAsync(Message message, CancellationToken cancellationToken)
370+
{
371+
if (_webSocket is null || message.Id is null)
372+
{
373+
return;
374+
}
375+
376+
var result = new StreamResourceContentResult
377+
{
378+
Id = (int)message.Id,
379+
Result = new()
380+
{
381+
BufferedData = string.Empty
382+
}
383+
};
384+
385+
await _webSocket.SendAsync(result, cancellationToken);
386+
}
387+
388+
private async Task HandleNetworkGetResponseBodyAsync(GetResponseBodyMessage message, CancellationToken cancellationToken)
389+
{
390+
if (_webSocket is null || message.Params?.RequestId is null)
391+
{
392+
return;
393+
}
394+
395+
if (!_responseBody.TryGetValue(message.Params.RequestId, out var value) ||
396+
// should never happen because the message is sent from devtools
397+
// and Id is required on all socket messages but theoretically
398+
// it is possible
399+
message.Id is null)
400+
{
401+
return;
402+
}
403+
404+
var result = new GetResponseBodyResult
405+
{
406+
Id = (int)message.Id,
407+
Result = new()
408+
{
409+
Body = value.Body,
410+
Base64Encoded = value.Base64Encoded
411+
}
412+
};
413+
414+
await _webSocket.SendAsync(result, cancellationToken);
415+
}
416+
417+
private async Task SendBodyAsDataReceivedAsync(string requestId, string? body, CancellationToken cancellationToken)
418+
{
419+
if (_webSocket is null || string.IsNullOrEmpty(body))
420+
{
421+
return;
422+
}
423+
424+
var base64Encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(body));
425+
var dataReceivedMessage = new DataReceivedMessage
426+
{
427+
Params = new()
428+
{
429+
RequestId = requestId,
430+
Timestamp = (double)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() / 1000,
431+
Data = base64Encoded,
432+
DataLength = body.Length,
433+
EncodedDataLength = base64Encoded.Length
434+
}
435+
};
436+
437+
await _webSocket.SendAsync(dataReceivedMessage, cancellationToken);
438+
}
439+
371440
private static int GetFreePort()
372441
{
373442
using var listener = new TcpListener(IPAddress.Loopback, 0);

0 commit comments

Comments
 (0)