Skip to content

Conversation

@HofmeisterAn
Copy link
Collaborator

@HofmeisterAn HofmeisterAn commented Dec 13, 2025

The HijackStream() method blocks hijacking if the stream is wrapped because it needs direct access to the raw transport stream for protocol upgrades. This PR changes how the library handles the response stream: when an Upgrade header is set, the Content-Length header is ignored, allowing the stream to be hijacked successfully, closes #34. This probably relates to and fixes #47 as well.

@lanwen Thanks for already addressing the issue in TC Desktop. If I understood your comment correctly, you had something like this in mind. It would be great if you could take a quick look at the changes in HttpConnection to make sure I got it right. Thanks!

@HofmeisterAn HofmeisterAn added the bug Something isn't working label Dec 13, 2025
Copy link

@lanwen lanwen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks legit, please let me know how can I try that. We have a stable reproducer here: https://github.com/ivan-curkovic/tcc-bug-reproduction

@HofmeisterAn
Copy link
Collaborator Author

HofmeisterAn commented Dec 15, 2025

Looks legit, please let me know how can I try that. We have a stable reproducer here: https://github.com/ivan-curkovic/tcc-bug-reproduction

Probably the best approach is to use this branch locally or in GH Codespaces.

Just change the endpoint of the container runtime:

diff --git a/test/Docker.DotNet.Tests/TestFixture.cs b/test/Docker.DotNet.Tests/TestFixture.cs
index b32ecd6..ada3469 100644
--- a/test/Docker.DotNet.Tests/TestFixture.cs
+++ b/test/Docker.DotNet.Tests/TestFixture.cs
@@ -21,7 +21,7 @@ public sealed class TestFixture : Progress<JSONMessage>, IAsyncLifetime, IDispos
     public TestFixture(IMessageSink messageSink)
     {
         _messageSink = messageSink;
-        DockerClientConfiguration = new DockerClientConfiguration();
+        DockerClientConfiguration = new DockerClientConfiguration(endpoint: new Uri("http://localhost:12345"));
         DockerClient = DockerClientConfiguration.CreateClient(logger: this);
         Cts = new CancellationTokenSource(TimeSpan.FromMinutes(5));
         Cts.Token.Register(() => throw new TimeoutException("Docker.DotNet tests timed out."));

and run the tests:

dotnet test --framework net10.0

If Docker_IsRunning is failing, you can ignore it.

You can also just run the tests related to creating and starting containers (that should be enough):

dotnet test --framework net10.0 --filter FullyQualifiedName~IContainerOperationsTests

Edit: Unfortunately, I don't think we can use the reproducer. TC for .NET isn't compatible with Docker Engine v29 yet, though Docker.DotNet has already been updated. Normally, we could just bump the transitive dependency.

@lanwen
Copy link

lanwen commented Dec 15, 2025

@HofmeisterAn I mean if I can try it as a dependency for the reproducer - is that possible from the local branch?

@HofmeisterAn
Copy link
Collaborator Author

@HofmeisterAn I mean if I can try it as a dependency for the reproducer - is that possible from the local branch?

That's what my edit is referring to. I don't think it's that simple because of incompatibility with Docker Engine v29.

OC, we can try:

  1. Checkout v3.130.0.
  2. Cherry-pick the fix from this branch.
  3. Bump TC in the reproducer to v4.9.0.
  4. Add Docker.DotNet as a local project in the reproducer SLN.
  5. Add a project reference for Docker.DotNet in TccTest1.csproj.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Rancher Desktop invalid chunk header encountered [Bug]: Testcontainers Desktop cannot hijack chunked or content length stream

3 participants