nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: http4s/http4s
Pull request #6745 (2022-10-12 18:04:03)

Make StreamForking resource safe in the face of cancelation
This is a backport of #6610 by @TimWSpence to 0.23 branch.


Patch:
diff --git a/ember-server/shared/src/main/scala/org/http4s/ember/server/internal/StreamForking.scala b/ember-server/shared/src/main/scala/org/http4s/ember/server/internal/StreamForking.scala
index 496ef92c0f..e08b96b038 100644
--- a/ember-server/shared/src/main/scala/org/http4s/ember/server/internal/StreamForking.scala
+++ b/ember-server/shared/src/main/scala/org/http4s/ember/server/internal/StreamForking.scala
@@ -18,6 +18,7 @@ package org.http4s.ember.server.internal
 
 import cats.effect.Concurrent
 import cats.effect.std.Semaphore
+import cats.effect.syntax.all._
 import cats.syntax.all._
 import fs2.Stream
 import fs2.concurrent.Signal
@@ -60,7 +61,8 @@ private[internal] object StreamForking {
           .interruptWhen(stopSignal)
           .compile
           .drain
-          .handleErrorWith(stopFailed) >> available.release >> decrementRunning
+          .handleErrorWith(stopFailed)
+          .guarantee(available.release >> decrementRunning)
 
         available.acquire >> incrementRunning >> F.start(fa).void
       }


Test patch:
diff --git a/ember-server/shared/src/test/scala/org/http4s/ember/server/internal/StreamForkingSuite.scala b/ember-server/shared/src/test/scala/org/http4s/ember/server/internal/StreamForkingSuite.scala
index 73fa6577d3..8ec105431a 100644
--- a/ember-server/shared/src/test/scala/org/http4s/ember/server/internal/StreamForkingSuite.scala
+++ b/ember-server/shared/src/test/scala/org/http4s/ember/server/internal/StreamForkingSuite.scala
@@ -74,4 +74,19 @@ class StreamForkingSuite extends CatsEffectSuite {
       .intercept[RuntimeException]
   }
 
+  test("inner stream cancels") {
+    IO.ref(false)
+      .flatMap { ref =>
+        val stream = Stream(
+          Stream.eval(IO.canceled),
+          Stream.eval(ref.set(true)),
+        )
+
+        // canceled stream should still return semaphore permit
+        // and allow second eval to run
+        forking(stream, 1).compile.drain >> ref.get
+      }
+      .assertEquals(true)
+  }
+
 }
Repository: http4s/http4s
Pull request #6781 (2022-10-31 23:55:28)

`Shutdown#trackConnection` should never be empty
Fixes https://github.com/http4s/http4s/issues/6780.


Patch:
diff --git a/ember-server/shared/src/main/scala/org/http4s/ember/server/internal/Shutdown.scala b/ember-server/shared/src/main/scala/org/http4s/ember/server/internal/Shutdown.scala
index e0660ada63..fe71305826 100644
--- a/ember-server/shared/src/main/scala/org/http4s/ember/server/internal/Shutdown.scala
+++ b/ember-server/shared/src/main/scala/org/http4s/ember/server/internal/Shutdown.scala
@@ -100,7 +100,7 @@ private[server] object Shutdown {
         override val signal: F[Unit] = unblock.get
         override val newConnection: F[Unit] = F.unit
         override val removeConnection: F[Unit] = F.unit
-        override val trackConnection: Stream[F, Unit] = Stream.empty
+        override val trackConnection: Stream[F, Unit] = Stream.emit(())
       }
     }
 


Test patch:
diff --git a/ember-server/shared/src/test/scala/org/http4s/ember/server/EmberServerSuite.scala b/ember-server/shared/src/test/scala/org/http4s/ember/server/EmberServerSuite.scala
index f9d63da224..930adf8caa 100644
--- a/ember-server/shared/src/test/scala/org/http4s/ember/server/EmberServerSuite.scala
+++ b/ember-server/shared/src/test/scala/org/http4s/ember/server/EmberServerSuite.scala
@@ -28,6 +28,8 @@ import org.http4s.ember.client.EmberClientBuilder
 import org.http4s.implicits._
 import org.http4s.server.Server
 
