diff --git a/akka-docs-dev/rst/java/code/docs/http/javadsl/server/HttpServerExampleDocTest.java b/akka-docs-dev/rst/java/code/docs/http/javadsl/server/HttpServerExampleDocTest.java index 4229b906ac..e159b630db 100644 --- a/akka-docs-dev/rst/java/code/docs/http/javadsl/server/HttpServerExampleDocTest.java +++ b/akka-docs-dev/rst/java/code/docs/http/javadsl/server/HttpServerExampleDocTest.java @@ -156,7 +156,7 @@ public class HttpServerExampleDocTest { .via(failureDetection) .map(request -> { Source bytes = request.entity().getDataBytes(); - HttpEntityChunked entity = HttpEntities.create(ContentTypes.TEXT_PLAIN_UTF8, bytes); + HttpEntity.Chunked entity = HttpEntities.create(ContentTypes.TEXT_PLAIN_UTF8, bytes); return HttpResponse.create() .withEntity(entity); diff --git a/akka-http-core/src/main/java/akka/http/javadsl/model/ChunkStreamPart.java b/akka-http-core/src/main/java/akka/http/javadsl/model/ChunkStreamPart.java deleted file mode 100644 index 6a2c5c60d8..0000000000 --- a/akka-http-core/src/main/java/akka/http/javadsl/model/ChunkStreamPart.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (C) 2009-2014 Typesafe Inc. - */ - -package akka.http.javadsl.model; - -import akka.http.impl.util.Util; -import akka.http.scaladsl.model.HttpEntity; -import akka.util.ByteString; - -/** - * Represents part of a stream of incoming data for `Transfer-Encoding: chunked` messages. - */ -public abstract class ChunkStreamPart { - /** - * Returns the byte data of this chunk. Will be non-empty for every regular - * chunk. Will be empty for the last chunk. - */ - public abstract ByteString data(); - - /** - * Returns extensions data for this chunk. - */ - public abstract String extension(); - - /** - * Returns if this is the last chunk - */ - public abstract boolean isLastChunk(); - - /** - * If this is the last chunk, this will return an Iterable of the trailer headers. Otherwise, - * it will be empty. - */ - public abstract Iterable getTrailerHeaders(); - - /** - * Creates a chunk from data and extension. - */ - public static ChunkStreamPart create(ByteString data, String extension) { - return new HttpEntity.Chunk(data, extension); - } - - /** - * Creates a chunk from data with an empty extension. - */ - public static ChunkStreamPart create(ByteString data) { - return create(data, ""); - } - - /** - * The default last ChunkStreamPart that has no extension and no trailer headers. - */ - public static final ChunkStreamPart LAST = HttpEntity.LastChunk$.MODULE$; - - /** - * Creates a last chunk with extension and headers. - */ - public static ChunkStreamPart createLast(String extension, Iterable trailerHeaders){ - return new HttpEntity.LastChunk(extension, Util.convertIterable(trailerHeaders)); - } -} diff --git a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntities.java b/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntities.java index 9644b8a4a0..7c7372b7cf 100644 --- a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntities.java +++ b/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntities.java @@ -16,27 +16,27 @@ import akka.stream.javadsl.Source; public final class HttpEntities { private HttpEntities() {} - public static HttpEntityStrict create(String string) { + public static HttpEntity.Strict create(String string) { return HttpEntity$.MODULE$.apply(string); } - public static HttpEntityStrict create(byte[] bytes) { + public static HttpEntity.Strict create(byte[] bytes) { return HttpEntity$.MODULE$.apply(bytes); } - public static HttpEntityStrict create(ByteString bytes) { + public static HttpEntity.Strict create(ByteString bytes) { return HttpEntity$.MODULE$.apply(bytes); } - public static HttpEntityStrict create(ContentType.NonBinary contentType, String string) { + public static HttpEntity.Strict create(ContentType.NonBinary contentType, String string) { return HttpEntity$.MODULE$.apply((akka.http.scaladsl.model.ContentType.NonBinary) contentType, string); } - public static HttpEntityStrict create(ContentType contentType, byte[] bytes) { + public static HttpEntity.Strict create(ContentType contentType, byte[] bytes) { return HttpEntity$.MODULE$.apply((akka.http.scaladsl.model.ContentType) contentType, bytes); } - public static HttpEntityStrict create(ContentType contentType, ByteString bytes) { + public static HttpEntity.Strict create(ContentType contentType, ByteString bytes) { return HttpEntity$.MODULE$.apply((akka.http.scaladsl.model.ContentType) contentType, bytes); } @@ -48,23 +48,23 @@ public final class HttpEntities { return HttpEntity$.MODULE$.apply((akka.http.scaladsl.model.ContentType) contentType, file, chunkSize); } - public static HttpEntityDefault create(ContentType contentType, long contentLength, Source data) { + public static HttpEntity.Default create(ContentType contentType, long contentLength, Source data) { return new akka.http.scaladsl.model.HttpEntity.Default((akka.http.scaladsl.model.ContentType) contentType, contentLength, data.asScala()); } - public static HttpEntityChunked create(ContentType contentType, Source data) { + public static HttpEntity.Chunked create(ContentType contentType, Source data) { return HttpEntity.Chunked$.MODULE$.fromData((akka.http.scaladsl.model.ContentType) contentType, data.asScala()); } - public static HttpEntityCloseDelimited createCloseDelimited(ContentType contentType, Source data) { + public static HttpEntity.CloseDelimited createCloseDelimited(ContentType contentType, Source data) { return new akka.http.scaladsl.model.HttpEntity.CloseDelimited((akka.http.scaladsl.model.ContentType) contentType, data.asScala()); } - public static HttpEntityIndefiniteLength createIndefiniteLength(ContentType contentType, Source data) { + public static HttpEntity.IndefiniteLength createIndefiniteLength(ContentType contentType, Source data) { return new akka.http.scaladsl.model.HttpEntity.IndefiniteLength((akka.http.scaladsl.model.ContentType) contentType, data.asScala()); } - public static HttpEntityChunked createChunked(ContentType contentType, Source data) { + public static HttpEntity.Chunked createChunked(ContentType contentType, Source data) { return akka.http.scaladsl.model.HttpEntity.Chunked$.MODULE$.fromData( (akka.http.scaladsl.model.ContentType) contentType, data.asScala()); diff --git a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntity.java b/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntity.java index e208e8de84..a0118953fd 100644 --- a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntity.java +++ b/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntity.java @@ -4,6 +4,7 @@ package akka.http.javadsl.model; +import akka.http.impl.util.Util; import akka.http.scaladsl.model.HttpEntity$; import akka.japi.Option; import akka.stream.Materializer; @@ -19,13 +20,13 @@ import scala.concurrent.Future; * An HttpEntity can be of several kinds: * * - HttpEntity.Empty: the statically known empty entity - * - HttpEntityStrict: an entity containing already evaluated ByteString data - * - HttpEntityDefault: the default entity which has a known length and which contains + * - HttpEntity.Strict: an entity containing already evaluated ByteString data + * - HttpEntity.Default: the default entity which has a known length and which contains * a stream of ByteStrings. - * - HttpEntityChunked: represents an entity that is delivered using `Transfer-Encoding: chunked` - * - HttpEntityCloseDelimited: an entity which doesn't have a fixed length but which is delimited by + * - HttpEntity.Chunked: represents an entity that is delivered using `Transfer-Encoding: chunked` + * - HttpEntity.CloseDelimited: an entity which doesn't have a fixed length but which is delimited by * closing the connection. - * - HttpEntityIndefiniteLength: an entity which doesn't have a fixed length which can be used to construct BodyParts + * - HttpEntity.IndefiniteLength: an entity which doesn't have a fixed length which can be used to construct BodyParts * with indefinite length * * Marker-interfaces denote which subclasses can be used in which context: @@ -40,12 +41,12 @@ public interface HttpEntity { /** * Returns the content-type of this entity */ - ContentType contentType(); + ContentType getContentType(); /** * The empty entity. */ - HttpEntityStrict EMPTY = HttpEntity$.MODULE$.Empty(); + HttpEntity.Strict EMPTY = HttpEntity$.MODULE$.Empty(); /** * Returns if this entity is known to be empty. Open-ended entity types like @@ -92,5 +93,94 @@ public interface HttpEntity { * Use getDataBytes and stream processing instead if the expected data is big or * is likely to take a long time. */ - Future toStrict(long timeoutMillis, Materializer materializer); + Future toStrict(long timeoutMillis, Materializer materializer); + + /** + * The entity type which consists of a predefined fixed ByteString of data. + */ + interface Strict extends UniversalEntity { + ByteString getData(); + } + + /** + * The default entity type which has a predetermined length and a stream of data bytes. + */ + interface Default extends UniversalEntity { + long getContentLength(); + } + + /** + * Represents an entity without a predetermined content-length. Its length is implicitly + * determined by closing the underlying connection. Therefore, this entity type is only + * available for Http responses. + */ + interface CloseDelimited extends ResponseEntity { + } + + /** + * Represents an entity transferred using `Transfer-Encoding: chunked`. It consists of a + * stream of {@link ChunkStreamPart}. + */ + interface Chunked extends RequestEntity, ResponseEntity { + Source getChunks(); + } + + /** + * Represents an entity without a predetermined content-length to use in a BodyParts. + */ + interface IndefiniteLength extends BodyPartEntity { + } + + /** + * A part of a stream of incoming data for `Transfer-Encoding: chunked` messages. + */ + abstract class ChunkStreamPart { + /** + * Returns the byte data of this chunk. Will be non-empty for every regular + * chunk. Will be empty for the last chunk. + */ + public abstract ByteString data(); + + /** + * Returns extensions data for this chunk. + */ + public abstract String extension(); + + /** + * Returns if this is the last chunk + */ + public abstract boolean isLastChunk(); + + /** + * If this is the last chunk, this will return an Iterable of the trailer headers. Otherwise, + * it will be empty. + */ + public abstract Iterable getTrailerHeaders(); + + /** + * Creates a chunk from data and extension. + */ + public static ChunkStreamPart create(ByteString data, String extension) { + return new akka.http.scaladsl.model.HttpEntity.Chunk(data, extension); + } + + /** + * Creates a chunk from data with an empty extension. + */ + public static ChunkStreamPart create(ByteString data) { + return create(data, ""); + } + + /** + * The default last ChunkStreamPart that has no extension and no trailer headers. + */ + public static final ChunkStreamPart LAST = akka.http.scaladsl.model.HttpEntity.LastChunk$.MODULE$; + + /** + * Creates a last chunk with extension and headers. + */ + public static ChunkStreamPart createLast(String extension, Iterable trailerHeaders){ + return new akka.http.scaladsl.model.HttpEntity.LastChunk(extension, Util.convertIterable(trailerHeaders)); + } + } } diff --git a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityChunked.java b/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityChunked.java deleted file mode 100644 index bb35028801..0000000000 --- a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityChunked.java +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright (C) 2009-2014 Typesafe Inc. - */ - -package akka.http.javadsl.model; - -import akka.stream.javadsl.Source; - -/** - * Represents an entity transferred using `Transfer-Encoding: chunked`. It consists of a - * stream of {@link ChunkStreamPart}. - */ -public abstract class HttpEntityChunked implements RequestEntity, ResponseEntity { - public abstract Source getChunks(); -} diff --git a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityCloseDelimited.java b/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityCloseDelimited.java deleted file mode 100644 index 6357ee5470..0000000000 --- a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityCloseDelimited.java +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Copyright (C) 2009-2014 Typesafe Inc. - */ - -package akka.http.javadsl.model; - -/** - * Represents an entity without a predetermined content-length. Its length is implicitly - * determined by closing the underlying connection. Therefore, this entity type is only - * available for Http responses. - */ -public abstract class HttpEntityCloseDelimited implements ResponseEntity {} diff --git a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityDefault.java b/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityDefault.java deleted file mode 100644 index 94f8f981ad..0000000000 --- a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityDefault.java +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Copyright (C) 2009-2014 Typesafe Inc. - */ - -package akka.http.javadsl.model; - -/** - * The default entity type which has a predetermined length and a stream of data bytes. - */ -public abstract class HttpEntityDefault implements BodyPartEntity, RequestEntity, ResponseEntity { - public abstract long contentLength(); -} diff --git a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityIndefiniteLength.java b/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityIndefiniteLength.java deleted file mode 100644 index 5f75d02159..0000000000 --- a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityIndefiniteLength.java +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright (C) 2009-2014 Typesafe Inc. - */ - -package akka.http.javadsl.model; - -/** - * Represents an entity without a predetermined content-length to use in a BodyParts. - */ -public abstract class HttpEntityIndefiniteLength implements BodyPartEntity {} \ No newline at end of file diff --git a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityStrict.java b/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityStrict.java deleted file mode 100644 index 58d67951c1..0000000000 --- a/akka-http-core/src/main/java/akka/http/javadsl/model/HttpEntityStrict.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2009-2014 Typesafe Inc. - */ - -package akka.http.javadsl.model; - -import akka.util.ByteString; - -/** - * The entity type which consists of a predefined fixed ByteString of data. - */ -public abstract class HttpEntityStrict implements BodyPartEntity, RequestEntity, ResponseEntity { - public abstract ByteString data(); -} diff --git a/akka-http-core/src/main/scala/akka/http/scaladsl/model/HttpEntity.scala b/akka-http-core/src/main/scala/akka/http/scaladsl/model/HttpEntity.scala index 6f306d37b6..8fdc77d954 100755 --- a/akka-http-core/src/main/scala/akka/http/scaladsl/model/HttpEntity.scala +++ b/akka-http-core/src/main/scala/akka/http/scaladsl/model/HttpEntity.scala @@ -7,6 +7,7 @@ package akka.http.scaladsl.model import language.implicitConversions import java.io.File import java.lang.{ Iterable ⇒ JIterable, Long ⇒ JLong } +import scala.util.control.NonFatal import scala.concurrent.Future import scala.concurrent.duration._ import scala.collection.immutable @@ -15,14 +16,11 @@ import akka.stream.scaladsl._ import akka.stream.stage._ import akka.stream._ import akka.{ japi, stream } -import akka.http.javadsl.model.HttpEntityStrict import akka.http.scaladsl.model.ContentType.{ NonBinary, Binary } import akka.http.scaladsl.util.FastFuture import akka.http.javadsl.{ model ⇒ jm } import akka.http.impl.util.JavaMapping.Implicits._ -import scala.util.control.NonFatal - /** * Models the entity (aka "body" or "content) of an HTTP message. */ @@ -100,7 +98,11 @@ sealed trait HttpEntity extends jm.HttpEntity { def withSizeLimit(maxBytes: Long): HttpEntity /** Java API */ - def getDataBytes: stream.javadsl.Source[ByteString, AnyRef] = stream.javadsl.Source.fromGraph(dataBytes.asInstanceOf[Source[ByteString, AnyRef]]) + def getContentType: jm.ContentType = contentType + + /** Java API */ + def getDataBytes: stream.javadsl.Source[ByteString, AnyRef] = + stream.javadsl.Source.fromGraph(dataBytes.asInstanceOf[Source[ByteString, AnyRef]]) /** Java API */ def getContentLengthOption: japi.Option[JLong] = @@ -113,7 +115,7 @@ sealed trait HttpEntity extends jm.HttpEntity { def isChunked: Boolean = false /** Java API */ - def toStrict(timeoutMillis: Long, materializer: Materializer): Future[HttpEntityStrict] = + def toStrict(timeoutMillis: Long, materializer: Materializer): Future[jm.HttpEntity.Strict] = toStrict(timeoutMillis.millis)(materializer) } @@ -178,34 +180,41 @@ sealed trait UniversalEntity extends jm.UniversalEntity with MessageEntity with } object HttpEntity { - implicit def apply(string: String): Strict = apply(ContentTypes.`text/plain(UTF-8)`, string) - implicit def apply(bytes: Array[Byte]): Strict = apply(ContentTypes.`application/octet-stream`, bytes) - implicit def apply(data: ByteString): Strict = apply(ContentTypes.`application/octet-stream`, data) - def apply(contentType: ContentType.NonBinary, string: String): Strict = + implicit def apply(string: String): HttpEntity.Strict = apply(ContentTypes.`text/plain(UTF-8)`, string) + implicit def apply(bytes: Array[Byte]): HttpEntity.Strict = apply(ContentTypes.`application/octet-stream`, bytes) + implicit def apply(data: ByteString): HttpEntity.Strict = apply(ContentTypes.`application/octet-stream`, data) + def apply(contentType: ContentType.NonBinary, string: String): HttpEntity.Strict = if (string.isEmpty) empty(contentType) else apply(contentType, ByteString(string.getBytes(contentType.charset.nioCharset))) - def apply(contentType: ContentType, bytes: Array[Byte]): Strict = + def apply(contentType: ContentType, bytes: Array[Byte]): HttpEntity.Strict = if (bytes.length == 0) empty(contentType) else apply(contentType, ByteString(bytes)) - def apply(contentType: ContentType, data: ByteString): Strict = - if (data.isEmpty) empty(contentType) else Strict(contentType, data) + def apply(contentType: ContentType, data: ByteString): HttpEntity.Strict = + if (data.isEmpty) empty(contentType) else HttpEntity.Strict(contentType, data) def apply(contentType: ContentType, contentLength: Long, data: Source[ByteString, Any]): UniversalEntity = - if (contentLength == 0) empty(contentType) else Default(contentType, contentLength, data) - def apply(contentType: ContentType, data: Source[ByteString, Any]): Chunked = - Chunked.fromData(contentType, data) + if (contentLength == 0) empty(contentType) else HttpEntity.Default(contentType, contentLength, data) + def apply(contentType: ContentType, data: Source[ByteString, Any]): HttpEntity.Chunked = + HttpEntity.Chunked.fromData(contentType, data) +/** + * Returns either the empty entity, if the given file is empty, or a [[Default]] entity + * consisting of a stream of [[ByteString]] instances each containing `chunkSize` bytes + * (except for the final ByteString, which simply contains the remaining bytes). + * + * If the given `chunkSize` is -1 the default chunk size is used. + */ def apply(contentType: ContentType, file: File, chunkSize: Int = -1): UniversalEntity = { val fileLength = file.length if (fileLength > 0) - Default(contentType, fileLength, + HttpEntity.Default(contentType, fileLength, if (chunkSize > 0) FileIO.fromFile(file, chunkSize) else FileIO.fromFile(file)) else empty(contentType) } - val Empty: Strict = Strict(ContentTypes.NoContentType, data = ByteString.empty) + val Empty: HttpEntity.Strict = HttpEntity.Strict(ContentTypes.NoContentType, data = ByteString.empty) - def empty(contentType: ContentType): Strict = + def empty(contentType: ContentType): HttpEntity.Strict = if (contentType == Empty.contentType) Empty - else Strict(contentType, data = ByteString.empty) + else HttpEntity.Strict(contentType, data = ByteString.empty) // TODO: re-establish serializability // TODO: equal/hashcode ? @@ -214,7 +223,7 @@ object HttpEntity { * The model for the entity of a "regular" unchunked HTTP message with known, fixed data. */ final case class Strict(contentType: ContentType, data: ByteString) - extends jm.HttpEntityStrict with UniversalEntity { + extends jm.HttpEntity.Strict with UniversalEntity { def contentLength: Long = data.length @@ -226,12 +235,12 @@ object HttpEntity { FastFuture.successful(this) override def transformDataBytes(transformer: Flow[ByteString, ByteString, Any]): MessageEntity = - Chunked.fromData(contentType, Source.single(data).via(transformer)) + HttpEntity.Chunked.fromData(contentType, Source.single(data).via(transformer)) override def transformDataBytes(newContentLength: Long, transformer: Flow[ByteString, ByteString, Any]): UniversalEntity = - Default(contentType, newContentLength, Source.single(data) via transformer) + HttpEntity.Default(contentType, newContentLength, Source.single(data) via transformer) - def withContentType(contentType: ContentType): Strict = + def withContentType(contentType: ContentType): HttpEntity.Strict = if (contentType == this.contentType) this else copy(contentType = contentType) /** @@ -239,7 +248,7 @@ object HttpEntity { */ def withSizeLimit(maxBytes: Long): UniversalEntity = if (data.length <= maxBytes) this - else Default(contentType, data.length, limitableByteSource(Source.single(data))) withSizeLimit maxBytes + else HttpEntity.Default(contentType, data.length, limitableByteSource(Source.single(data))) withSizeLimit maxBytes override def productPrefix = "HttpEntity.Strict" @@ -263,6 +272,9 @@ object HttpEntity { s"$productPrefix($contentType,$dataAsString)" } + + /** Java API */ + override def getData = data } /** @@ -271,29 +283,32 @@ object HttpEntity { final case class Default(contentType: ContentType, contentLength: Long, data: Source[ByteString, Any]) - extends jm.HttpEntityDefault with UniversalEntity { + extends jm.HttpEntity.Default with UniversalEntity { require(contentLength > 0, "contentLength must be positive (use `HttpEntity.empty(contentType)` for empty entities)") def isKnownEmpty = false override def isDefault: Boolean = true def dataBytes: Source[ByteString, Any] = data - override def transformDataBytes(transformer: Flow[ByteString, ByteString, Any]): Chunked = - Chunked.fromData(contentType, data via transformer) + override def transformDataBytes(transformer: Flow[ByteString, ByteString, Any]): HttpEntity.Chunked = + HttpEntity.Chunked.fromData(contentType, data via transformer) override def transformDataBytes(newContentLength: Long, transformer: Flow[ByteString, ByteString, Any]): UniversalEntity = - Default(contentType, newContentLength, data via transformer) + HttpEntity.Default(contentType, newContentLength, data via transformer) - def withContentType(contentType: ContentType): Default = + def withContentType(contentType: ContentType): HttpEntity.Default = if (contentType == this.contentType) this else copy(contentType = contentType) /** * See [[HttpEntity#withSizeLimit]]. */ - def withSizeLimit(maxBytes: Long): Default = + def withSizeLimit(maxBytes: Long): HttpEntity.Default = copy(data = data withAttributes Attributes(SizeLimit(maxBytes, Some(contentLength)))) override def productPrefix = "HttpEntity.Default" + + /** Java API */ + override def getContentLength = contentLength } /** @@ -302,7 +317,7 @@ object HttpEntity { * INTERNAL API */ private[http] sealed trait WithoutKnownLength extends HttpEntity { - type Self <: WithoutKnownLength + type Self <: HttpEntity.WithoutKnownLength def contentType: ContentType def data: Source[ByteString, Any] def contentLengthOption: Option[Long] = None @@ -327,14 +342,14 @@ object HttpEntity { * Note that this type of HttpEntity can only be used for HttpResponses. */ final case class CloseDelimited(contentType: ContentType, data: Source[ByteString, Any]) - extends jm.HttpEntityCloseDelimited with ResponseEntity with WithoutKnownLength { - type Self = CloseDelimited + extends jm.HttpEntity.CloseDelimited with ResponseEntity with HttpEntity.WithoutKnownLength { + type Self = HttpEntity.CloseDelimited override def isCloseDelimited: Boolean = true - def withContentType(contentType: ContentType): CloseDelimited = + def withContentType(contentType: ContentType): HttpEntity.CloseDelimited = if (contentType == this.contentType) this else copy(contentType = contentType) - def withData(data: Source[ByteString, Any]): CloseDelimited = copy(data = data) + def withData(data: Source[ByteString, Any]): HttpEntity.CloseDelimited = copy(data = data) override def productPrefix = "HttpEntity.CloseDelimited" } @@ -344,14 +359,14 @@ object HttpEntity { * Note that this type of HttpEntity can only be used for BodyParts. */ final case class IndefiniteLength(contentType: ContentType, data: Source[ByteString, Any]) - extends jm.HttpEntityIndefiniteLength with BodyPartEntity with WithoutKnownLength { - type Self = IndefiniteLength + extends jm.HttpEntity.IndefiniteLength with BodyPartEntity with HttpEntity.WithoutKnownLength { + type Self = HttpEntity.IndefiniteLength override def isIndefiniteLength: Boolean = true - def withContentType(contentType: ContentType): IndefiniteLength = + def withContentType(contentType: ContentType): HttpEntity.IndefiniteLength = if (contentType == this.contentType) this else copy(contentType = contentType) - def withData(data: Source[ByteString, Any]): IndefiniteLength = copy(data = data) + def withData(data: Source[ByteString, Any]): HttpEntity.IndefiniteLength = copy(data = data) override def productPrefix = "HttpEntity.IndefiniteLength" } @@ -360,7 +375,7 @@ object HttpEntity { * The model for the entity of a chunked HTTP message (with `Transfer-Encoding: chunked`). */ final case class Chunked(contentType: ContentType, chunks: Source[ChunkStreamPart, Any]) - extends jm.HttpEntityChunked with MessageEntity { + extends jm.HttpEntity.Chunked with MessageEntity { def isKnownEmpty = chunks eq Source.empty def contentLengthOption: Option[Long] = None @@ -369,10 +384,10 @@ object HttpEntity { def dataBytes: Source[ByteString, Any] = chunks.map(_.data).filter(_.nonEmpty) - def withSizeLimit(maxBytes: Long): Chunked = + def withSizeLimit(maxBytes: Long): HttpEntity.Chunked = copy(chunks = chunks withAttributes Attributes(SizeLimit(maxBytes))) - override def transformDataBytes(transformer: Flow[ByteString, ByteString, Any]): Chunked = { + override def transformDataBytes(transformer: Flow[ByteString, ByteString, Any]): HttpEntity.Chunked = { val newData = chunks.map { case Chunk(data, "") ⇒ data @@ -381,24 +396,25 @@ object HttpEntity { throw new IllegalArgumentException("Chunked.transformDataBytes not allowed for chunks with metadata") } via transformer - Chunked.fromData(contentType, newData) + HttpEntity.Chunked.fromData(contentType, newData) } - def withContentType(contentType: ContentType): Chunked = + def withContentType(contentType: ContentType): HttpEntity.Chunked = if (contentType == this.contentType) this else copy(contentType = contentType) override def productPrefix = "HttpEntity.Chunked" /** Java API */ - def getChunks: stream.javadsl.Source[jm.ChunkStreamPart, Any] = stream.javadsl.Source.fromGraph(chunks) + def getChunks: stream.javadsl.Source[jm.HttpEntity.ChunkStreamPart, AnyRef] = + stream.javadsl.Source.fromGraph(chunks.asInstanceOf[Source[jm.HttpEntity.ChunkStreamPart, AnyRef]]) } object Chunked { /** * Returns a ``Chunked`` entity where one Chunk is produced for every non-empty ByteString produced by the given * ``Source``. */ - def fromData(contentType: ContentType, chunks: Source[ByteString, Any]): Chunked = - Chunked(contentType, chunks.collect[ChunkStreamPart] { + def fromData(contentType: ContentType, chunks: Source[ByteString, Any]): HttpEntity.Chunked = + HttpEntity.Chunked(contentType, chunks.collect[ChunkStreamPart] { case b: ByteString if b.nonEmpty ⇒ Chunk(b) }) } @@ -407,7 +423,7 @@ object HttpEntity { * An element of the HttpEntity data stream. * Can be either a `Chunk` or a `LastChunk`. */ - sealed abstract class ChunkStreamPart extends jm.ChunkStreamPart { + sealed abstract class ChunkStreamPart extends jm.HttpEntity.ChunkStreamPart { def data: ByteString def extension: String def isLastChunk: Boolean @@ -421,7 +437,7 @@ object HttpEntity { /** * An intermediate entity chunk guaranteed to carry non-empty data. */ - final case class Chunk(data: ByteString, extension: String = "") extends ChunkStreamPart { + final case class Chunk(data: ByteString, extension: String = "") extends HttpEntity.ChunkStreamPart { require(data.nonEmpty, "An HttpEntity.Chunk must have non-empty data") def isLastChunk = false @@ -438,7 +454,7 @@ object HttpEntity { * If you don't need extensions or trailer headers you can save an allocation * by directly using the `LastChunk` companion object. */ - case class LastChunk(extension: String = "", trailer: immutable.Seq[HttpHeader] = Nil) extends ChunkStreamPart { + case class LastChunk(extension: String = "", trailer: immutable.Seq[HttpHeader] = Nil) extends HttpEntity.ChunkStreamPart { def data = ByteString.empty def isLastChunk = true diff --git a/akka-http-testkit/src/main/scala/akka/http/javadsl/testkit/TestResponse.scala b/akka-http-testkit/src/main/scala/akka/http/javadsl/testkit/TestResponse.scala index 20614bc85d..20e35279e3 100644 --- a/akka-http-testkit/src/main/scala/akka/http/javadsl/testkit/TestResponse.scala +++ b/akka-http-testkit/src/main/scala/akka/http/javadsl/testkit/TestResponse.scala @@ -27,7 +27,7 @@ abstract class TestResponse(_response: HttpResponse, awaitAtMost: FiniteDuration /** * Returns the strictified entity of the response. It will be strictified on first access. */ - lazy val entity: HttpEntityStrict = _response.entity.toStrict(awaitAtMost).awaitResult(awaitAtMost) + lazy val entity: HttpEntity.Strict = _response.entity.toStrict(awaitAtMost).awaitResult(awaitAtMost) /** * Returns a copy of the underlying response with the strictified entity. @@ -47,7 +47,7 @@ abstract class TestResponse(_response: HttpResponse, awaitAtMost: FiniteDuration /** * Returns the bytes of the response entity */ - def entityBytes: ByteString = entity.data() + def entityBytes: ByteString = entity.getData /** * Returns the entity of the response unmarshalled with the given ``Unmarshaller``. @@ -60,7 +60,7 @@ abstract class TestResponse(_response: HttpResponse, awaitAtMost: FiniteDuration /** * Returns the entity of the response interpreted as an UTF-8 encoded string. */ - def entityAsString: String = entity.data().utf8String + def entityAsString: String = entity.getData.utf8String /** * Returns the [[StatusCode]] of the response.