Skip to content

Commit 1135e86

Browse files
committed
Working
1 parent 4a8d8b3 commit 1135e86

File tree

6 files changed

+58
-17
lines changed

6 files changed

+58
-17
lines changed

src/main/java/io/fusionauth/http/HTTPValues.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ public static final class Headers {
216216

217217
public static final String ContentEncoding = "Content-Encoding";
218218

219+
public static final String ContentEncodingLower = "content-encoding";
220+
219221
public static final String ContentLength = "Content-Length";
220222

221223
public static final String ContentLengthLower = "content-length";

src/main/java/io/fusionauth/http/server/HTTPRequest.java

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ public class HTTPRequest implements Buildable<HTTPRequest> {
6868

6969
private final Map<String, Object> attributes = new HashMap<>();
7070

71+
private final List<String> contentEncodings = new LinkedList<>();
72+
7173
private final Map<String, Cookie> cookies = new HashMap<>();
7274

7375
private final List<FileInfo> files = new LinkedList<>();
@@ -296,6 +298,15 @@ public void setCharacterEncoding(Charset encoding) {
296298
this.encoding = encoding;
297299
}
298300

301+
public List<String> getContentEncodings() {
302+
return contentEncodings;
303+
}
304+
305+
public void setContentEncodings(List<String> encodings) {
306+
this.contentEncodings.clear();
307+
this.contentEncodings.addAll(encodings);
308+
}
309+
299310
public Long getContentLength() {
300311
return contentLength;
301312
}
@@ -715,7 +726,7 @@ public void setURLParameters(String name, Collection<String> values) {
715726

716727
private void decodeHeader(String name, String value) {
717728
switch (name) {
718-
case Headers.AcceptEncodingLower:
729+
case Headers.AcceptEncodingLower, Headers.ContentEncodingLower:
719730
SortedSet<WeightedString> weightedStrings = new TreeSet<>();
720731
String[] parts = value.split(",");
721732
int index = 0;
@@ -738,11 +749,15 @@ private void decodeHeader(String name, String value) {
738749
}
739750

740751
// Transfer the Strings in weighted-position order
741-
setAcceptEncodings(
742-
weightedStrings.stream()
743-
.map(WeightedString::value)
744-
.toList()
745-
);
752+
var result = weightedStrings.stream()
753+
.map(WeightedString::value)
754+
.toList();
755+
756+
if (name.equals(Headers.AcceptEncodingLower)) {
757+
setAcceptEncodings(result);
758+
} else {
759+
setContentEncodings(result);
760+
}
746761
break;
747762
case Headers.AcceptLanguageLower:
748763
try {
@@ -801,15 +816,12 @@ private void decodeHeader(String name, String value) {
801816
}
802817
}
803818
} else {
819+
this.host = value;
804820
if ("http".equalsIgnoreCase(scheme)) {
805821
this.port = 80;
806-
}
807-
else if ("https".equalsIgnoreCase(scheme)) {
822+
} else if ("https".equalsIgnoreCase(scheme)) {
808823
this.port = 443;
809-
} else {
810-
// fallback, intentionally do nothing
811824
}
812-
this.host = value;
813825
}
814826
break;
815827
}

src/main/java/io/fusionauth/http/server/internal/HTTPWorker.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ public void run() {
144144
instrumenter.acceptedRequest();
145145
}
146146

147+
// TODO : Content-Encoding, we are currently keeping the PushbackInputStream for the entire keep-alive session.
148+
// Ideally we'd set the InputStream for gzip, deflate, etc lower.
149+
// Also... with Pushback bytes... the bytes may be compressed for the next request. So we'll need to be able to
150+
// read handle this. So perhaps this should all be handled at a high level?
151+
147152
httpInputStream = new HTTPInputStream(configuration, request, inputStream);
148153
request.setInputStream(httpInputStream);
149154

src/main/java/io/fusionauth/http/server/io/HTTPInputStream.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717

1818
import java.io.IOException;
1919
import java.io.InputStream;
20+
import java.util.zip.DeflaterInputStream;
21+
import java.util.zip.GZIPInputStream;
2022

23+
import io.fusionauth.http.HTTPValues.ContentEncodings;
2124
import io.fusionauth.http.io.ChunkedInputStream;
2225
import io.fusionauth.http.io.PushbackInputStream;
2326
import io.fusionauth.http.log.Logger;
@@ -161,13 +164,27 @@ public int read(byte[] b, int off, int len) throws IOException {
161164
return read;
162165
}
163166

164-
private void commit() {
167+
private void commit() throws IOException {
165168
committed = true;
166169

167-
// Note that isChunked() should take precedence over the fact that we have a Content-Length.
168-
// - The client should not send both, but in the case they are both present we ignore Content-Length
169170
Long contentLength = request.getContentLength();
170171
boolean hasBody = (contentLength != null && contentLength > 0) || request.isChunked();
172+
173+
// if (hasBody) {
174+
// // The request may contain more than one value, apply in reverse order.
175+
// for (String contentEncoding : request.getContentEncodings().reversed()) {
176+
// if (contentEncoding.equalsIgnoreCase(ContentEncodings.Deflate)) {
177+
// // Use the default buffer size of 512
178+
// delegate = new DeflaterInputStream(delegate);
179+
// } else if (contentEncoding.equalsIgnoreCase(ContentEncodings.Gzip)) {
180+
// // Use the default buffer size of 512
181+
// delegate = new GZIPInputStream(delegate);
182+
// }
183+
// }
184+
// }
185+
186+
// Note that isChunked() should take precedence over the fact that we have a Content-Length.
187+
// - The client should not send both, but in the case they are both present we ignore Content-Length
171188
if (!hasBody) {
172189
delegate = InputStream.nullInputStream();
173190
} else if (request.isChunked()) {

src/test/java/io/fusionauth/http/ChunkedTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public void chunkedRequest_doNotReadTheInputStream(String scheme) throws Excepti
144144
var response = client.send(HttpRequest.newBuilder()
145145
.uri(uri)
146146
.header(Headers.ContentType, "text/plain")
147-
// Note that using a InputStream baed publisher will caues the JDK to
147+
// Note that using a InputStream based publisher will caues the JDK to
148148
// enable Transfer-Encoding: chunked
149149
.POST(BodyPublishers.ofInputStream(() ->
150150
new ByteArrayInputStream(responseBodyBytes)))

src/test/java/io/fusionauth/http/CompressionTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,11 @@ public void compress(String encoding, boolean chunked, String scheme) throws Exc
105105
}
106106
};
107107

108+
// Compress the request using the encoding parameter
108109
ByteArrayOutputStream baseOutputStream = new ByteArrayOutputStream();
109110
DeflaterOutputStream out = encoding.equals(ContentEncodings.Deflate)
110-
? new DeflaterOutputStream(baseOutputStream)
111-
: new GZIPOutputStream(baseOutputStream);
111+
? new DeflaterOutputStream(baseOutputStream, true)
112+
: new GZIPOutputStream(baseOutputStream, true);
112113
out.write("Hello world!".getBytes(StandardCharsets.UTF_8));
113114
out.finish();
114115
byte[] payload = baseOutputStream.toByteArray();
@@ -122,6 +123,10 @@ public void compress(String encoding, boolean chunked, String scheme) throws Exc
122123
.header(Headers.AcceptEncoding, encoding)
123124
// Send the request using the same encoding
124125
.header(Headers.ContentEncoding, encoding)
126+
.header(Headers.ContentType, "text/plain")
127+
// Manually set the header since the body is small, the client not turn on chunked.
128+
.header(Headers.TransferEncoding, "chunked")
129+
// A ByteArrayInputStream should cause the request to be chunk encoded
125130
.POST(BodyPublishers.ofInputStream(() -> new ByteArrayInputStream(payload)))
126131
.uri(uri).GET().build(),
127132
r -> BodySubscribers.ofInputStream()

0 commit comments

Comments
 (0)