Skip to content

Commit c0ffee4

Browse files
committed
!hco #15915 introduce more shades of HttpEntities
The introduction of BodyParts again showed that not all entity types are useful for every kind of context. There are now these contexts where HttpEntities are used: - requests - responses - body parts And several kinds of entities: - Strict - Default - Chunked - CloseDelimited - IndefiniteLength To increase type safety of the API marker-interfaces are introduced defining which kinds of entities can be used in which contexts: - RequestEntity: Strict, Default, Chunked - ResponseEntity: Strict, Default, Chunked, CloseDelimited - BodyPartEntity: Strict, Default, IndefiniteLength Also, to be able still to provide abstractions over some kinds of entities additional auxiliary interfaces were necessary: - MessageEntity = RequestEntity >: ResponseEntity: Strict, Default, Chunked (type alias for RequestEntity) - UniversalEntity = RequestEntity with ResponseEntity with BodyPartEntity = Strict, Default
1 parent 6f68f87 commit c0ffee4

40 files changed

Lines changed: 289 additions & 159 deletions
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
3+
*/
4+
5+
package akka.http.model.japi;
6+
7+
/** Marker-interface for entity types that can be used in a body part */
8+
public interface BodyPartEntity extends HttpEntity {}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
3+
*/
4+
5+
package akka.http.model.japi;
6+
7+
import java.io.File;
8+
9+
import akka.util.ByteString;
10+
import org.reactivestreams.Publisher;
11+
12+
import akka.stream.FlowMaterializer;
13+
import akka.http.model.HttpEntity$;
14+
15+
/** Constructors for HttpEntity instances */
16+
public final class HttpEntities {
17+
private HttpEntities() {}
18+
19+
public static HttpEntityStrict create(String string) {
20+
return HttpEntity$.MODULE$.apply(string);
21+
}
22+
23+
public static HttpEntityStrict create(byte[] bytes) {
24+
return HttpEntity$.MODULE$.apply(bytes);
25+
}
26+
27+
public static HttpEntityStrict create(ByteString bytes) {
28+
return HttpEntity$.MODULE$.apply(bytes);
29+
}
30+
31+
public static HttpEntityStrict create(ContentType contentType, String string) {
32+
return HttpEntity$.MODULE$.apply((akka.http.model.ContentType) contentType, string);
33+
}
34+
35+
public static HttpEntityStrict create(ContentType contentType, byte[] bytes) {
36+
return HttpEntity$.MODULE$.apply((akka.http.model.ContentType) contentType, bytes);
37+
}
38+
39+
public static HttpEntityStrict create(ContentType contentType, ByteString bytes) {
40+
return HttpEntity$.MODULE$.apply((akka.http.model.ContentType) contentType, bytes);
41+
}
42+
43+
public static UniversalEntity create(ContentType contentType, File file) {
44+
return HttpEntity$.MODULE$.apply((akka.http.model.ContentType) contentType, file);
45+
}
46+
47+
public static HttpEntityDefault create(ContentType contentType, long contentLength, Publisher<ByteString> data) {
48+
return new akka.http.model.HttpEntity.Default((akka.http.model.ContentType) contentType, contentLength, data);
49+
}
50+
51+
public static HttpEntityCloseDelimited createCloseDelimited(ContentType contentType, Publisher<ByteString> data) {
52+
return new akka.http.model.HttpEntity.CloseDelimited((akka.http.model.ContentType) contentType, data);
53+
}
54+
55+
public static HttpEntityIndefiniteLength createIndefiniteLength(ContentType contentType, Publisher<ByteString> data) {
56+
return new akka.http.model.HttpEntity.IndefiniteLength((akka.http.model.ContentType) contentType, data);
57+
}
58+
59+
public static HttpEntityChunked createChunked(ContentType contentType, Publisher<ChunkStreamPart> chunks) {
60+
return new akka.http.model.HttpEntity.Chunked(
61+
(akka.http.model.ContentType) contentType,
62+
Util.<ChunkStreamPart, akka.http.model.HttpEntity.ChunkStreamPart>upcastPublisher(chunks));
63+
}
64+
65+
public static HttpEntityChunked createChunked(ContentType contentType, Publisher<ByteString> data, FlowMaterializer materializer) {
66+
return akka.http.model.HttpEntity.Chunked$.MODULE$.fromData(
67+
(akka.http.model.ContentType) contentType,
68+
data, materializer);
69+
}
70+
}

