=htc #20789 fix double push of requestPrepOut in HTTP blueprint (#20841)

* =htc #20789 fix double push of requestPrepOut in HTTP blueprint

* =htc simplify fix, can pull eagerly but under this condition

* =htc make early response a single line
This commit is contained in:
Konrad Malawski 2016-06-30 00:11:44 +02:00 committed by GitHub
parent 421eb3d021
commit d4d9c1943e
2 changed files with 10 additions and 11 deletions

View file

@ -392,7 +392,8 @@ private[http] object HttpServerBluePrint {
case x: EntityStreamError if messageEndPending && openRequests.isEmpty case x: EntityStreamError if messageEndPending && openRequests.isEmpty
// client terminated the connection after receiving an early response to 100-continue // client terminated the connection after receiving an early response to 100-continue
completeStage() completeStage()
case x push(requestPrepOut, x) case x
push(requestPrepOut, x)
} }
override def onUpstreamFinish() = override def onUpstreamFinish() =
if (openRequests.isEmpty) completeStage() if (openRequests.isEmpty) completeStage()
@ -414,19 +415,17 @@ private[http] object HttpServerBluePrint {
val isEarlyResponse = messageEndPending && openRequests.isEmpty val isEarlyResponse = messageEndPending && openRequests.isEmpty
if (isEarlyResponse && response.status.isSuccess) if (isEarlyResponse && response.status.isSuccess)
log.warning( log.warning(
"""Sending 2xx response before end of request was received... "Sending an 2xx 'early' response before end of request was received... " +
|Note that the connection will be closed after this response. Also, many clients will not read early responses! "Note that the connection will be closed after this response. Also, many clients will not read early responses! " +
|Consider waiting for the request end before dispatching this response!""".stripMargin) "Consider only issuing this response after the request data has been completely read!")
val close = requestStart.closeRequested || val close = requestStart.closeRequested ||
requestStart.expect100Continue && oneHundredContinueResponsePending || (requestStart.expect100Continue && oneHundredContinueResponsePending) ||
isClosed(requestParsingIn) && openRequests.isEmpty || (isClosed(requestParsingIn) && openRequests.isEmpty) ||
isEarlyResponse isEarlyResponse
emit(responseCtxOut, ResponseRenderingContext(response, requestStart.method, requestStart.protocol, close), emit(responseCtxOut, ResponseRenderingContext(response, requestStart.method, requestStart.protocol, close),
pullHttpResponseIn) pullHttpResponseIn)
if (close) complete(responseCtxOut) if (close && requestStart.expect100Continue) pull(requestParsingIn)
// when the client closes the connection, we need to pull onc more time to get the
// request parser to complete
if (close && isEarlyResponse) pull(requestParsingIn)
} }
override def onUpstreamFinish() = override def onUpstreamFinish() =
if (openRequests.isEmpty && isClosed(requestParsingIn)) completeStage() if (openRequests.isEmpty && isClosed(requestParsingIn)) completeStage()

View file

@ -684,7 +684,7 @@ class HttpServerSpec extends AkkaSpec(
// client then closes the connection // client then closes the connection
netIn.sendComplete() netIn.sendComplete()
requests.expectComplete() // this should happen, but never does requests.expectComplete()
netOut.expectComplete() netOut.expectComplete()
}) })