Merge pull request #20343 from TrustNoOne/20342-support-httpentity-withSizeLimit
support HttpEntity.with/withoutSizeLimit in scaladsl HttpEntity
This commit is contained in:
commit
fd89f36940
3 changed files with 75 additions and 1 deletions
|
|
@ -86,6 +86,45 @@ sealed trait HttpEntity extends jm.HttpEntity {
|
|||
*/
|
||||
def withContentType(contentType: ContentType): HttpEntity
|
||||
|
||||
/**
|
||||
* Apply the given size limit to this entity by returning a new entity instance which automatically verifies that the
|
||||
* data stream encapsulated by this instance produces at most `maxBytes` data bytes. In case this verification fails
|
||||
* the respective stream will be terminated with an `EntityStreamException` either directly at materialization
|
||||
* time (if the Content-Length is known) or whenever more data bytes than allowed have been read.
|
||||
*
|
||||
* When called on `Strict` entities the method will return the entity itself if the length is within the bound,
|
||||
* otherwise a `Default` entity with a single element data stream. This allows for potential refinement of the
|
||||
* entity size limit at a later point (before materialization of the data stream).
|
||||
*
|
||||
* By default all message entities produced by the HTTP layer automatically carry the limit that is defined in the
|
||||
* application's `max-content-length` config setting. If the entity is transformed in a way that changes the
|
||||
* Content-Length and then another limit is applied then this new limit will be evaluated against the new
|
||||
* Content-Length. If the entity is transformed in a way that changes the Content-Length and no new limit is applied
|
||||
* then the previous limit will be applied against the previous Content-Length.
|
||||
*
|
||||
* Note that the size limit applied via this method will only have any effect if the `Source` instance contained
|
||||
* in this entity has been appropriately modified via the `HttpEntity.limitable` method. For all entities created
|
||||
* by the HTTP layer itself this is always the case, but if you create entities yourself and would like them to
|
||||
* properly respect limits defined via this method you need to make sure to apply `HttpEntity.limitable` yourself.
|
||||
*/
|
||||
override def withSizeLimit(maxBytes: Long): HttpEntity
|
||||
|
||||
/**
|
||||
* Lift the size limit from this entity by returning a new entity instance which skips the size verification.
|
||||
*
|
||||
* By default all message entities produced by the HTTP layer automatically carry the limit that is defined in the
|
||||
* application's `max-content-length` config setting. It is recommended to always keep an upper limit on accepted
|
||||
* entities to avoid potential attackers flooding you with too large requests/responses, so use this method with caution.
|
||||
*
|
||||
* Note that the size limit applied via this method will only have any effect if the `Source` instance contained
|
||||
* in this entity has been appropriately modified via the `HttpEntity.limitable` method. For all entities created
|
||||
* by the HTTP layer itself this is always the case, but if you create entities yourself and would like them to
|
||||
* properly respect limits defined via this method you need to make sure to apply `HttpEntity.limitable` yourself.
|
||||
*
|
||||
* See [[withSizeLimit]] for more details.
|
||||
*/
|
||||
override def withoutSizeLimit: HttpEntity
|
||||
|
||||
/** Java API */
|
||||
override def getContentType: jm.ContentType = contentType
|
||||
|
||||
|
|
|
|||
|
|
@ -157,20 +157,50 @@ class HttpEntitySpec extends FreeSpec with MustMatchers with BeforeAndAfterAll {
|
|||
withReturnType[UniversalEntity](Strict(tpe, abc).withoutSizeLimit)
|
||||
withReturnType[RequestEntity](Strict(tpe, abc).asInstanceOf[RequestEntity].withoutSizeLimit)
|
||||
withReturnType[ResponseEntity](Strict(tpe, abc).asInstanceOf[ResponseEntity].withoutSizeLimit)
|
||||
withReturnType[HttpEntity](Strict(tpe, abc).asInstanceOf[HttpEntity].withoutSizeLimit)
|
||||
}
|
||||
"Default" in {
|
||||
withReturnType[Default](Default(tpe, 11, source(abc, de, fgh, ijk)).withoutSizeLimit)
|
||||
withReturnType[RequestEntity](Default(tpe, 11, source(abc, de, fgh, ijk)).asInstanceOf[RequestEntity].withoutSizeLimit)
|
||||
withReturnType[ResponseEntity](Default(tpe, 11, source(abc, de, fgh, ijk)).asInstanceOf[ResponseEntity].withoutSizeLimit)
|
||||
withReturnType[HttpEntity](Default(tpe, 11, source(abc, de, fgh, ijk)).asInstanceOf[HttpEntity].withoutSizeLimit)
|
||||
}
|
||||
"CloseDelimited" in {
|
||||
withReturnType[CloseDelimited](CloseDelimited(tpe, source(abc, de, fgh, ijk)).withoutSizeLimit)
|
||||
withReturnType[ResponseEntity](CloseDelimited(tpe, source(abc, de, fgh, ijk)).asInstanceOf[ResponseEntity].withoutSizeLimit)
|
||||
withReturnType[HttpEntity](CloseDelimited(tpe, source(abc, de, fgh, ijk)).asInstanceOf[HttpEntity].withoutSizeLimit)
|
||||
}
|
||||
"Chunked" in {
|
||||
withReturnType[Chunked](Chunked(tpe, source(Chunk(abc), Chunk(fgh), Chunk(ijk), LastChunk)).withoutSizeLimit)
|
||||
withReturnType[RequestEntity](Chunked(tpe, source(Chunk(abc), Chunk(fgh), Chunk(ijk), LastChunk)).asInstanceOf[RequestEntity].withoutSizeLimit)
|
||||
withReturnType[ResponseEntity](Chunked(tpe, source(Chunk(abc), Chunk(fgh), Chunk(ijk), LastChunk)).asInstanceOf[ResponseEntity].withoutSizeLimit)
|
||||
withReturnType[HttpEntity](Chunked(tpe, source(Chunk(abc), Chunk(fgh), Chunk(ijk), LastChunk)).asInstanceOf[HttpEntity].withoutSizeLimit)
|
||||
}
|
||||
}
|
||||
"support withSizeLimit" - {
|
||||
"Strict" in {
|
||||
HttpEntity.Empty.withSizeLimit(123L)
|
||||
withReturnType[UniversalEntity](Strict(tpe, abc).withSizeLimit(123L))
|
||||
withReturnType[RequestEntity](Strict(tpe, abc).asInstanceOf[RequestEntity].withSizeLimit(123L))
|
||||
withReturnType[ResponseEntity](Strict(tpe, abc).asInstanceOf[ResponseEntity].withSizeLimit(123L))
|
||||
withReturnType[HttpEntity](Strict(tpe, abc).asInstanceOf[HttpEntity].withSizeLimit(123L))
|
||||
}
|
||||
"Default" in {
|
||||
withReturnType[Default](Default(tpe, 11, source(abc, de, fgh, ijk)).withoutSizeLimit)
|
||||
withReturnType[RequestEntity](Default(tpe, 11, source(abc, de, fgh, ijk)).asInstanceOf[RequestEntity].withSizeLimit(123L))
|
||||
withReturnType[ResponseEntity](Default(tpe, 11, source(abc, de, fgh, ijk)).asInstanceOf[ResponseEntity].withSizeLimit(123L))
|
||||
withReturnType[HttpEntity](Default(tpe, 11, source(abc, de, fgh, ijk)).asInstanceOf[HttpEntity].withSizeLimit(123L))
|
||||
}
|
||||
"CloseDelimited" in {
|
||||
withReturnType[CloseDelimited](CloseDelimited(tpe, source(abc, de, fgh, ijk)).withSizeLimit(123L))
|
||||
withReturnType[ResponseEntity](CloseDelimited(tpe, source(abc, de, fgh, ijk)).asInstanceOf[ResponseEntity].withSizeLimit(123L))
|
||||
withReturnType[HttpEntity](CloseDelimited(tpe, source(abc, de, fgh, ijk)).asInstanceOf[HttpEntity].withSizeLimit(123L))
|
||||
}
|
||||
"Chunked" in {
|
||||
withReturnType[Chunked](Chunked(tpe, source(Chunk(abc), Chunk(fgh), Chunk(ijk), LastChunk)).withSizeLimit(123L))
|
||||
withReturnType[RequestEntity](Chunked(tpe, source(Chunk(abc), Chunk(fgh), Chunk(ijk), LastChunk)).asInstanceOf[RequestEntity].withSizeLimit(123L))
|
||||
withReturnType[ResponseEntity](Chunked(tpe, source(Chunk(abc), Chunk(fgh), Chunk(ijk), LastChunk)).asInstanceOf[ResponseEntity].withSizeLimit(123L))
|
||||
withReturnType[HttpEntity](Chunked(tpe, source(Chunk(abc), Chunk(fgh), Chunk(ijk), LastChunk)).asInstanceOf[HttpEntity].withSizeLimit(123L))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -742,7 +742,12 @@ object MiMa extends AutoPlugin {
|
|||
|
||||
// #20123
|
||||
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.stream.scaladsl.FlowOps.recoverWithRetries")
|
||||
)
|
||||
),
|
||||
"2.4.4" -> Seq(
|
||||
// #20342 HttpEntity scaladsl overrides
|
||||
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.http.scaladsl.model.HttpEntity.withoutSizeLimit"),
|
||||
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.http.scaladsl.model.HttpEntity.withSizeLimit")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue