Skip to content

Commit 5d96060

Browse files
committed
Add input stream skipping for oversized payloads to prevent TCP RST.
1 parent 1c305ff commit 5d96060

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

rest/.jvm/src/main/scala/io/udash/rest/RestServlet.scala

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package io.udash
22
package rest
33

4-
import com.avsystem.commons._
4+
import com.avsystem.commons.*
55
import com.avsystem.commons.annotation.explicitGenerics
66
import com.typesafe.scalalogging.LazyLogging
7-
import io.udash.rest.RestServlet._
8-
import io.udash.rest.raw._
7+
import io.udash.rest.RestServlet.*
8+
import io.udash.rest.raw.*
99
import io.udash.utils.URLEncoder
1010
import monix.eval.Task
1111
import monix.execution.Scheduler
@@ -15,7 +15,7 @@ import java.util.concurrent.atomic.AtomicBoolean
1515
import javax.servlet.http.{HttpServlet, HttpServletRequest, HttpServletResponse}
1616
import javax.servlet.{AsyncEvent, AsyncListener}
1717
import scala.annotation.tailrec
18-
import scala.concurrent.duration._
18+
import scala.concurrent.duration.*
1919

2020
object RestServlet {
2121
final val DefaultHandleTimeout = 30.seconds
@@ -49,7 +49,7 @@ class RestServlet(
4949
scheduler: Scheduler
5050
) extends HttpServlet with LazyLogging {
5151

52-
import RestServlet._
52+
import RestServlet.*
5353

5454
override def service(request: HttpServletRequest, response: HttpServletResponse): Unit = {
5555
val asyncContext = request.startAsync()
@@ -117,6 +117,11 @@ class RestServlet(
117117
private def readBody(request: HttpServletRequest): HttpBody = {
118118
val contentLength = request.getContentLengthLong.opt.filter(_ != -1)
119119
contentLength.filter(_ > maxPayloadSize).foreach { length =>
120+
// When we're responding immediately, with some headers and an empty body, and we're dropping the request body.
121+
// Jetty sees that you won't stream the body, and marks the "read" end of the connection is needing to close.
122+
// Once the response is written, Jetty closes the connection. Since there is data that hasn't been read in the kernel buffer,
123+
// that will trigger sending a TCP RST.
124+
request.getInputStream.skipNBytes(length)
120125
throw HttpErrorException.plain(413, s"Payload is larger than maximum $maxPayloadSize bytes ($length)")
121126
}
122127

0 commit comments

Comments
 (0)