Skip to content

Commit a1bdc3e

Browse files
authored
Merge branch 'main' into scala-3
2 parents f2acbb6 + 1335ca0 commit a1bdc3e

File tree

28 files changed

+125
-93
lines changed

28 files changed

+125
-93
lines changed

LICENSE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Additional Use Grant:
1515
Connecting to a Play Framework websocket and/or Play Framework
1616
request/response bodies for server and play-ws client.
1717

18-
Change Date: TBD ( 3 years after 10.4.0 release )
18+
Change Date: 2025-10-25
1919

2020
Change License: Apache License, Version 2.0
2121

akka-http-core/src/main/java/akka/http/javadsl/model/StatusCodes.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,16 @@ private StatusCodes() {}
5757
public static final StatusCode GONE = akka.http.scaladsl.model.StatusCodes.Gone();
5858
public static final StatusCode LENGTH_REQUIRED = akka.http.scaladsl.model.StatusCodes.LengthRequired();
5959
public static final StatusCode PRECONDITION_FAILED = akka.http.scaladsl.model.StatusCodes.PreconditionFailed();
60+
public static final StatusCode CONTENT_TOO_LARGE = akka.http.scaladsl.model.StatusCodes.ContentTooLarge();
61+
62+
/**
63+
* @deprecated deprecated in favor of CONTENT_TOO_LARGE
64+
*/
65+
@Deprecated
6066
public static final StatusCode PAYLOAD_TOO_LARGE = akka.http.scaladsl.model.StatusCodes.PayloadTooLarge();
6167

6268
/**
63-
* @deprecated deprecated in favor of PAYLOAD_TOO_LARGE
69+
* @deprecated deprecated in favor of CONTENT_TOO_LARGE
6470
*/
6571
@Deprecated
6672
public static final StatusCode REQUEST_ENTITY_TOO_LARGE = akka.http.scaladsl.model.StatusCodes.RequestEntityTooLarge();
@@ -83,6 +89,12 @@ private StatusCodes() {}
8389
public static final StatusCode IM_A_TEAPOT = akka.http.scaladsl.model.StatusCodes.ImATeapot();
8490
public static final StatusCode ENHANCE_YOUR_CALM = akka.http.scaladsl.model.StatusCodes.EnhanceYourCalm();
8591
public static final StatusCode MISDIRECTED_REQUEST = akka.http.scaladsl.model.StatusCodes.MisdirectedRequest();
92+
public static final StatusCode UNPROCESSABLE_CONTENT = akka.http.scaladsl.model.StatusCodes.UnprocessableContent();
93+
94+
/**
95+
* @deprecated deprecated in favor of UNPROCESSABLE_CONTENT
96+
*/
97+
@Deprecated
8698
public static final StatusCode UNPROCESSABLE_ENTITY = akka.http.scaladsl.model.StatusCodes.UnprocessableEntity();
8799
public static final StatusCode LOCKED = akka.http.scaladsl.model.StatusCodes.Locked();
88100
public static final StatusCode FAILED_DEPENDENCY = akka.http.scaladsl.model.StatusCodes.FailedDependency();

akka-http-core/src/main/scala/akka/http/impl/engine/http2/ProtocolSwitch.scala

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,7 @@ private[http] object ProtocolSwitch {
6060
}
6161
})
6262

63-
private val ignorePull = new OutHandler {
64-
def onPull(): Unit = ()
65-
}
66-
67-
setHandler(netOut, ignorePull)
63+
setHandler(netOut, GraphStageLogic.EagerTerminateOutput)
6864

