akka-http icon indicating copy to clipboard operation
akka-http copied to clipboard

Duplicated 100 responses if there is an exception thrown by the unmarshaller

Open cataphract opened this issue 2 years ago • 1 comments

This is happening since 10.1.2 (offending commit is f62419e06)

build.gradle

plugins {
    id 'scala'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation group: 'com.typesafe.akka', name: 'akka-http_2.12', version: '10.1.2'
    implementation group: 'com.typesafe.akka', name: 'akka-stream_2.12', version: '2.5.+'
}

task runServer(type: JavaExec) {
    main = 'sample.Main'
    classpath = sourceSets.main.runtimeClasspath
    args = []
}

src/main/scala/Main.scala

package sample

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.unmarshalling.FromEntityUnmarshaller
import akka.http.scaladsl.unmarshalling.Unmarshaller.messageUnmarshallerFromEntityUnmarshaller
import akka.stream.ActorMaterializer

import scala.util.Random

object Main {

  implicit val randomStringUnmarshaller: FromEntityUnmarshaller[String] = {
    import akka.http.scaladsl.unmarshalling.PredefinedFromEntityUnmarshallers._

    stringUnmarshaller.map { str =>
      if (Random.nextBoolean()) {
        str
      } else {
        throw new RuntimeException("Random Unmarshalling Failure")
      }
    }
  }

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem("my-system")
    implicit val materializer = ActorMaterializer()
    implicit val executionContext = system.dispatcher

    val route: Route = {
        path("post-endpoint") {
          post {
            entity(as[String]) { data =>
              complete(s"Received: $data")
            }
          }
        }
    }

    val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)

    println(s"Server online at http://localhost:8080/")
  }
}

Results:

$ curl -H 'Expect: 100-continue' -d a=x -v http://localhost:8080/post-endpoint
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /post-endpoint HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.81.0
> Accept: */*
> Expect: 100-continue
> Content-Length: 3
> Content-Type: application/x-www-form-urlencoded
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 100 Continue
< Server: akka-http/10.1.2
< Date: Fri, 01 Sep 2023 10:03:25 GMT
* We are completely uploaded and fine
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: akka-http/10.1.2
< Date: Fri, 01 Sep 2023 10:03:25 GMT
< Content-Type: text/plain; charset=UTF-8
< Content-Length: 13
< 
* Connection #0 to host localhost left intact
Received: a=x
$ curl -H 'Expect: 100-continue' -d a=x -v http://localhost:8080/post-endpoint
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /post-endpoint HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.81.0
> Accept: */*
> Expect: 100-continue
> Content-Length: 3
> Content-Type: application/x-www-form-urlencoded
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 100 Continue
< Server: akka-http/10.1.2
< Date: Fri, 01 Sep 2023 10:04:44 GMT
* We are completely uploaded and fine
* Mark bundle as not supporting multiuse
< HTTP/1.1 100 Continue
< Server: akka-http/10.1.2
< Date: Fri, 01 Sep 2023 10:04:44 GMT
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request
< Server: akka-http/10.1.2
< Date: Fri, 01 Sep 2023 10:04:44 GMT
< Content-Type: text/plain; charset=UTF-8
< Content-Length: 63
< 
The request content was malformed:
* Connection #0 to host localhost left intact
Random Unmarshalling Failure

cataphract avatar Sep 01 '23 10:09 cataphract

Thanks for the detailed report

johanandren avatar Sep 04 '23 07:09 johanandren