Quantcast
Channel: Akka Libraries - Discussion Forum for Akka technologies
Viewing all articles
Browse latest Browse all 1362

POST request with Content-Length header produces "Sending an 2xx 'early' response"

$
0
0

Hello,
I am getting the following WARN’s

[2021-09-10 16:41:57,406] [WARN] [akka.actor.ActorSystemImpl] [default-akka.actor.default-dispatcher-16] [akka.actor.ActorSystemImpl(default)] - Sending an 2xx 'early' response before end of request for http://localhost:8080/collection-ids?entity_class=SOME_CLASS_ID received... Note that the connection will be closed after this response. Also, many clients will not read early responses! Consider only issuing this response after the request data has been completely read!

while external client calls my service like this (see demo app below)

curl --request POST 'http://localhost:8080/collection-ids?entity_class=SOME_CLASS_ID' \
-H 'Content-Type: application/json' \
-H 'Content-Length: 1234'

Please note that it’s a POST request and it contains Content-Length header.

Logs:

[2021-09-10 16:41:57,406] [INFO] [akka.actor.ActorSystemImpl] [default-akka.actor.default-dispatcher-16] [akka.actor.ActorSystemImpl(default)] - Client ReST: Response for
  Request : HttpRequest(HttpMethod(POST),http://localhost:8080/collection-ids?entity_class=SOME_CLASS_ID,List(Timeout-Access: <function1>, Host, User-Agent: curl/7.54.0, Accept: */*),HttpEntity.Default(application/json,1234 bytes total),HttpProtocol(HTTP/1.1))
  Response: Complete(HttpResponse(200 OK,List(),HttpEntity.Strict(application/json,24 bytes total),HttpProtocol(HTTP/1.1)))
[2021-09-10 16:41:57,406] [WARN] [akka.actor.ActorSystemImpl] [default-akka.actor.default-dispatcher-16] [akka.actor.ActorSystemImpl(default)] - Sending an 2xx 'early' response before end of request for http://localhost:8080/collection-ids?entity_class=SOME_CLASS_ID received... Note that the connection will be closed after this response. Also, many clients will not read early responses! Consider only issuing this response after the request data has been completely read!

I am sure that I’ve been getting these WARNs because Content-Length header.
Side note: when request is POST + Content-Length HttpEntity type is Default (see logs above)

The following call doesn’t produce any warning:

curl --location --request POST 'http://localhost:8080/collection-ids?entity_class=SOME_CLASS_ID' \
-H 'Content-Type: application/json'

Logs:

[2021-09-10 16:42:10,575] [INFO] [akka.actor.ActorSystemImpl] [default-akka.actor.default-dispatcher-4] [akka.actor.ActorSystemImpl(default)] - Client ReST: Response for
  Request : HttpRequest(HttpMethod(POST),http://localhost:8080/collection-ids?entity_class=SOME_CLASS_ID,List(Timeout-Access: <function1>, Host, User-Agent: curl/7.54.0, Accept: */*),HttpEntity.Strict(application/json,0 bytes total),HttpProtocol(HTTP/1.1))
  Response: Complete(HttpResponse(200 OK,List(),HttpEntity.Strict(application/json,24 bytes total),HttpProtocol(HTTP/1.1)))

Side note: when request POST + without Content-Length HttpEntity type is Strict (see logs above)

As I said it’s an external client. I can’t change the API as well as can’t force client to exclude Content-Length from their POST request.

Question

is it possible to “mute” this particular WARN via akka-http Directive or another workaround?
P.S. I can’t “mute” akka.actor.ActorSystemImpl because it might produce other important warnings.

References


Demo app

lib verions:

lazy val akkaHttpVersion = "10.2.6"
lazy val akkaVersion    = "2.6.16"

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-http"                % akkaHttpVersion,
  "com.typesafe.akka" %% "akka-http-spray-json"     % akkaHttpVersion,
  "com.typesafe.akka" %% "akka-actor-typed"         % akkaVersion,
  "com.typesafe.akka" %% "akka-stream"              % akkaVersion,
  "ch.qos.logback"    % "logback-classic"           % "1.2.3"

Souce

package com.example

import akka.actor.ActorSystem
import akka.event.Logging
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.directives.DebuggingDirectives
import spray.json.DefaultJsonProtocol

import scala.concurrent.Future
import scala.io.StdIn

object JsonFormats  {
  import DefaultJsonProtocol._
  implicit val userJsonFormat = jsonFormat1(User)
}

final case class User(name: String)

object CollectionRoutes {

  import JsonFormats._
  import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._

  val collectionRoute: Route = {
    pathPrefix("collection-ids") {
      post {
        parameters("entity_class") { entityClass =>
          complete(Future.successful(User(entityClass)))
        }
      }
    }
  }

  val collectionRouteLogged = DebuggingDirectives.logRequestResult("Client ReST", Logging.InfoLevel)(collectionRoute)
}

object HttpServerHighLevel {
  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()
    implicit val executionContext = system.dispatcher

    val bindingFuture = Http().newServerAt("localhost", 8080).bind(CollectionRoutes.collectionRouteLogged)
    println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
    StdIn.readLine()
    bindingFuture
      .flatMap(_.unbind())
      .onComplete(_ => system.terminate())
  }
}

1 post - 1 participant

Read full topic


Viewing all articles
Browse latest Browse all 1362

Trending Articles