6965
def install(serverImplementation: HttpImplementation, firstElement: SslTlsInbound): Unit = {
7066
val networkSide = Flow.fromSinkAndSource(serverDataIn.sink, serverDataOut.source)

akka-http-core/src/main/scala/akka/http/impl/engine/parsing/HttpRequestParser.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ private[http] final class HttpRequestParser(
209209
setCompletionHandling(HttpMessageParser.CompletionOk)
210210
startNewMessage(input, bodyStart)
211211
} else if (!method.isEntityAccepted) {
212-
failMessageStart(UnprocessableEntity, s"${method.name} requests must not have an entity")
212+
failMessageStart(UnprocessableContent, s"${method.name} requests must not have an entity")
213213
} else if (contentLength <= input.size - bodyStart) {
214214
val cl = contentLength.toInt
215215
emitRequestStart(strictEntity(cth, input, bodyStart, cl))
@@ -221,7 +221,7 @@ private[http] final class HttpRequestParser(
221221
}
222222
} else {
223223
if (!method.isEntityAccepted) {
224-
failMessageStart(UnprocessableEntity, s"${method.name} requests must not have an entity")
224+
failMessageStart(UnprocessableContent, s"${method.name} requests must not have an entity")
225225
} else {
226226
if (clh.isEmpty) {
227227
emitRequestStart(chunkedEntity(cth), headers)

akka-http-core/src/main/scala/akka/http/impl/engine/rendering/HttpResponseRendererFactory.scala

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -51,37 +51,36 @@ private[http] class HttpResponseRendererFactory(
5151
val shape: FlowShape[ResponseRenderingContext, ResponseRenderingOutput] = FlowShape(in, out)
5252

5353
def createLogic(inheritedAttributes: Attributes): GraphStageLogic =
54-
new GraphStageLogic(shape) {
54+
new GraphStageLogic(shape) with InHandler {
5555
var closeMode: CloseMode = DontClose // signals what to do after the current response
5656
def close: Boolean = closeMode != DontClose
5757
def closeIf(cond: Boolean): Unit = if (cond) closeMode = CloseConnection
5858
var transferSink: Option[SubSinkInlet[ByteString]] = None
5959
def transferring: Boolean = transferSink.isDefined
6060

61-
setHandler(in, new InHandler {
62-
override def onPush(): Unit =
63-
render(grab(in)) match {
64-
case Strict(outElement) =>
65-
push(out, outElement)
66-
if (close) completeStage()
67-
case HeadersAndStreamedEntity(headerData, outStream) =>
68-
try transfer(headerData, outStream)
69-
catch {
70-
case NonFatal(e) =>
71-
log.error(e, s"Rendering of response failed because response entity stream materialization failed with '${e.getMessage}'. Sending out 500 response instead.")
72-
push(out, render(ResponseRenderingContext(HttpResponse(500, entity = StatusCodes.InternalServerError.defaultMessage))).asInstanceOf[Strict].bytes)
73-
}
74-
}
61+
override def onPush(): Unit =
62+
render(grab(in)) match {
63+
case Strict(outElement) =>
64+
push(out, outElement)
65+
if (close) completeStage()
66+
case HeadersAndStreamedEntity(headerData, outStream) =>
67+
try transfer(headerData, outStream)
68+
catch {
69+
case NonFatal(e) =>
70+
log.error(e, s"Rendering of response failed because response entity stream materialization failed with '${e.getMessage}'. Sending out 500 response instead.")
71+
push(out, render(ResponseRenderingContext(HttpResponse(500, entity = StatusCodes.InternalServerError.defaultMessage))).asInstanceOf[Strict].bytes)
72+
}
73+
}
7574

76-
override def onUpstreamFinish(): Unit =
77-
if (transferring) closeMode = CloseConnection
78-
else completeStage()
75+
override def onUpstreamFinish(): Unit =
76+
if (transferring) closeMode = CloseConnection
77+
else completeStage()
78+
79+
override def onUpstreamFailure(ex: Throwable): Unit = {
80+
stopTransfer()
81+
failStage(ex)
82+
}
7983

80-
override def onUpstreamFailure(ex: Throwable): Unit = {
81-
stopTransfer()
82-
failStage(ex)
83-
}
84-
})
8584
private val waitForDemandHandler = new OutHandler {
8685
def onPull(): Unit = if (!hasBeenPulled(in)) tryPull(in)
8786
}
@@ -92,6 +91,7 @@ private[http] class HttpResponseRendererFactory(
9291
transferSink = None
9392
}
9493

94+
setHandler(in, this)
9595
setHandler(out, waitForDemandHandler)
9696
def transfer(headerData: ByteString, outStream: Source[ByteString, Any]): Unit = {
9797
val sinkIn = new SubSinkInlet[ByteString]("RenderingSink")

akka-http-core/src/main/scala/akka/http/impl/engine/server/HttpServerBluePrint.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ private[http] object HttpServerBluePrint {
499499
case None => s"Aggregated data length of request entity exceeds the configured limit of $limit bytes"
500500
}
501501
val info = ErrorInfo(summary, "Consider increasing the value of akka.http.server.parsing.max-content-length")
502-
finishWithIllegalRequestError(StatusCodes.PayloadTooLarge, info)
502+
finishWithIllegalRequestError(StatusCodes.ContentTooLarge, info)
503503

504504
case IllegalUriException(errorInfo) =>
505505
finishWithIllegalRequestError(StatusCodes.BadRequest, errorInfo)

akka-http-core/src/main/scala/akka/http/impl/engine/ws/FrameEventRenderer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ private[http] final class FrameEventRenderer extends GraphStage[FlowShape[FrameE
3333

3434
push(out, renderStart(start))
3535

36-
case f: FrameData =>
36+
case _: FrameData =>
3737
fail(out, new IllegalStateException("unexpected FrameData (need FrameStart first)"))
3838
}
3939
}

akka-http-core/src/main/scala/akka/http/impl/engine/ws/WebSocket.scala

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,16 +271,14 @@ private[http] object WebSocket {
271271

272272
val shape = new FlowShape(in, out)
273273

274-
def createLogic(effectiveAttributes: Attributes) = new GraphStageLogic(shape) {
275-
setHandler(out, new OutHandler {
274+
def createLogic(effectiveAttributes: Attributes): GraphStageLogic with InHandler with OutHandler =
275+
new GraphStageLogic(shape) with InHandler with OutHandler {
276276
override def onPull(): Unit = pull(in)
277-
})
278-
setHandler(in, new InHandler {
279277
override def onPush(): Unit = push(out, grab(in))
280278
override def onUpstreamFinish(): Unit = emit(out, UserHandlerCompleted, () => completeStage())
281279
override def onUpstreamFailure(ex: Throwable): Unit = emit(out, UserHandlerErredOut(ex), () => completeStage())
282-
})
283-
}
280+
setHandlers(in, out, this)
281+
}
284282
}
285283

286284
case object Tick

akka-http-core/src/main/scala/akka/http/impl/util/package.scala

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,22 +111,20 @@ package util {
111111

112112
override val shape = FlowShape(byteStringIn, httpEntityOut)
113113

114-
override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = new TimerGraphStageLogic(shape) {
115-
val bytes = ByteString.newBuilder
116-
private var emptyStream = false
114+
override def createLogic(inheritedAttributes: Attributes): GraphStageLogic =
115+
new TimerGraphStageLogic(shape) with InHandler with OutHandler {
116+
val bytes = ByteString.newBuilder
117+
private var emptyStream = false
117118

118-
override def preStart(): Unit = scheduleOnce("ToStrictTimeoutTimer", timeout)
119+
override def preStart(): Unit = scheduleOnce("ToStrictTimeoutTimer", timeout)
119120

120-
setHandler(httpEntityOut, new OutHandler {
121121
override def onPull(): Unit = {
122122
if (emptyStream) {
123123
push(httpEntityOut, HttpEntity.Strict(contentType, ByteString.empty))
124124
completeStage()
125125
} else pull(byteStringIn)
126126
}
127-
})
128127

129-
setHandler(byteStringIn, new InHandler {
130128
override def onPush(): Unit = {
131129
bytes ++= grab(byteStringIn)
132130
maxBytes match {
@@ -136,18 +134,20 @@ package util {
136134
pull(byteStringIn)
137135
}
138136
}
137+
139138
override def onUpstreamFinish(): Unit = {
140139
if (isAvailable(httpEntityOut)) {
141140
push(httpEntityOut, HttpEntity.Strict(contentType, bytes.result()))
142141
completeStage()
143142
} else emptyStream = true
144143
}
145-
})
146144

147-
override def onTimer(key: Any): Unit =
148-
failStage(new java.util.concurrent.TimeoutException(
149-
s"HttpEntity.toStrict timed out after $timeout while still waiting for outstanding data"))
150-
}
145+
setHandlers(byteStringIn, httpEntityOut, this)
146+
147+
override def onTimer(key: Any): Unit =
148+
failStage(new java.util.concurrent.TimeoutException(
149+
s"HttpEntity.toStrict timed out after $timeout while still waiting for outstanding data"))
150+
}
151151

152152
override def toString = "ToStrict"
153153
}

akka-http-core/src/main/scala/akka/http/scaladsl/model/StatusCode.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,11 @@ object StatusCodes extends ObjectRegistry[Int, StatusCode] {
141141
val Gone = reg(c(410)("Gone", "The resource requested is no longer available and will not be available again."))
142142
val LengthRequired = reg(c(411)("Length Required", "The request did not specify the length of its content, which is required by the requested resource."))
143143
val PreconditionFailed = reg(c(412)("Precondition Failed", "The server does not meet one of the preconditions that the requester put on the request."))
144-
val PayloadTooLarge = reg(c(413)("Payload Too Large", "The request payload is larger than the server is willing or able to process."))
145-
@deprecated("deprecated in favor of PayloadTooLarge", "10.1.11")
146-
val RequestEntityTooLarge = PayloadTooLarge
144+
val ContentTooLarge = reg(c(413)("Content Too Large", "The request content is larger than the server is willing or able to process."))
145+
@deprecated("deprecated in favor of ContentTooLarge", "10.4.0")
146+
val PayloadTooLarge = ContentTooLarge
147+
@deprecated("deprecated in favor of ContentTooLarge", "10.4.0")
148+
val RequestEntityTooLarge = ContentTooLarge
147149
val UriTooLong = reg(c(414)("URI Too Long", "The URI provided was too long for the server to process."))
148150
@deprecated("deprecated in favor of UriTooLong", "10.1.11")
149151
val RequestUriTooLong = UriTooLong
@@ -155,7 +157,9 @@ object StatusCodes extends ObjectRegistry[Int, StatusCode] {
155157
val ImATeapot = reg(c(418)("I'm a teapot", "The resulting entity body MAY be short and stout."))
156158
val EnhanceYourCalm = reg(c(420)("Enhance Your Calm", "You are being rate-limited.")) // Twitter only
157159
val MisdirectedRequest = reg(c(421)("Misdirected Request", "The request was directed at a server that is not able to produce a response.")) // HTTP/2 only. https://tools.ietf.org/html/rfc7540#section-9.1.2
158-
val UnprocessableEntity = reg(c(422)("Unprocessable Entity", "The request was well-formed but was unable to be followed due to semantic errors."))
160+
val UnprocessableContent = reg(c(422)("Unprocessable Content", "The request was well-formed but was unable to be followed due to semantic errors."))
161+
@deprecated("deprecated in favor of UnprocessableContent", "10.4.0")
162+
val UnprocessableEntity = UnprocessableContent
159163
val Locked = reg(c(423)("Locked", "The resource that is being accessed is locked."))
160164
val FailedDependency = reg(c(424)("Failed Dependency", "The request failed due to failure of a previous request."))
161165
val TooEarly = reg(c(425)("Too Early", "The server is unwilling to risk processing a request that might be replayed.")) // RFC 8470

0 commit comments

Comments
 (0)