Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,23 +91,53 @@ private void RequestLeftQueue(double timeOnQueueMilliseconds, byte versionMajor,
}

[Event(7, Level = EventLevel.Informational)]
public void ResponseHeadersBegin()
public void RequestHeadersStart()
{
WriteEvent(eventId: 7);
}

[Event(8, Level = EventLevel.Informational)]
public void ResponseContentStart()
public void RequestHeadersStop()
{
WriteEvent(eventId: 8);
}

[Event(9, Level = EventLevel.Informational)]
public void ResponseContentStop()
public void RequestContentStart()
{
WriteEvent(eventId: 9);
}

[Event(10, Level = EventLevel.Informational)]
public void RequestContentStop(long contentLength)
{
WriteEvent(eventId: 10, contentLength);
}

[Event(11, Level = EventLevel.Informational)]
public void ResponseHeadersStart()
{
WriteEvent(eventId: 11);
}

[Event(12, Level = EventLevel.Informational)]
public void ResponseHeadersStop()
{
WriteEvent(eventId: 12);
}

[Event(13, Level = EventLevel.Informational)]
public void ResponseContentStart()
{
WriteEvent(eventId: 13);
}

[Event(14, Level = EventLevel.Informational)]
public void ResponseContentStop()
{
WriteEvent(eventId: 14);
}

[NonEvent]
public void Http11ConnectionEstablished()
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,8 @@ public ChunkedEncodingWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand All@@ -39,6 +41,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,6 +17,8 @@ public ContentLengthWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand All@@ -27,6 +29,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored) // token ignored as it comes from SendAsync
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1354,6 +1354,8 @@ private async ValueTask<Http2Stream> SendHeadersAsync(HttpRequestMessage request
ArrayBuffer headerBuffer = default;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

// Serialize headers to a temporary buffer, and do as much work to prepare to send the headers as we can
// before taking the write lock.
headerBuffer = new ArrayBuffer(InitialConnectionBufferSize, usePool: true);
Expand DownExpand Up@@ -1434,6 +1436,9 @@ await PerformWriteAsync(totalSize, (thisRef: this, http2Stream, headerBytes, end

return s.mustFlush || s.endStream;
}, cancellationToken).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

return http2Stream;
}
catch
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -194,6 +194,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)
{
using var writeStream = new Http2WriteStream(this);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

ValueTask vt = _request.Content.InternalCopyToAsync(writeStream, context: null, _requestBodyCancellationSource.Token);
if (vt.IsCompleted)
{
Expand All@@ -208,6 +210,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)

await vt.ConfigureAwait(false);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(writeStream.BytesWritten);
}

if (NetEventSource.Log.IsEnabled()) Trace($"Finished sending request body.");
Expand DownExpand Up@@ -568,8 +572,6 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)

public void OnHeadersStart()
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();

Debug.Assert(!Monitor.IsEntered(SyncObject));
lock (SyncObject)
{
Expand DownExpand Up@@ -839,6 +841,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
bool emptyResponse;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Wait for response headers to be read.
bool wait;

Expand All@@ -851,6 +855,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
(wait, emptyResponse) = TryEnsureHeaders();
Debug.Assert(!wait);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();
}
catch
{
Expand DownExpand Up@@ -1344,6 +1350,8 @@ private sealed class Http2WriteStream : HttpBaseStream
{
private Http2Stream? _http2Stream;

public long BytesWritten { get; private set; }

public Http2WriteStream(Http2Stream http2Stream)
{
Debug.Assert(http2Stream != null);
Expand All@@ -1370,6 +1378,8 @@ protected override void Dispose(bool disposing)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{
BytesWritten += buffer.Length;

Http2Stream? http2Stream = _http2Stream;

if (http2Stream == null)
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -364,6 +364,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
CancellationTokenRegistration cancellationRegistration = RegisterCancellation(cancellationToken);
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

Debug.Assert(request.RequestUri != null);
// Write request line
await WriteStringAsync(normalizedMethod.Method, async).ConfigureAwait(false);
Expand DownExpand Up@@ -457,6 +459,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
// CRLF for end of headers.
await WriteTwoBytesAsync((byte)'\r', (byte)'\n', async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

if (request.Content == null)
{
// We have nothing more to send, so flush out any headers we haven't yet sent.
Expand DownExpand Up@@ -535,7 +539,7 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
var response = new HttpResponseMessage() { RequestMessage = request, Content = new HttpConnectionResponseContent() };
ParseStatusLine(await ReadNextResponseHeaderLineAsync(async).ConfigureAwait(false), response);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Multiple 1xx responses handling.
// RFC 7231: A client MUST be able to parse one or more 1xx responses received prior to a final response,
Expand DownExpand Up@@ -584,6 +588,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
ParseHeaderNameValue(this, line, response);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();

if (allowExpect100ToContinue != null)
{
// If we sent an Expect: 100-continue header, and didn't receive a 100-continue. Handle the final response accordingly.
Expand DownExpand Up@@ -817,6 +823,9 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Now that we're sending content, prohibit retries on this connection.
_canRetry = false;

Debug.Assert(stream.BytesWritten == 0);
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

// Copy all of the data to the server.
if (async)
{
Expand All@@ -833,6 +842,8 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Flush any content that might still be buffered.
await FlushAsync(async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(stream.BytesWritten);

if (NetEventSource.Log.IsEnabled()) Trace("Finished sending request content.");
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,6 +12,8 @@ internal partial class HttpConnection : IDisposable
{
private abstract class HttpContentWriteStream : HttpContentStream
{
public long BytesWritten { get; protected set; }

public HttpContentWriteStream(HttpConnection connection) : base(connection) =>
Debug.Assert(connection != null);

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,23 +91,53 @@ private void RequestLeftQueue(double timeOnQueueMilliseconds, byte versionMajor,
}

[Event(7, Level = EventLevel.Informational)]
public void ResponseHeadersBegin()
public void RequestHeadersStart()
{
WriteEvent(eventId: 7);
}

[Event(8, Level = EventLevel.Informational)]
public void ResponseContentStart()
public void RequestHeadersStop()
{
WriteEvent(eventId: 8);
}

[Event(9, Level = EventLevel.Informational)]
public void ResponseContentStop()
public void RequestContentStart()
{
WriteEvent(eventId: 9);
}

[Event(10, Level = EventLevel.Informational)]
public void RequestContentStop(long contentLength)
{
WriteEvent(eventId: 10, contentLength);
}

[Event(11, Level = EventLevel.Informational)]
public void ResponseHeadersStart()
{
WriteEvent(eventId: 11);
}

[Event(12, Level = EventLevel.Informational)]
public void ResponseHeadersStop()
{
WriteEvent(eventId: 12);
}

[Event(13, Level = EventLevel.Informational)]
public void ResponseContentStart()
{
WriteEvent(eventId: 13);
}

[Event(14, Level = EventLevel.Informational)]
public void ResponseContentStop()
{
WriteEvent(eventId: 14);
}

[NonEvent]
public void Http11ConnectionEstablished()
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,8 @@ public ChunkedEncodingWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand All@@ -39,6 +41,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,6 +17,8 @@ public ContentLengthWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand All@@ -27,6 +29,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored) // token ignored as it comes from SendAsync
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1354,6 +1354,8 @@ private async ValueTask<Http2Stream> SendHeadersAsync(HttpRequestMessage request
ArrayBuffer headerBuffer = default;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

// Serialize headers to a temporary buffer, and do as much work to prepare to send the headers as we can
// before taking the write lock.
headerBuffer = new ArrayBuffer(InitialConnectionBufferSize, usePool: true);
Expand DownExpand Up@@ -1434,6 +1436,9 @@ await PerformWriteAsync(totalSize, (thisRef: this, http2Stream, headerBytes, end

return s.mustFlush || s.endStream;
}, cancellationToken).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

return http2Stream;
}
catch
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -194,6 +194,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)
{
using var writeStream = new Http2WriteStream(this);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

ValueTask vt = _request.Content.InternalCopyToAsync(writeStream, context: null, _requestBodyCancellationSource.Token);
if (vt.IsCompleted)
{
Expand All@@ -208,6 +210,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)

await vt.ConfigureAwait(false);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(writeStream.BytesWritten);
}

if (NetEventSource.Log.IsEnabled()) Trace($"Finished sending request body.");
Expand DownExpand Up@@ -568,8 +572,6 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)

public void OnHeadersStart()
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();

Debug.Assert(!Monitor.IsEntered(SyncObject));
lock (SyncObject)
{
Expand DownExpand Up@@ -839,6 +841,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
bool emptyResponse;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Wait for response headers to be read.
bool wait;

Expand All@@ -851,6 +855,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
(wait, emptyResponse) = TryEnsureHeaders();
Debug.Assert(!wait);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();
}
catch
{
Expand DownExpand Up@@ -1344,6 +1350,8 @@ private sealed class Http2WriteStream : HttpBaseStream
{
private Http2Stream? _http2Stream;

public long BytesWritten { get; private set; }

public Http2WriteStream(Http2Stream http2Stream)
{
Debug.Assert(http2Stream != null);
Expand All@@ -1370,6 +1378,8 @@ protected override void Dispose(bool disposing)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{
BytesWritten += buffer.Length;

Http2Stream? http2Stream = _http2Stream;

if (http2Stream == null)
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -364,6 +364,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
CancellationTokenRegistration cancellationRegistration = RegisterCancellation(cancellationToken);
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

Debug.Assert(request.RequestUri != null);
// Write request line
await WriteStringAsync(normalizedMethod.Method, async).ConfigureAwait(false);
Expand DownExpand Up@@ -457,6 +459,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
// CRLF for end of headers.
await WriteTwoBytesAsync((byte)'\r', (byte)'\n', async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

if (request.Content == null)
{
// We have nothing more to send, so flush out any headers we haven't yet sent.
Expand DownExpand Up@@ -535,7 +539,7 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
var response = new HttpResponseMessage() { RequestMessage = request, Content = new HttpConnectionResponseContent() };
ParseStatusLine(await ReadNextResponseHeaderLineAsync(async).ConfigureAwait(false), response);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Multiple 1xx responses handling.
// RFC 7231: A client MUST be able to parse one or more 1xx responses received prior to a final response,
Expand DownExpand Up@@ -584,6 +588,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
ParseHeaderNameValue(this, line, response);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();

if (allowExpect100ToContinue != null)
{
// If we sent an Expect: 100-continue header, and didn't receive a 100-continue. Handle the final response accordingly.
Expand DownExpand Up@@ -817,6 +823,9 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Now that we're sending content, prohibit retries on this connection.
_canRetry = false;

Debug.Assert(stream.BytesWritten == 0);
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

// Copy all of the data to the server.
if (async)
{
Expand All@@ -833,6 +842,8 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Flush any content that might still be buffered.
await FlushAsync(async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(stream.BytesWritten);

if (NetEventSource.Log.IsEnabled()) Trace("Finished sending request content.");
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,6 +12,8 @@ internal partial class HttpConnection : IDisposable
{
private abstract class HttpContentWriteStream : HttpContentStream
{
public long BytesWritten { get; protected set; }

public HttpContentWriteStream(HttpConnection connection) : base(connection) =>
Debug.Assert(connection != null);

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,23 +91,53 @@ private void RequestLeftQueue(double timeOnQueueMilliseconds, byte versionMajor,
}

[Event(7, Level = EventLevel.Informational)]
public void ResponseHeadersBegin()
public void RequestHeadersStart()
{
WriteEvent(eventId: 7);
}

[Event(8, Level = EventLevel.Informational)]
public void ResponseContentStart()
public void RequestHeadersStop()
{
WriteEvent(eventId: 8);
}

[Event(9, Level = EventLevel.Informational)]
public void ResponseContentStop()
public void RequestContentStart()
{
WriteEvent(eventId: 9);
}

[Event(10, Level = EventLevel.Informational)]
public void RequestContentStop(long contentLength)
{
WriteEvent(eventId: 10, contentLength);
}

[Event(11, Level = EventLevel.Informational)]
public void ResponseHeadersStart()
{
WriteEvent(eventId: 11);
}

[Event(12, Level = EventLevel.Informational)]
public void ResponseHeadersStop()
{
WriteEvent(eventId: 12);
}

[Event(13, Level = EventLevel.Informational)]
public void ResponseContentStart()
{
WriteEvent(eventId: 13);
}

[Event(14, Level = EventLevel.Informational)]
public void ResponseContentStop()
{
WriteEvent(eventId: 14);
}

[NonEvent]
public void Http11ConnectionEstablished()
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,8 @@ public ChunkedEncodingWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand All@@ -39,6 +41,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,6 +17,8 @@ public ContentLengthWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand All@@ -27,6 +29,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored) // token ignored as it comes from SendAsync
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1354,6 +1354,8 @@ private async ValueTask<Http2Stream> SendHeadersAsync(HttpRequestMessage request
ArrayBuffer headerBuffer = default;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

// Serialize headers to a temporary buffer, and do as much work to prepare to send the headers as we can
// before taking the write lock.
headerBuffer = new ArrayBuffer(InitialConnectionBufferSize, usePool: true);
Expand DownExpand Up@@ -1434,6 +1436,9 @@ await PerformWriteAsync(totalSize, (thisRef: this, http2Stream, headerBytes, end

return s.mustFlush || s.endStream;
}, cancellationToken).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

return http2Stream;
}
catch
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -194,6 +194,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)
{
using var writeStream = new Http2WriteStream(this);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

ValueTask vt = _request.Content.InternalCopyToAsync(writeStream, context: null, _requestBodyCancellationSource.Token);
if (vt.IsCompleted)
{
Expand All@@ -208,6 +210,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)

await vt.ConfigureAwait(false);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(writeStream.BytesWritten);
}

if (NetEventSource.Log.IsEnabled()) Trace($"Finished sending request body.");
Expand DownExpand Up@@ -568,8 +572,6 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)

public void OnHeadersStart()
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();

Debug.Assert(!Monitor.IsEntered(SyncObject));
lock (SyncObject)
{
Expand DownExpand Up@@ -839,6 +841,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
bool emptyResponse;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Wait for response headers to be read.
bool wait;

Expand All@@ -851,6 +855,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
(wait, emptyResponse) = TryEnsureHeaders();
Debug.Assert(!wait);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();
}
catch
{
Expand DownExpand Up@@ -1344,6 +1350,8 @@ private sealed class Http2WriteStream : HttpBaseStream
{
private Http2Stream? _http2Stream;

public long BytesWritten { get; private set; }

public Http2WriteStream(Http2Stream http2Stream)
{
Debug.Assert(http2Stream != null);
Expand All@@ -1370,6 +1378,8 @@ protected override void Dispose(bool disposing)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{
BytesWritten += buffer.Length;

Http2Stream? http2Stream = _http2Stream;

if (http2Stream == null)
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -364,6 +364,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
CancellationTokenRegistration cancellationRegistration = RegisterCancellation(cancellationToken);
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

Debug.Assert(request.RequestUri != null);
// Write request line
await WriteStringAsync(normalizedMethod.Method, async).ConfigureAwait(false);
Expand DownExpand Up@@ -457,6 +459,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
// CRLF for end of headers.
await WriteTwoBytesAsync((byte)'\r', (byte)'\n', async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

if (request.Content == null)
{
// We have nothing more to send, so flush out any headers we haven't yet sent.
Expand DownExpand Up@@ -535,7 +539,7 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
var response = new HttpResponseMessage() { RequestMessage = request, Content = new HttpConnectionResponseContent() };
ParseStatusLine(await ReadNextResponseHeaderLineAsync(async).ConfigureAwait(false), response);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Multiple 1xx responses handling.
// RFC 7231: A client MUST be able to parse one or more 1xx responses received prior to a final response,
Expand DownExpand Up@@ -584,6 +588,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
ParseHeaderNameValue(this, line, response);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();

if (allowExpect100ToContinue != null)
{
// If we sent an Expect: 100-continue header, and didn't receive a 100-continue. Handle the final response accordingly.
Expand DownExpand Up@@ -817,6 +823,9 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Now that we're sending content, prohibit retries on this connection.
_canRetry = false;

Debug.Assert(stream.BytesWritten == 0);
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

// Copy all of the data to the server.
if (async)
{
Expand All@@ -833,6 +842,8 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Flush any content that might still be buffered.
await FlushAsync(async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(stream.BytesWritten);

if (NetEventSource.Log.IsEnabled()) Trace("Finished sending request content.");
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,6 +12,8 @@ internal partial class HttpConnection : IDisposable
{
private abstract class HttpContentWriteStream : HttpContentStream
{
public long BytesWritten { get; protected set; }

public HttpContentWriteStream(HttpConnection connection) : base(connection) =>
Debug.Assert(connection != null);

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,23 +91,53 @@ private void RequestLeftQueue(double timeOnQueueMilliseconds, byte versionMajor,
}

[Event(7, Level = EventLevel.Informational)]
public void ResponseHeadersBegin()
public void RequestHeadersStart()
{
WriteEvent(eventId: 7);
}

[Event(8, Level = EventLevel.Informational)]
public void ResponseContentStart()
public void RequestHeadersStop()
{
WriteEvent(eventId: 8);
}

[Event(9, Level = EventLevel.Informational)]
public void ResponseContentStop()
public void RequestContentStart()
{
WriteEvent(eventId: 9);
}

[Event(10, Level = EventLevel.Informational)]
public void RequestContentStop(long contentLength)
{
WriteEvent(eventId: 10, contentLength);
}

[Event(11, Level = EventLevel.Informational)]
public void ResponseHeadersStart()
{
WriteEvent(eventId: 11);
}

[Event(12, Level = EventLevel.Informational)]
public void ResponseHeadersStop()
{
WriteEvent(eventId: 12);
}

[Event(13, Level = EventLevel.Informational)]
public void ResponseContentStart()
{
WriteEvent(eventId: 13);
}

[Event(14, Level = EventLevel.Informational)]
public void ResponseContentStop()
{
WriteEvent(eventId: 14);
}

[NonEvent]
public void Http11ConnectionEstablished()
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,8 @@ public ChunkedEncodingWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand All@@ -39,6 +41,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,6 +17,8 @@ public ContentLengthWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand All@@ -27,6 +29,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored) // token ignored as it comes from SendAsync
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1354,6 +1354,8 @@ private async ValueTask<Http2Stream> SendHeadersAsync(HttpRequestMessage request
ArrayBuffer headerBuffer = default;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

// Serialize headers to a temporary buffer, and do as much work to prepare to send the headers as we can
// before taking the write lock.
headerBuffer = new ArrayBuffer(InitialConnectionBufferSize, usePool: true);
Expand DownExpand Up@@ -1434,6 +1436,9 @@ await PerformWriteAsync(totalSize, (thisRef: this, http2Stream, headerBytes, end

return s.mustFlush || s.endStream;
}, cancellationToken).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

return http2Stream;
}
catch
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -194,6 +194,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)
{
using var writeStream = new Http2WriteStream(this);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

ValueTask vt = _request.Content.InternalCopyToAsync(writeStream, context: null, _requestBodyCancellationSource.Token);
if (vt.IsCompleted)
{
Expand All@@ -208,6 +210,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)

await vt.ConfigureAwait(false);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(writeStream.BytesWritten);
}

if (NetEventSource.Log.IsEnabled()) Trace($"Finished sending request body.");
Expand DownExpand Up@@ -568,8 +572,6 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)

public void OnHeadersStart()
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();

Debug.Assert(!Monitor.IsEntered(SyncObject));
lock (SyncObject)
{
Expand DownExpand Up@@ -839,6 +841,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
bool emptyResponse;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Wait for response headers to be read.
bool wait;

Expand All@@ -851,6 +855,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
(wait, emptyResponse) = TryEnsureHeaders();
Debug.Assert(!wait);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();
}
catch
{
Expand DownExpand Up@@ -1344,6 +1350,8 @@ private sealed class Http2WriteStream : HttpBaseStream
{
private Http2Stream? _http2Stream;

public long BytesWritten { get; private set; }

public Http2WriteStream(Http2Stream http2Stream)
{
Debug.Assert(http2Stream != null);
Expand All@@ -1370,6 +1378,8 @@ protected override void Dispose(bool disposing)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{
BytesWritten += buffer.Length;

Http2Stream? http2Stream = _http2Stream;

if (http2Stream == null)
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -364,6 +364,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
CancellationTokenRegistration cancellationRegistration = RegisterCancellation(cancellationToken);
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

Debug.Assert(request.RequestUri != null);
// Write request line
await WriteStringAsync(normalizedMethod.Method, async).ConfigureAwait(false);
Expand DownExpand Up@@ -457,6 +459,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
// CRLF for end of headers.
await WriteTwoBytesAsync((byte)'\r', (byte)'\n', async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

if (request.Content == null)
{
// We have nothing more to send, so flush out any headers we haven't yet sent.
Expand DownExpand Up@@ -535,7 +539,7 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
var response = new HttpResponseMessage() { RequestMessage = request, Content = new HttpConnectionResponseContent() };
ParseStatusLine(await ReadNextResponseHeaderLineAsync(async).ConfigureAwait(false), response);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Multiple 1xx responses handling.
// RFC 7231: A client MUST be able to parse one or more 1xx responses received prior to a final response,
Expand DownExpand Up@@ -584,6 +588,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
ParseHeaderNameValue(this, line, response);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();

if (allowExpect100ToContinue != null)
{
// If we sent an Expect: 100-continue header, and didn't receive a 100-continue. Handle the final response accordingly.
Expand DownExpand Up@@ -817,6 +823,9 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Now that we're sending content, prohibit retries on this connection.
_canRetry = false;

Debug.Assert(stream.BytesWritten == 0);
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

// Copy all of the data to the server.
if (async)
{
Expand All@@ -833,6 +842,8 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Flush any content that might still be buffered.
await FlushAsync(async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(stream.BytesWritten);

if (NetEventSource.Log.IsEnabled()) Trace("Finished sending request content.");
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,6 +12,8 @@ internal partial class HttpConnection : IDisposable
{
private abstract class HttpContentWriteStream : HttpContentStream
{
public long BytesWritten { get; protected set; }

public HttpContentWriteStream(HttpConnection connection) : base(connection) =>
Debug.Assert(connection != null);

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,23 +91,53 @@ private void RequestLeftQueue(double timeOnQueueMilliseconds, byte versionMajor,
}

[Event(7, Level = EventLevel.Informational)]
public void ResponseHeadersBegin()
public void RequestHeadersStart()
{
WriteEvent(eventId: 7);
}

[Event(8, Level = EventLevel.Informational)]
public void ResponseContentStart()
public void RequestHeadersStop()
{
WriteEvent(eventId: 8);
}

[Event(9, Level = EventLevel.Informational)]
public void ResponseContentStop()
public void RequestContentStart()
{
WriteEvent(eventId: 9);
}

[Event(10, Level = EventLevel.Informational)]
public void RequestContentStop(long contentLength)
{
WriteEvent(eventId: 10, contentLength);
}

[Event(11, Level = EventLevel.Informational)]
public void ResponseHeadersStart()
{
WriteEvent(eventId: 11);
}

[Event(12, Level = EventLevel.Informational)]
public void ResponseHeadersStop()
{
WriteEvent(eventId: 12);
}

[Event(13, Level = EventLevel.Informational)]
public void ResponseContentStart()
{
WriteEvent(eventId: 13);
}

[Event(14, Level = EventLevel.Informational)]
public void ResponseContentStop()
{
WriteEvent(eventId: 14);
}

[NonEvent]
public void Http11ConnectionEstablished()
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,8 @@ public ChunkedEncodingWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand All@@ -39,6 +41,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,6 +17,8 @@ public ContentLengthWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand All@@ -27,6 +29,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored) // token ignored as it comes from SendAsync
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1354,6 +1354,8 @@ private async ValueTask<Http2Stream> SendHeadersAsync(HttpRequestMessage request
ArrayBuffer headerBuffer = default;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

// Serialize headers to a temporary buffer, and do as much work to prepare to send the headers as we can
// before taking the write lock.
headerBuffer = new ArrayBuffer(InitialConnectionBufferSize, usePool: true);
Expand DownExpand Up@@ -1434,6 +1436,9 @@ await PerformWriteAsync(totalSize, (thisRef: this, http2Stream, headerBytes, end

return s.mustFlush || s.endStream;
}, cancellationToken).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

return http2Stream;
}
catch
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -194,6 +194,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)
{
using var writeStream = new Http2WriteStream(this);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

ValueTask vt = _request.Content.InternalCopyToAsync(writeStream, context: null, _requestBodyCancellationSource.Token);
if (vt.IsCompleted)
{
Expand All@@ -208,6 +210,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)

await vt.ConfigureAwait(false);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(writeStream.BytesWritten);
}

if (NetEventSource.Log.IsEnabled()) Trace($"Finished sending request body.");
Expand DownExpand Up@@ -568,8 +572,6 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)

public void OnHeadersStart()
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();

Debug.Assert(!Monitor.IsEntered(SyncObject));
lock (SyncObject)
{
Expand DownExpand Up@@ -839,6 +841,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
bool emptyResponse;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Wait for response headers to be read.
bool wait;

Expand All@@ -851,6 +855,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
(wait, emptyResponse) = TryEnsureHeaders();
Debug.Assert(!wait);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();
}
catch
{
Expand DownExpand Up@@ -1344,6 +1350,8 @@ private sealed class Http2WriteStream : HttpBaseStream
{
private Http2Stream? _http2Stream;

public long BytesWritten { get; private set; }

public Http2WriteStream(Http2Stream http2Stream)
{
Debug.Assert(http2Stream != null);
Expand All@@ -1370,6 +1378,8 @@ protected override void Dispose(bool disposing)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{
BytesWritten += buffer.Length;

Http2Stream? http2Stream = _http2Stream;

if (http2Stream == null)
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -364,6 +364,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
CancellationTokenRegistration cancellationRegistration = RegisterCancellation(cancellationToken);
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

Debug.Assert(request.RequestUri != null);
// Write request line
await WriteStringAsync(normalizedMethod.Method, async).ConfigureAwait(false);
Expand DownExpand Up@@ -457,6 +459,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
// CRLF for end of headers.
await WriteTwoBytesAsync((byte)'\r', (byte)'\n', async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

if (request.Content == null)
{
// We have nothing more to send, so flush out any headers we haven't yet sent.
Expand DownExpand Up@@ -535,7 +539,7 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
var response = new HttpResponseMessage() { RequestMessage = request, Content = new HttpConnectionResponseContent() };
ParseStatusLine(await ReadNextResponseHeaderLineAsync(async).ConfigureAwait(false), response);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Multiple 1xx responses handling.
// RFC 7231: A client MUST be able to parse one or more 1xx responses received prior to a final response,
Expand DownExpand Up@@ -584,6 +588,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
ParseHeaderNameValue(this, line, response);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();

if (allowExpect100ToContinue != null)
{
// If we sent an Expect: 100-continue header, and didn't receive a 100-continue. Handle the final response accordingly.
Expand DownExpand Up@@ -817,6 +823,9 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Now that we're sending content, prohibit retries on this connection.
_canRetry = false;

Debug.Assert(stream.BytesWritten == 0);
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

// Copy all of the data to the server.
if (async)
{
Expand All@@ -833,6 +842,8 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Flush any content that might still be buffered.
await FlushAsync(async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(stream.BytesWritten);

if (NetEventSource.Log.IsEnabled()) Trace("Finished sending request content.");
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,6 +12,8 @@ internal partial class HttpConnection : IDisposable
{
private abstract class HttpContentWriteStream : HttpContentStream
{
public long BytesWritten { get; protected set; }

public HttpContentWriteStream(HttpConnection connection) : base(connection) =>
Debug.Assert(connection != null);

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,23 +91,53 @@ private void RequestLeftQueue(double timeOnQueueMilliseconds, byte versionMajor,
}

[Event(7, Level = EventLevel.Informational)]
public void ResponseHeadersBegin()
public void RequestHeadersStart()
{
WriteEvent(eventId: 7);
}

[Event(8, Level = EventLevel.Informational)]
public void ResponseContentStart()
public void RequestHeadersStop()
{
WriteEvent(eventId: 8);
}

[Event(9, Level = EventLevel.Informational)]
public void ResponseContentStop()
public void RequestContentStart()
{
WriteEvent(eventId: 9);
}

[Event(10, Level = EventLevel.Informational)]
public void RequestContentStop(long contentLength)
{
WriteEvent(eventId: 10, contentLength);
}

[Event(11, Level = EventLevel.Informational)]
public void ResponseHeadersStart()
{
WriteEvent(eventId: 11);
}

[Event(12, Level = EventLevel.Informational)]
public void ResponseHeadersStop()
{
WriteEvent(eventId: 12);
}

[Event(13, Level = EventLevel.Informational)]
public void ResponseContentStart()
{
WriteEvent(eventId: 13);
}

[Event(14, Level = EventLevel.Informational)]
public void ResponseContentStop()
{
WriteEvent(eventId: 14);
}

[NonEvent]
public void Http11ConnectionEstablished()
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,8 @@ public ChunkedEncodingWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand All@@ -39,6 +41,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,6 +17,8 @@ public ContentLengthWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand All@@ -27,6 +29,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored) // token ignored as it comes from SendAsync
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1354,6 +1354,8 @@ private async ValueTask<Http2Stream> SendHeadersAsync(HttpRequestMessage request
ArrayBuffer headerBuffer = default;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

// Serialize headers to a temporary buffer, and do as much work to prepare to send the headers as we can
// before taking the write lock.
headerBuffer = new ArrayBuffer(InitialConnectionBufferSize, usePool: true);
Expand DownExpand Up@@ -1434,6 +1436,9 @@ await PerformWriteAsync(totalSize, (thisRef: this, http2Stream, headerBytes, end

return s.mustFlush || s.endStream;
}, cancellationToken).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

return http2Stream;
}
catch
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -194,6 +194,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)
{
using var writeStream = new Http2WriteStream(this);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

ValueTask vt = _request.Content.InternalCopyToAsync(writeStream, context: null, _requestBodyCancellationSource.Token);
if (vt.IsCompleted)
{
Expand All@@ -208,6 +210,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)

await vt.ConfigureAwait(false);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(writeStream.BytesWritten);
}

if (NetEventSource.Log.IsEnabled()) Trace($"Finished sending request body.");
Expand DownExpand Up@@ -568,8 +572,6 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)

public void OnHeadersStart()
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();

Debug.Assert(!Monitor.IsEntered(SyncObject));
lock (SyncObject)
{
Expand DownExpand Up@@ -839,6 +841,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
bool emptyResponse;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Wait for response headers to be read.
bool wait;

Expand All@@ -851,6 +855,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
(wait, emptyResponse) = TryEnsureHeaders();
Debug.Assert(!wait);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();
}
catch
{
Expand DownExpand Up@@ -1344,6 +1350,8 @@ private sealed class Http2WriteStream : HttpBaseStream
{
private Http2Stream? _http2Stream;

public long BytesWritten { get; private set; }

public Http2WriteStream(Http2Stream http2Stream)
{
Debug.Assert(http2Stream != null);
Expand All@@ -1370,6 +1378,8 @@ protected override void Dispose(bool disposing)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{
BytesWritten += buffer.Length;

Http2Stream? http2Stream = _http2Stream;

if (http2Stream == null)
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -364,6 +364,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
CancellationTokenRegistration cancellationRegistration = RegisterCancellation(cancellationToken);
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

Debug.Assert(request.RequestUri != null);
// Write request line
await WriteStringAsync(normalizedMethod.Method, async).ConfigureAwait(false);
Expand DownExpand Up@@ -457,6 +459,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
// CRLF for end of headers.
await WriteTwoBytesAsync((byte)'\r', (byte)'\n', async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

if (request.Content == null)
{
// We have nothing more to send, so flush out any headers we haven't yet sent.
Expand DownExpand Up@@ -535,7 +539,7 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
var response = new HttpResponseMessage() { RequestMessage = request, Content = new HttpConnectionResponseContent() };
ParseStatusLine(await ReadNextResponseHeaderLineAsync(async).ConfigureAwait(false), response);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Multiple 1xx responses handling.
// RFC 7231: A client MUST be able to parse one or more 1xx responses received prior to a final response,
Expand DownExpand Up@@ -584,6 +588,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
ParseHeaderNameValue(this, line, response);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();

if (allowExpect100ToContinue != null)
{
// If we sent an Expect: 100-continue header, and didn't receive a 100-continue. Handle the final response accordingly.
Expand DownExpand Up@@ -817,6 +823,9 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Now that we're sending content, prohibit retries on this connection.
_canRetry = false;

Debug.Assert(stream.BytesWritten == 0);
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

// Copy all of the data to the server.
if (async)
{
Expand All@@ -833,6 +842,8 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Flush any content that might still be buffered.
await FlushAsync(async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(stream.BytesWritten);

if (NetEventSource.Log.IsEnabled()) Trace("Finished sending request content.");
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,6 +12,8 @@ internal partial class HttpConnection : IDisposable
{
private abstract class HttpContentWriteStream : HttpContentStream
{
public long BytesWritten { get; protected set; }

public HttpContentWriteStream(HttpConnection connection) : base(connection) =>
Debug.Assert(connection != null);

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,23 +91,53 @@ private void RequestLeftQueue(double timeOnQueueMilliseconds, byte versionMajor,
}

[Event(7, Level = EventLevel.Informational)]
public void ResponseHeadersBegin()
public void RequestHeadersStart()
{
WriteEvent(eventId: 7);
}

[Event(8, Level = EventLevel.Informational)]
public void ResponseContentStart()
public void RequestHeadersStop()
{
WriteEvent(eventId: 8);
}

[Event(9, Level = EventLevel.Informational)]
public void ResponseContentStop()
public void RequestContentStart()
{
WriteEvent(eventId: 9);
}

[Event(10, Level = EventLevel.Informational)]
public void RequestContentStop(long contentLength)
{
WriteEvent(eventId: 10, contentLength);
}

[Event(11, Level = EventLevel.Informational)]
public void ResponseHeadersStart()
{
WriteEvent(eventId: 11);
}

[Event(12, Level = EventLevel.Informational)]
public void ResponseHeadersStop()
{
WriteEvent(eventId: 12);
}

[Event(13, Level = EventLevel.Informational)]
public void ResponseContentStart()
{
WriteEvent(eventId: 13);
}

[Event(14, Level = EventLevel.Informational)]
public void ResponseContentStop()
{
WriteEvent(eventId: 14);
}

[NonEvent]
public void Http11ConnectionEstablished()
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,8 @@ public ChunkedEncodingWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand All@@ -39,6 +41,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,6 +17,8 @@ public ContentLengthWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand All@@ -27,6 +29,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored) // token ignored as it comes from SendAsync
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1354,6 +1354,8 @@ private async ValueTask<Http2Stream> SendHeadersAsync(HttpRequestMessage request
ArrayBuffer headerBuffer = default;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

// Serialize headers to a temporary buffer, and do as much work to prepare to send the headers as we can
// before taking the write lock.
headerBuffer = new ArrayBuffer(InitialConnectionBufferSize, usePool: true);
Expand DownExpand Up@@ -1434,6 +1436,9 @@ await PerformWriteAsync(totalSize, (thisRef: this, http2Stream, headerBytes, end

return s.mustFlush || s.endStream;
}, cancellationToken).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

return http2Stream;
}
catch
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -194,6 +194,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)
{
using var writeStream = new Http2WriteStream(this);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

ValueTask vt = _request.Content.InternalCopyToAsync(writeStream, context: null, _requestBodyCancellationSource.Token);
if (vt.IsCompleted)
{
Expand All@@ -208,6 +210,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)

await vt.ConfigureAwait(false);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(writeStream.BytesWritten);
}

if (NetEventSource.Log.IsEnabled()) Trace($"Finished sending request body.");
Expand DownExpand Up@@ -568,8 +572,6 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)

public void OnHeadersStart()
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();

Debug.Assert(!Monitor.IsEntered(SyncObject));
lock (SyncObject)
{
Expand DownExpand Up@@ -839,6 +841,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
bool emptyResponse;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Wait for response headers to be read.
bool wait;

Expand All@@ -851,6 +855,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
(wait, emptyResponse) = TryEnsureHeaders();
Debug.Assert(!wait);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();
}
catch
{
Expand DownExpand Up@@ -1344,6 +1350,8 @@ private sealed class Http2WriteStream : HttpBaseStream
{
private Http2Stream? _http2Stream;

public long BytesWritten { get; private set; }

public Http2WriteStream(Http2Stream http2Stream)
{
Debug.Assert(http2Stream != null);
Expand All@@ -1370,6 +1378,8 @@ protected override void Dispose(bool disposing)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{
BytesWritten += buffer.Length;

Http2Stream? http2Stream = _http2Stream;

if (http2Stream == null)
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -364,6 +364,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
CancellationTokenRegistration cancellationRegistration = RegisterCancellation(cancellationToken);
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

Debug.Assert(request.RequestUri != null);
// Write request line
await WriteStringAsync(normalizedMethod.Method, async).ConfigureAwait(false);
Expand DownExpand Up@@ -457,6 +459,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
// CRLF for end of headers.
await WriteTwoBytesAsync((byte)'\r', (byte)'\n', async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

if (request.Content == null)
{
// We have nothing more to send, so flush out any headers we haven't yet sent.
Expand DownExpand Up@@ -535,7 +539,7 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
var response = new HttpResponseMessage() { RequestMessage = request, Content = new HttpConnectionResponseContent() };
ParseStatusLine(await ReadNextResponseHeaderLineAsync(async).ConfigureAwait(false), response);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Multiple 1xx responses handling.
// RFC 7231: A client MUST be able to parse one or more 1xx responses received prior to a final response,
Expand DownExpand Up@@ -584,6 +588,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
ParseHeaderNameValue(this, line, response);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();

if (allowExpect100ToContinue != null)
{
// If we sent an Expect: 100-continue header, and didn't receive a 100-continue. Handle the final response accordingly.
Expand DownExpand Up@@ -817,6 +823,9 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Now that we're sending content, prohibit retries on this connection.
_canRetry = false;

Debug.Assert(stream.BytesWritten == 0);
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

// Copy all of the data to the server.
if (async)
{
Expand All@@ -833,6 +842,8 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Flush any content that might still be buffered.
await FlushAsync(async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(stream.BytesWritten);

if (NetEventSource.Log.IsEnabled()) Trace("Finished sending request content.");
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,6 +12,8 @@ internal partial class HttpConnection : IDisposable
{
private abstract class HttpContentWriteStream : HttpContentStream
{
public long BytesWritten { get; protected set; }

public HttpContentWriteStream(HttpConnection connection) : base(connection) =>
Debug.Assert(connection != null);

Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -91,23 +91,53 @@ private void RequestLeftQueue(double timeOnQueueMilliseconds, byte versionMajor,
}

[Event(7, Level = EventLevel.Informational)]
public void ResponseHeadersBegin()
public void RequestHeadersStart()
{
WriteEvent(eventId: 7);
}

[Event(8, Level = EventLevel.Informational)]
public void ResponseContentStart()
public void RequestHeadersStop()
{
WriteEvent(eventId: 8);
}

[Event(9, Level = EventLevel.Informational)]
public void ResponseContentStop()
public void RequestContentStart()
{
WriteEvent(eventId: 9);
}

[Event(10, Level = EventLevel.Informational)]
public void RequestContentStop(long contentLength)
{
WriteEvent(eventId: 10, contentLength);
}

[Event(11, Level = EventLevel.Informational)]
public void ResponseHeadersStart()
{
WriteEvent(eventId: 11);
}

[Event(12, Level = EventLevel.Informational)]
public void ResponseHeadersStop()
{
WriteEvent(eventId: 12);
}

[Event(13, Level = EventLevel.Informational)]
public void ResponseContentStart()
{
WriteEvent(eventId: 13);
}

[Event(14, Level = EventLevel.Informational)]
public void ResponseContentStop()
{
WriteEvent(eventId: 14);
}

[NonEvent]
public void Http11ConnectionEstablished()
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,8 @@ public ChunkedEncodingWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand All@@ -39,6 +41,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored)
{
BytesWritten += buffer.Length;

HttpConnection connection = GetConnectionOrThrow();
Debug.Assert(connection._currentRequest != null);

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,6 +17,8 @@ public ContentLengthWriteStream(HttpConnection connection) : base(connection)

public override void Write(ReadOnlySpan<byte> buffer)
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand All@@ -27,6 +29,8 @@ public override void Write(ReadOnlySpan<byte> buffer)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken ignored) // token ignored as it comes from SendAsync
{
BytesWritten += buffer.Length;

// Have the connection write the data, skipping the buffer. Importantly, this will
// force a flush of anything already in the buffer, i.e. any remaining request headers
// that are still buffered.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -1354,6 +1354,8 @@ private async ValueTask<Http2Stream> SendHeadersAsync(HttpRequestMessage request
ArrayBuffer headerBuffer = default;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

// Serialize headers to a temporary buffer, and do as much work to prepare to send the headers as we can
// before taking the write lock.
headerBuffer = new ArrayBuffer(InitialConnectionBufferSize, usePool: true);
Expand DownExpand Up@@ -1434,6 +1436,9 @@ await PerformWriteAsync(totalSize, (thisRef: this, http2Stream, headerBytes, end

return s.mustFlush || s.endStream;
}, cancellationToken).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

return http2Stream;
}
catch
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -194,6 +194,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)
{
using var writeStream = new Http2WriteStream(this);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

ValueTask vt = _request.Content.InternalCopyToAsync(writeStream, context: null, _requestBodyCancellationSource.Token);
if (vt.IsCompleted)
{
Expand All@@ -208,6 +210,8 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken)

await vt.ConfigureAwait(false);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(writeStream.BytesWritten);
}

if (NetEventSource.Log.IsEnabled()) Trace($"Finished sending request body.");
Expand DownExpand Up@@ -568,8 +572,6 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)

public void OnHeadersStart()
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();

Debug.Assert(!Monitor.IsEntered(SyncObject));
lock (SyncObject)
{
Expand DownExpand Up@@ -839,6 +841,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
bool emptyResponse;
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Wait for response headers to be read.
bool wait;

Expand All@@ -851,6 +855,8 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken)
(wait, emptyResponse) = TryEnsureHeaders();
Debug.Assert(!wait);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();
}
catch
{
Expand DownExpand Up@@ -1344,6 +1350,8 @@ private sealed class Http2WriteStream : HttpBaseStream
{
private Http2Stream? _http2Stream;

public long BytesWritten { get; private set; }

public Http2WriteStream(Http2Stream http2Stream)
{
Debug.Assert(http2Stream != null);
Expand All@@ -1370,6 +1378,8 @@ protected override void Dispose(bool disposing)

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{
BytesWritten += buffer.Length;

Http2Stream? http2Stream = _http2Stream;

if (http2Stream == null)
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -364,6 +364,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
CancellationTokenRegistration cancellationRegistration = RegisterCancellation(cancellationToken);
try
{
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStart();

Debug.Assert(request.RequestUri != null);
// Write request line
await WriteStringAsync(normalizedMethod.Method, async).ConfigureAwait(false);
Expand DownExpand Up@@ -457,6 +459,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
// CRLF for end of headers.
await WriteTwoBytesAsync((byte)'\r', (byte)'\n', async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestHeadersStop();

if (request.Content == null)
{
// We have nothing more to send, so flush out any headers we haven't yet sent.
Expand DownExpand Up@@ -535,7 +539,7 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
var response = new HttpResponseMessage() { RequestMessage = request, Content = new HttpConnectionResponseContent() };
ParseStatusLine(await ReadNextResponseHeaderLineAsync(async).ConfigureAwait(false), response);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersBegin();
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStart();

// Multiple 1xx responses handling.
// RFC 7231: A client MUST be able to parse one or more 1xx responses received prior to a final response,
Expand DownExpand Up@@ -584,6 +588,8 @@ public async Task<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request,
ParseHeaderNameValue(this, line, response);
}

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.ResponseHeadersStop();

if (allowExpect100ToContinue != null)
{
// If we sent an Expect: 100-continue header, and didn't receive a 100-continue. Handle the final response accordingly.
Expand DownExpand Up@@ -817,6 +823,9 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Now that we're sending content, prohibit retries on this connection.
_canRetry = false;

Debug.Assert(stream.BytesWritten == 0);
if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStart();

// Copy all of the data to the server.
if (async)
{
Expand All@@ -833,6 +842,8 @@ private async ValueTask SendRequestContentAsync(HttpRequestMessage request, Http
// Flush any content that might still be buffered.
await FlushAsync(async).ConfigureAwait(false);

if (HttpTelemetry.Log.IsEnabled()) HttpTelemetry.Log.RequestContentStop(stream.BytesWritten);

if (NetEventSource.Log.IsEnabled()) Trace("Finished sending request content.");
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,6 +12,8 @@ internal partial class HttpConnection : IDisposable
{
private abstract class HttpContentWriteStream : HttpContentStream
{
public long BytesWritten { get; protected set; }

public HttpContentWriteStream(HttpConnection connection) : base(connection) =>
Debug.Assert(connection != null);

Expand Down
Loading