+import scala.concurrent.duration._
+
 class EmberServerSuite extends Http4sSuite {
 
   def service[F[_]](implicit F: Async[F]): HttpApp[F] = {
@@ -47,12 +49,15 @@ class EmberServerSuite extends Http4sSuite {
   def url(address: SocketAddress[Host], path: String = ""): String =
     s"http://${Uri.Host.fromIp4sHost(address.host).renderString}:${address.port.value}$path"
 
-  val serverResource: Resource[IO, Server] =
-    EmberServerBuilder
-      .default[IO]
-      .withPort(port"0")
-      .withHttpApp(service[IO])
-      .build
+  def serverResource(
+      f: EmberServerBuilder[IO] => EmberServerBuilder[IO] = identity
+  ): Resource[IO, Server] =
+    f(
+      EmberServerBuilder
+        .default[IO]
+        .withPort(port"0")
+        .withHttpApp(service[IO])
+    ).build
 
   private val client = ResourceFunFixture(EmberClientBuilder.default[IO].build)
 
@@ -75,13 +80,19 @@ class EmberServerSuite extends Http4sSuite {
   }
 
   client.test("server shuts down after exiting resource scope") { client =>
-    serverResource.use(server => IO.pure(server.addressIp4s)).flatMap { address =>
+    serverResource().use(server => IO.pure(server.addressIp4s)).flatMap { address =>
       client
         .get(url(address))(_.status.pure[IO])
         .intercept[ConnectException]
     }
   }
 
+  client.test("shutdown timeout of 0 doesn't reset connections") { client =>
+    serverResource(_.withShutdownTimeout(0.nanos)).use { server =>
+      client.expect[String](url(server.addressIp4s)).assertEquals("Hello!")
+    }
+  }
+
   server().test("server startup fails if address is already in use") { server =>
     EmberServerBuilder
       .default[IO]
Repository: http4s/http4s
Pull request #6853 (2022-12-06 14:09:45)

Fix for 6851 : Uri.Path.Segment can throw from its equals method
Let me know if I've picked the wrong place for the test!


Patch:
diff --git a/core/shared/src/main/scala/org/http4s/Uri.scala b/core/shared/src/main/scala/org/http4s/Uri.scala
index b22a781f9e..ac1f1cea2f 100644
--- a/core/shared/src/main/scala/org/http4s/Uri.scala
+++ b/core/shared/src/main/scala/org/http4s/Uri.scala
@@ -467,6 +467,7 @@ object Uri extends UriPlatform {
       override def equals(obj: Any): Boolean =
         obj match {
           case s: Segment => s.encoded == encoded
+          case _ => false
         }
 
       override def hashCode(): Int = encoded.hashCode


Test patch:
diff --git a/tests/shared/src/test/scala/org/http4s/SegmentSuite.scala b/tests/shared/src/test/scala/org/http4s/SegmentSuite.scala
index bceba77a94..e9a12160ca 100644
--- a/tests/shared/src/test/scala/org/http4s/SegmentSuite.scala
+++ b/tests/shared/src/test/scala/org/http4s/SegmentSuite.scala
@@ -17,9 +17,15 @@
 package org.http4s
 
 import cats.kernel.laws.discipline.OrderTests
+import munit.Compare
 import org.http4s.Uri.Path.Segment
 import org.http4s.laws.discipline.arbitrary._
 
 class SegmentSuite extends Http4sSuite {
   checkAll("Order[Segment]", OrderTests[Segment].order)
+
+  test("equals does not throw") {
+    implicit val comp: Compare[Segment, String] = Compare.defaultCompare
+    assertNotEquals(Uri.Path.Segment.apply("123"), "123")
+  }
 }