Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

Expand Down Expand Up @@ -39,7 +40,7 @@ private void decideCompression(int length) throws IOException {

if (compressionAllowed && length >= minSizeForCompression) {
Optional<Compressor> compressor;
compressor = findMatchingCompressor(ctx.header(Constants.ACCEPT_ENCODING));
compressor = findMatchingCompressor(ctx.headerValues(Constants.ACCEPT_ENCODING));
if (compressor.isPresent()) {
this.compressedStream = compressor.get().compress(originStream);
ctx.header(Constants.CONTENT_ENCODING, compressor.get().encoding());
Expand Down Expand Up @@ -69,9 +70,15 @@ public void close() throws IOException {
originStream.close();
}

private Optional<Compressor> findMatchingCompressor(String acceptedEncoding) {
private Optional<Compressor> findMatchingCompressor(List<String> acceptedEncoding) {
if (acceptedEncoding != null) {
return Arrays.stream(acceptedEncoding.split(","))
// it seems jetty may handle multi-value headers differently
var stream =
acceptedEncoding.size() > 1
? acceptedEncoding.stream()
: Arrays.stream(acceptedEncoding.getFirst().split(","));

return stream
.map(e -> e.trim().split(";")[0])
.map(e -> "*".equals(e) ? "gzip" : e.toLowerCase())
.map(compression::forType)
Expand Down
20 changes: 17 additions & 3 deletions avaje-jex/src/main/java/io/avaje/jex/core/JdkContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,15 +221,19 @@ public Map<String, List<String>> formParamMap() {
}

private String header(Headers headers, String name) {
final List<String> values = headers.get(name);
return values == null || values.isEmpty() ? null : values.getFirst();
return headers.getFirst(name);
}

@Override
public String header(String key) {
return header(exchange.getRequestHeaders(), key);
}

@Override
public List<String> headerValues(String key) {
return exchange.getRequestHeaders().get(key);
}

@Override
public Context header(String key, List<String> value) {
exchange.getResponseHeaders().put(key, value);
Expand Down Expand Up @@ -261,10 +265,20 @@ public Context headerMap(Map<String, List<String>> map) {
}

@Override
public Headers headers() {
public Headers requestHeaders() {
return exchange.getRequestHeaders();
}

@Override
public Headers responseHeaders() {
return exchange.getResponseHeaders();
}

@Override
public List<String> responseHeaderValues(String key) {
return exchange.getResponseHeaders().get(key);
}

@Override
public String host() {
return header(Constants.HOST);
Expand Down
32 changes: 27 additions & 5 deletions avaje-jex/src/main/java/io/avaje/jex/http/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ default <T> T bodyAsClass(Class<T> beanType) {
* @param beanType The bean type
*/
<T> T bodyAsType(Type beanType);

/**
* Return the request body as bean using {@link #bodyAsInputStream()}.
*
Expand All @@ -99,7 +99,7 @@ default <T> T bodyAsClass(Class<T> beanType) {
default <T> T bodyStreamAsClass(Class<T> beanType) {
return bodyAsType(beanType);
}

/**
* Return the request body as bean of the given type using {@link #bodyAsInputStream()}.
*
Expand Down Expand Up @@ -192,12 +192,19 @@ default String fullUrl() {
}

/**
* Return the request header.
* Return the request header value by name.
*
* @param key The header key
* @param key The first value of the header
*/
String header(String key);

/**
* Return the request headers.
*
* @param key all values of the header key
*/
List<String> headerValues(String key);

/**
* Set the response header.
*
Expand Down Expand Up @@ -235,7 +242,14 @@ default String fullUrl() {
*
* @return the request headers
*/
Headers headers();
Headers requestHeaders();

/**
* Return underlying response headers.
*
* @return the response headers
*/
Headers responseHeaders();

/** Add the response headers using the provided map. */
default Context headers(Map<String, String> headers) {
Expand Down Expand Up @@ -439,6 +453,14 @@ default Context render(String name) {
*/
String responseHeader(String key);

/**
* Returns the value of the specified response header.
*
* @param key The name of the header.
* @return The value of the header, or null if not found.
*/
List<String> responseHeaderValues(String key);

/** Return true if the response has been sent. */
boolean responseSent();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@ static TestPair init() {
"/sus",
ctx ->
ctx.write(
CompressionTest.class.getResourceAsStream("/public/sus.txt")))
.get(
"/forced",
ctx -> ctx.header(Constants.CONTENT_ENCODING, "gzip").text("hi")));
CompressionTest.class.getResourceAsStream("/public/sus.txt"))));

return TestPair.create(app);
}
Expand Down Expand Up @@ -72,12 +69,4 @@ void testNoCompression() {
assertThat(res.statusCode()).isEqualTo(200);
assertThat(res.headers().firstValue(Constants.CONTENT_ENCODING)).isEmpty();
}

@Test
void testForcedCompression() {
HttpResponse<String> res =
pair.request().header(Constants.ACCEPT_ENCODING, "gzip").path("forced").GET().asString();
assertThat(res.statusCode()).isEqualTo(200);
assertThat(res.headers().firstValue(Constants.CONTENT_ENCODING)).contains("gzip");
}
}
8 changes: 7 additions & 1 deletion avaje-jex/src/test/java/io/avaje/jex/core/TestPair.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.avaje.jex.core;

import java.net.http.HttpClient.Version;
import java.time.Duration;

import io.avaje.http.client.HttpClient;
import io.avaje.http.client.HttpClientRequest;
Expand Down Expand Up @@ -43,7 +44,12 @@ public static TestPair create(Jex app) {
var jexServer = app.port(0).start();
var port = jexServer.port();
var url = "http://localhost:" + port;
var client = HttpClient.builder().version(Version.HTTP_1_1).baseUrl(url).build();
var client =
HttpClient.builder()
.version(Version.HTTP_1_1)
.requestTimeout(Duration.ofDays(1))
.baseUrl(url)
.build();

return new TestPair(port, jexServer, client);
}
Expand Down