akka-http-core/src/main/java/akka/http/model/japi/HttpEntity.java

Lines changed: 17 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
import akka.util.ByteString;
1010
import org.reactivestreams.Publisher;
1111

12-
import java.io.File;
13-
1412
/**
1513
* Represents the entity of an Http message. An entity consists of the content-type of the data
1614
* and the actual data itself. Some subtypes of HttpEntity also define the content-length of the
@@ -19,16 +17,24 @@
1917
* An HttpEntity can be of several kinds:
2018
*
2119
* - HttpEntity.Empty: the statically known empty entity
20+
* - HttpEntityStrict: an entity containing already evaluated ByteString data
2221
* - HttpEntityDefault: the default entity which has a known length and which contains
2322
* a stream of ByteStrings.
2423
* - HttpEntityChunked: represents an entity that is delivered using `Transfer-Encoding: chunked`
25-
* - HttpEntityCloseDelimited: the entity which doesn't have a fixed length but which is delimited by
24+
* - HttpEntityCloseDelimited: an entity which doesn't have a fixed length but which is delimited by
2625
* closing the connection.
26+
* - HttpEntityIndefiniteLength: an entity which doesn't have a fixed length which can be used to construct BodyParts
27+
* with indefinite length
28+
*
29+
* Marker-interfaces denote which subclasses can be used in which context:
30+
* - RequestEntity: an entity type that can be used in an HttpRequest
31+
* - ResponseEntity: an entity type that can be used in an HttpResponse
32+
* - BodyPartEntity: an entity type that can be used in a BodyPart
33+
* - UniversalEntity: an entity type that can be used in every context
2734
*
28-
* All entity subtypes but HttpEntityCloseDelimited are subtypes of {@link HttpEntityRegular} which
29-
* means they can be used in Http request that disallow close-delimited transfer of the entity.
35+
* Use the static constructors in HttpEntities to construct instances.
3036
*/
31-
public abstract class HttpEntity {
37+
public interface HttpEntity {
3238
/**
3339
* Returns the content-type of this entity
3440
*/
@@ -45,11 +51,6 @@ public abstract class HttpEntity {
4551
*/
4652
public abstract boolean isKnownEmpty();
4753

48-
/**
49-
* Returns if this entity is a subtype of HttpEntityRegular.
50-
*/
51-
public abstract boolean isRegular();
52-
5354
/**
5455
* Returns if this entity is a subtype of HttpEntityChunked.
5556
*/
@@ -65,46 +66,13 @@ public abstract class HttpEntity {
6566
*/
6667
public abstract boolean isCloseDelimited();
6768

69+
/**
70+
* Returns if this entity is a subtype of HttpEntityIndefiniteLength.
71+
*/
72+
public abstract boolean isIndefiniteLength();
73+
6874
/**
6975
* Returns a stream of data bytes this entity consists of.
7076
*/
7177
public abstract Publisher<ByteString> getDataBytes(FlowMaterializer materializer);
72-
73-
public static HttpEntityStrict create(String string) {
74-
return HttpEntity$.MODULE$.apply(string);
75-
}
76-
public static HttpEntityStrict create(byte[] bytes) {
77-
return HttpEntity$.MODULE$.apply(bytes);
78-
}
79-
public static HttpEntityStrict create(ByteString bytes) {
80-
return HttpEntity$.MODULE$.apply(bytes);
81-
}
82-
public static HttpEntityStrict create(ContentType contentType, String string) {
83-
return HttpEntity$.MODULE$.apply((akka.http.model.ContentType) contentType, string);
84-
}
85-
public static HttpEntityStrict create(ContentType contentType, byte[] bytes) {
86-
return HttpEntity$.MODULE$.apply((akka.http.model.ContentType) contentType, bytes);
87-
}
88-
public static HttpEntityStrict create(ContentType contentType, ByteString bytes) {
89-
return HttpEntity$.MODULE$.apply((akka.http.model.ContentType) contentType, bytes);
90-
}
91-
public static HttpEntityRegular create(ContentType contentType, File file) {
92-
return (HttpEntityRegular) HttpEntity$.MODULE$.apply((akka.http.model.ContentType) contentType, file);
93-
}
94-
public static HttpEntityDefault create(ContentType contentType, long contentLength, Publisher<ByteString> data) {
95-
return new akka.http.model.HttpEntity.Default((akka.http.model.ContentType) contentType, contentLength, data);
96-
}
97-
public static HttpEntityCloseDelimited createCloseDelimited(ContentType contentType, Publisher<ByteString> data) {
98-
return new akka.http.model.HttpEntity.CloseDelimited((akka.http.model.ContentType) contentType, data);
99-
}
100-
public static HttpEntityChunked createChunked(ContentType contentType, Publisher<ChunkStreamPart> chunks) {
101-
return new akka.http.model.HttpEntity.Chunked(
102-
(akka.http.model.ContentType) contentType,
103-
Util.<ChunkStreamPart, akka.http.model.HttpEntity.ChunkStreamPart>upcastPublisher(chunks));
104-
}
105-
public static HttpEntityChunked createChunked(ContentType contentType, Publisher<ByteString> data, FlowMaterializer materializer) {
106-
return akka.http.model.HttpEntity.Chunked$.MODULE$.fromData(
107-
(akka.http.model.ContentType) contentType,
108-
data, materializer);
109-
}
11078
}

akka-http-core/src/main/java/akka/http/model/japi/HttpEntityChunked.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
* Represents an entity transferred using `Transfer-Encoding: chunked`. It consists of a
1111
* stream of {@link ChunkStreamPart}.
1212
*/
13-
public abstract class HttpEntityChunked extends HttpEntityRegular {
13+
public abstract class HttpEntityChunked implements RequestEntity, ResponseEntity {
1414
public abstract Publisher<ChunkStreamPart> getChunks();
1515
}

akka-http-core/src/main/java/akka/http/model/japi/HttpEntityCloseDelimited.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212
* determined by closing the underlying connection. Therefore, this entity type is only
1313
* available for Http responses.
1414
*/
15-
public abstract class HttpEntityCloseDelimited extends HttpEntity {
15+
public abstract class HttpEntityCloseDelimited implements ResponseEntity {
1616
public abstract Publisher<ByteString> data();
1717
}

akka-http-core/src/main/java/akka/http/model/japi/HttpEntityDefault.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
/**
1111
* The default entity type which has a predetermined length and a stream of data bytes.
1212
*/
13-
public abstract class HttpEntityDefault extends HttpEntityRegular {
13+
public abstract class HttpEntityDefault implements BodyPartEntity, RequestEntity, ResponseEntity {
1414
public abstract long contentLength();
1515
public abstract Publisher<ByteString> data();
1616
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
3+
*/
4+
5+
package akka.http.model.japi;
6+
7+
import akka.util.ByteString;
8+
import org.reactivestreams.Publisher;
9+
10+
/**
11+
* Represents an entity without a predetermined content-length to use in a BodyParts.
12+
*/
13+
public abstract class HttpEntityIndefiniteLength implements BodyPartEntity {
14+
public abstract Publisher<ByteString> data();
15+
}

akka-http-core/src/main/java/akka/http/model/japi/HttpEntityRegular.java

Lines changed: 0 additions & 10 deletions
This file was deleted.

akka-http-core/src/main/java/akka/http/model/japi/HttpEntityStrict.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
/**
1010
* The entity type which consists of a predefined fixed ByteString of data.
1111
*/
12-
public abstract class HttpEntityStrict extends HttpEntityRegular {
12+
public abstract class HttpEntityStrict implements BodyPartEntity, RequestEntity, ResponseEntity {
1313
public abstract ByteString data();
1414
}

akka-http-core/src/main/java/akka/http/model/japi/HttpMessage.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public interface HttpMessage {
4848
/**
4949
* The entity of this message.
5050
*/
51-
HttpEntity entity();
51+
ResponseEntity entity();
5252

5353
public static interface MessageTransformations<Self> {
5454
/**
@@ -71,11 +71,6 @@ public static interface MessageTransformations<Self> {
7171
*/
7272
Self removeHeader(String headerName);
7373

74-
/**
75-
* Returns a copy of this message with a new entity.
76-
*/
77-
Self withEntity(HttpEntity entity);
78-
7974
/**
8075
* Returns a copy of this message with a new entity.
8176
*/
@@ -110,5 +105,10 @@ public static interface MessageTransformations<Self> {
110105
* Returns a copy of Self message with a new entity.
111106
*/
112107
Self withEntity(ContentType type, File file);
108+
109+
/**
110+
* Returns a copy of Self message with a new entity.
111+
*/
112+
Self withEntity(RequestEntity entity);
113113
}
114114
}

0 commit comments

Comments
 (0)