Skip to content

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

@cataphract

Description

@cataphract

This is happening since 10.1.2 (offending commit is f62419e)

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    1 - triagedTickets that are safe to pick up for contributing in terms of likeliness of being acceptedbug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions