Skip to content

Commit

Permalink
Handle zero or more spaces after commas when parsing Accept-Encoding (#…
Browse files Browse the repository at this point in the history
…6380)

* Handle zero or more spaces after commas when parsing Accept-Encoding header. Minor refactoring to add some unit tests. Issue 6352.

* Removed empty line.

Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com>

---------

Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com>
  • Loading branch information
spericas committed Mar 8, 2023
1 parent 1dac492 commit 4cce2ba
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 8 deletions.
10 changes: 10 additions & 0 deletions nima/http/encoding/encoding/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,7 @@ public ContentEncoder encoder(Headers headers) {
Accept-Encoding: gzip, compress, br
Accept-Encoding: br;q=1.0, gzip;q=0.8, *;q=0.1
*/
String[] values = acceptEncoding.split(", ");
List<EncodingWithQ> supported = new ArrayList<>(values.length);
for (String value : values) {
supported.add(EncodingWithQ.parse(value));
}
Collections.sort(supported);
List<EncodingWithQ> supported = encodings(acceptEncoding);
for (EncodingWithQ encodingWithQ : supported) {
if ("*".equals(encodingWithQ.encoding)) {
return firstEncoder;
Expand All @@ -113,7 +108,23 @@ public ContentEncoder encoder(Headers headers) {
return ContentEncoder.NO_OP;
}

private static class EncodingWithQ implements Comparable<EncodingWithQ> {
/**
* Extract encodings from header value and sort them based on quality.
*
* @param acceptEncoding comma-separated list of encodings
* @return sorted list of encodings
*/
static List<EncodingWithQ> encodings(String acceptEncoding) {
String[] values = acceptEncoding.split(",");
List<EncodingWithQ> supported = new ArrayList<>(values.length);
for (String value : values) {
supported.add(EncodingWithQ.parse(value));
}
Collections.sort(supported);
return supported;
}

static class EncodingWithQ implements Comparable<EncodingWithQ> {
private final String encoding;
private final double q;

Expand All @@ -125,7 +136,7 @@ private static class EncodingWithQ implements Comparable<EncodingWithQ> {
static EncodingWithQ parse(String value) {
if (value.indexOf(';') != -1) {
int index = value.indexOf(';');
String encoding = value.substring(0, index);
String encoding = value.substring(0, index).trim();
String qString = value.substring(index + 1); // q=0.1
index = qString.indexOf('=');
if (index == -1) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.helidon.nima.http.encoding;

import java.util.List;

import org.junit.jupiter.api.Test;
import io.helidon.nima.http.encoding.ContentEncodingSupportImpl.EncodingWithQ;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static io.helidon.nima.http.encoding.ContentEncodingSupportImpl.encodings;

class ContentEncodingSupportTest {

@Test
void testEncodingsParserOne() {
List<EncodingWithQ> encodings = encodings("gzip");
assertThat(encodings.size(), is(1));
assertThat(encodings.get(0).toString(), is("gzip;q=1.0"));
}

@Test
void testEncodingsParserMany() {
List<EncodingWithQ> encodings = encodings("gzip,compress, br ");
assertThat(encodings.size(), is(3));
assertThat(encodings.get(0).toString(), is("gzip;q=1.0"));
assertThat(encodings.get(1).toString(), is("compress;q=1.0"));
assertThat(encodings.get(2).toString(), is("br;q=1.0"));
}

@Test
void testEncodingsParserWithQs() {
List<EncodingWithQ> encodings = encodings("gzip;q=1.0, deflate;q=0.6, identity;q=0.3");
assertThat(encodings.size(), is(3));
assertThat(encodings.get(0).toString(), is("gzip;q=1.0"));
assertThat(encodings.get(1).toString(), is("deflate;q=0.6"));
assertThat(encodings.get(2).toString(), is("identity;q=0.3"));
}
}

0 comments on commit 4cce2ba

Please sign in to comment.