I have created a question already on StackOverflow, but nobody seems to be able to answer it, so I will post it here.
I am using Akka Http (v. 10.1.10) to create a client with proxy. Each time the response is any other than successful, I get an error instead of a proper response entity:
akka.http.impl.engine.client.ProxyConnectionFailedException: The HTTP(S) proxy rejected to open a connection to hahahahahhahaahahhahaadsfsd.com:80 with status code: 503 Service Unavailable
at akka.http.impl.engine.client.HttpsProxyGraphStage$anon$1$anon$4.onPush(HttpsProxyGraphStage.scala:143)
at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:523)
at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:409)
at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:606)
at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:485)
at akka.stream.impl.fusing.GraphInterpreterShell.processEvent(ActorGraphInterpreter.scala:581)
at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$processEvent(ActorGraphInterpreter.scala:749)
at akka.stream.impl.fusing.ActorGraphInterpreter$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:764)
at akka.actor.Actor.aroundReceive(Actor.scala:539)
at akka.actor.Actor.aroundReceive$(Actor.scala:537)
at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:671)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:612)
at akka.actor.ActorCell.invoke(ActorCell.scala:581)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:268)
at akka.dispatch.Mailbox.run(Mailbox.scala:229)
at akka.dispatch.Mailbox.exec(Mailbox.scala:241)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
In the Akka Http core code, I found that it is the implementation of the handler for proxy that forces the error on purpose if the response is any other than successful:
case Connecting =>
val proxyResponse = grab(bytesIn)
parser.parseBytes(proxyResponse) match {
case NeedMoreData =>
pull(bytesIn)
case ResponseStart(_: StatusCodes.Success, _, _, _, _) =>
var pushed = false
val parseResult = parser.onPull()
require(parseResult == ParserOutput.MessageEnd, s"parseResult should be MessageEnd but was $parseResult")
parser.onPull() match {
// NeedMoreData is what we emit in overridden `parseMessage` in case input.size == offset
case NeedMoreData =>
case RemainingBytes(bytes) =>
push(sslOut, bytes) // parser already read more than expected, forward that data directly
pushed = true
case other =>
throw new IllegalStateException(s"unexpected element of type ${other.getClass}")
}
parser.onUpstreamFinish()
log.debug(s"HTTP(S) proxy connection to {}:{} established. Now forwarding data.", targetHostName, targetPort)
state = Connected
if (isAvailable(bytesOut)) pull(sslIn)
if (isAvailable(sslOut)) pull(bytesIn)
case ResponseStart(statusCode, _, _, _, _) =>
failStage(new ProxyConnectionFailedException(s"The HTTP(S) proxy rejected to open a connection to $targetHostName:$targetPort with status code: $statusCode"))
case other =>
throw new IllegalStateException(s"unexpected element of type $other")
}
I am wondering what is the reason for such implementation, if someone knows? And how to work it around to get a response entity instead of the error when response from the server is not successful?