michaelf-crwd opened a new issue, #583:
URL: https://github.com/apache/pekko-http/issues/583
Hi Pekko team,
I'm having an odd issue with a simple http request to a pekko micro service.
The `Accept-Charset` header value is deliberately set wrong (by a security
scanning tool) and the result is Server Error 500 and a stack trace logged out
server side. Expected behaviour was for pekko-http to do a default to e.g.
UTF-8 charset and report back a server side error to the client, nor log out a
stack trace.
Minimal sample scala code processing the inbound request:
```
import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.event.{Logging, LoggingAdapter}
import org.apache.pekko.http.scaladsl.Http
import org.apache.pekko.http.scaladsl.model.{ContentTypes, HttpEntity}
import org.apache.pekko.http.scaladsl.server.Directives._
import org.apache.pekko.http.scaladsl.server.Route
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import scala.concurrent.ExecutionContext
import scala.util.Using
trait Service {
implicit val system: ActorSystem
implicit def executor: ExecutionContext
def config: Config
val logger: LoggingAdapter
val routes: Route = {
logRequestResult("pekko-http-microservice") {
concat(
// http://localhost:9000/hello
path("hello") {
get {
complete(HttpEntity(ContentTypes.`text/html(UTF-8)`,
"<h1>Greetings from the pekko-http-microservice</h1>"))
}
}
)
}
}
}
object ServerApp extends App with Service {
override implicit val system: ActorSystem = ActorSystem()
override implicit val executor: ExecutionContext = system.dispatcher
override val config = ConfigFactory.load()
override val logger = Logging(system, "pekkoHttpMicroservice")
Http()
.newServerAt(config.getString("http.interface"),
config.getInt("http.port"))
.bindFlow(routes)
}
```
Sample request:
```
curl -v -H "Accept-Charset: wrong" http://localhost:9000/hello
* Host localhost:9000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:9000...
* Connected to localhost (::1) port 9000
> GET /hello HTTP/1.1
> Host: localhost:9000
> User-Agent: curl/8.6.0
> Accept: */*
> Accept-Charset: wrong
>
< HTTP/1.1 500 Internal Server Error
< Server: pekko-http/1.0.1
< Date: Mon, 12 Aug 2024 10:34:32 GMT
< Content-Type: text/plain; charset=UTF-8
< Content-Length: 35
<
* Connection #0 to host localhost left intact
There was an internal server error.%
```
Expected response:
```
< HTTP/1.1 200 OK
< Server: pekko-http/1.0.1
< Date: Mon, 12 Aug 2024 10:35:10 GMT
< Content-Type: text/html; charset=UTF-8
< Content-Length: 51
<
* Connection #0 to host localhost left intact
<h1>Greetings from the pekko-http-microservice</h1>%
```
The following stack-trace is logged server-side:
```
[ERROR] [08/12/2024 12:34:32.515]
[default-pekko.actor.default-dispatcher-107]
[org.apache.pekko.actor.ActorSystemImpl(default)] Error during processing of
request: 'wrong'. Completing with 500 Internal Server Error response. To change
default exception handling behavior, provide a custom ExceptionHandler.
java.nio.charset.UnsupportedCharsetException: wrong
at java.base/java.nio.charset.Charset.forName(Charset.java:559)
at
org.apache.pekko.http.scaladsl.model.HttpCharset$.$anonfun$findNioCharset$1(HttpCharset.scala:88)
at scala.util.Try$.apply(Try.scala:217)
at
org.apache.pekko.http.scaladsl.model.HttpCharset$.findNioCharset(HttpCharset.scala:88)
at
org.apache.pekko.http.scaladsl.model.HttpCharset.<init>(HttpCharset.scala:64)
at
org.apache.pekko.http.scaladsl.model.HttpCharset$.apply(HttpCharset.scala:62)
at
org.apache.pekko.http.scaladsl.model.HttpCharset$.custom(HttpCharset.scala:86)
at
org.apache.pekko.http.impl.model.parser.CommonActions.$anonfun$getCharset$1(CommonActions.scala:71)
at scala.Option.getOrElse(Option.scala:201)
at
org.apache.pekko.http.impl.model.parser.CommonActions.getCharset(CommonActions.scala:71)
at
org.apache.pekko.http.impl.model.parser.CommonActions.getCharset$(CommonActions.scala:68)
at
org.apache.pekko.http.impl.model.parser.HeaderParser.getCharset(HeaderParser.scala:37)
at
org.apache.pekko.http.impl.model.parser.AcceptCharsetHeader.charset$minusrange$minusdef(AcceptCharsetHeader.scala:38)
at
org.apache.pekko.http.impl.model.parser.AcceptCharsetHeader.charset$minusrange$minusdef$(AcceptCharsetHeader.scala:37)
at
org.apache.pekko.http.impl.model.parser.HeaderParser.charset$minusrange$minusdef(HeaderParser.scala:37)
at
org.apache.pekko.http.impl.model.parser.AcceptCharsetHeader.charset$minusrange$minusdecl(AcceptCharsetHeader.scala:29)
at
org.apache.pekko.http.impl.model.parser.AcceptCharsetHeader.charset$minusrange$minusdecl$(AcceptCharsetHeader.scala:28)
at
org.apache.pekko.http.impl.model.parser.HeaderParser.charset$minusrange$minusdecl(HeaderParser.scala:37)
at
org.apache.pekko.http.impl.model.parser.AcceptCharsetHeader.rec$2(AcceptCharsetHeader.scala:25)
at
org.apache.pekko.http.impl.model.parser.AcceptCharsetHeader.accept$minuscharset(AcceptCharsetHeader.scala:24)
at
org.apache.pekko.http.impl.model.parser.AcceptCharsetHeader.accept$minuscharset$(AcceptCharsetHeader.scala:24)
at
org.apache.pekko.http.impl.model.parser.HeaderParser.accept$minuscharset(HeaderParser.scala:37)
at
org.apache.pekko.http.impl.model.parser.HeaderParser$$anon$1$$anon$60.$anonfun$apply$59(HeaderParser.scala:141)
at org.parboiled2.Parser.__run(Parser.scala:125)
at
org.apache.pekko.http.impl.model.parser.HeaderParser$$anon$1$$anon$60.apply(HeaderParser.scala:141)
at
org.parboiled2.DynamicRuleDispatch.$anonfun$apply$1(DynamicRuleDispatch.scala:36)
at scala.Option.map(Option.scala:242)
at
org.parboiled2.DynamicRuleDispatch.apply(DynamicRuleDispatch.scala:36)
at
org.parboiled2.DynamicRuleDispatch.apply$(DynamicRuleDispatch.scala:35)
at
org.apache.pekko.http.impl.model.parser.HeaderParser$$anon$1.apply(HeaderParser.scala:141)
at
org.apache.pekko.http.impl.model.parser.HeaderParser$.$anonfun$lookupParser$1(HeaderParser.scala:126)
at
org.apache.pekko.http.impl.engine.parsing.HttpHeaderParser$ModeledHeaderValueParser.apply(HttpHeaderParser.scala:570)
at
org.apache.pekko.http.impl.engine.parsing.HttpHeaderParser.startValueBranch$1(HttpHeaderParser.scala:125)
at
org.apache.pekko.http.impl.engine.parsing.HttpHeaderParser.parseHeaderLine(HttpHeaderParser.scala:145)
at
org.apache.pekko.http.impl.engine.parsing.HttpMessageParser.parseHeaderLines(HttpMessageParser.scala:158)
at
org.apache.pekko.http.impl.engine.parsing.HttpMessageParser.parseHeaderLines$(HttpMessageParser.scala:148)
at
org.apache.pekko.http.impl.engine.parsing.HttpRequestParser$$anon$1.parseHeaderLines(HttpRequestParser.scala:59)
at
org.apache.pekko.http.impl.engine.parsing.HttpRequestParser$$anon$1.parseMessage(HttpRequestParser.scala:94)
at
org.apache.pekko.http.impl.engine.parsing.HttpMessageParser.startNewMessage(HttpMessageParser.scala:124)
at
org.apache.pekko.http.impl.engine.parsing.HttpMessageParser.startNewMessage$(HttpMessageParser.scala:122)
at
org.apache.pekko.http.impl.engine.parsing.HttpRequestParser$$anon$1.startNewMessage(HttpRequestParser.scala:59)
at
org.apache.pekko.http.impl.engine.parsing.HttpMessageParser.$anonfun$state$1(HttpMessageParser.scala:49)
at
org.apache.pekko.http.impl.engine.parsing.HttpMessageParser.run$1(HttpMessageParser.scala:82)
at
org.apache.pekko.http.impl.engine.parsing.HttpMessageParser.parseBytes(HttpMessageParser.scala:96)
at
org.apache.pekko.http.impl.engine.parsing.HttpMessageParser.parseBytes$(HttpMessageParser.scala:80)
at
org.apache.pekko.http.impl.engine.parsing.HttpRequestParser$$anon$1.parseBytes(HttpRequestParser.scala:59)
at
org.apache.pekko.http.impl.engine.parsing.HttpMessageParser.parseSessionBytes(HttpMessageParser.scala:78)
at
org.apache.pekko.http.impl.engine.parsing.HttpMessageParser.parseSessionBytes$(HttpMessageParser.scala:73)
at
org.apache.pekko.http.impl.engine.parsing.HttpRequestParser$$anon$1.parseSessionBytes(HttpRequestParser.scala:59)
at
org.apache.pekko.http.impl.engine.parsing.HttpRequestParser$$anon$1.onPush(HttpRequestParser.scala:71)
at
org.apache.pekko.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:555)
at
org.apache.pekko.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:433)
at
org.apache.pekko.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:662)
at
org.apache.pekko.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:532)
at
org.apache.pekko.stream.impl.fusing.GraphInterpreterShell.processEvent(ActorGraphInterpreter.scala:637)
at
org.apache.pekko.stream.impl.fusing.ActorGraphInterpreter.org$apache$pekko$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:813)
at
org.apache.pekko.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:831)
at org.apache.pekko.actor.Actor.aroundReceive(Actor.scala:547)
at org.apache.pekko.actor.Actor.aroundReceive$(Actor.scala:545)
at
org.apache.pekko.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:729)
at org.apache.pekko.actor.ActorCell.receiveMessage(ActorCell.scala:590)
at org.apache.pekko.actor.ActorCell.invoke(ActorCell.scala:557)
at org.apache.pekko.dispatch.Mailbox.processMailbox(Mailbox.scala:280)
at org.apache.pekko.dispatch.Mailbox.run(Mailbox.scala:241)
at org.apache.pekko.dispatch.Mailbox.exec(Mailbox.scala:253)
at
java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
at
java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1491)
at
java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:2073)
at
java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2035)
at
java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:187)
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]