perwendel / spark

A simple expressive web framework for java. Spark has a kotlin DSL https://github.com/perwendel/spark-kotlin
Apache License 2.0
9.63k stars 1.56k forks source link

Request.body() throws NullPointerException if stream throws any exception (EOFException) #1178

Open vryzhuk opened 4 years ago

vryzhuk commented 4 years ago

Spark catches actual exception during reading body's input stream: https://github.com/perwendel/spark/blob/77345cffe3285cdef958be56a731aa2f67bd5229/src/main/java/spark/Request.java#L275

During the call to Request.body() we expect bodyAsBytes to be not null https://github.com/perwendel/spark/blob/77345cffe3285cdef958be56a731aa2f67bd5229/src/main/java/spark/Request.java#L258 But bodyAsBytes won't be initialized if we get an Exception during reading an input stream. In this case we would have a warning with actual exception and NullPointerException would be thrown from Request.body()

Steps to reproduce:

  1. Create request and let body's inputStream throw an exception (request could have no body)
  2. Call Request.body()

Expected result: re-throw the error or return null body.

Actual result: NullPointerException

Logs Warning log:

Exception when reading body
org.eclipse.jetty.io.EofException: Early EOF
    at org.eclipse.jetty.server.HttpInput$3.getError(HttpInput.java:1143)
    at org.eclipse.jetty.server.HttpInput$3.noContent(HttpInput.java:1131)
    at org.eclipse.jetty.server.HttpInput.read(HttpInput.java:318)
    at java.base/java.io.InputStream.read(InputStream.java:205)
    at spark.utils.IOUtils.toByteArray(IOUtils.java:133)
    at spark.embeddedserver.jetty.HttpRequestWrapper.cacheInputStream(HttpRequestWrapper.java:73)
    at spark.embeddedserver.jetty.HttpRequestWrapper.getInputStream(HttpRequestWrapper.java:67)
    at spark.Request.readBodyAsBytes(Request.java:271)
    at spark.Request.bodyAsBytes(Request.java:264)
    at spark.Request.body(Request.java:256)
    at spark.http.matching.RequestWrapper.body(RequestWrapper.java:94)

Error log:

java.lang.NullPointerException: null
at java.lang.String.<init> (String.java:537)
at spark.utils.StringUtils.toString (StringUtils.java:381)
at spark.Request.body (Request.java:256)
at spark.http.matching.RequestWrapper.body (RequestWrapper.java:94)
...
vryzhuk commented 4 years ago

Possible workaround is to check nonNull(request.bodyAsBytes()) before invoking request.body()