Skip to content

Commit 733a98c

Browse files
committed
Use PercentCodec and MessageSupport in ALPN header codec
Drop local percent-decoding logic in AlpnHeaderSupport and delegate to core5 PercentCodec. Use MessageSupport#headerOfTokens to format the ALPN header value.
1 parent eed86b1 commit 733a98c

1 file changed

Lines changed: 8 additions & 40 deletions

File tree

httpclient5/src/main/java/org/apache/hc/client5/http/impl/AlpnHeaderSupport.java

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
*/
2727
package org.apache.hc.client5.http.impl;
2828

29-
3029
import java.nio.charset.StandardCharsets;
3130
import java.util.ArrayList;
3231
import java.util.Collections;
@@ -35,8 +34,10 @@
3534
import org.apache.hc.core5.annotation.Contract;
3635
import org.apache.hc.core5.annotation.Internal;
3736
import org.apache.hc.core5.annotation.ThreadingBehavior;
37+
import org.apache.hc.core5.http.Header;
3838
import org.apache.hc.core5.http.message.MessageSupport;
3939
import org.apache.hc.core5.http.message.ParserCursor;
40+
import org.apache.hc.core5.net.PercentCodec;
4041
import org.apache.hc.core5.util.Args;
4142

4243
/**
@@ -48,6 +49,7 @@
4849
@Internal
4950
public final class AlpnHeaderSupport {
5051

52+
private static final String HEADER_NAME = "ALPN";
5153
private static final char[] HEXADECIMAL = "0123456789ABCDEF".toCharArray();
5254

5355
private AlpnHeaderSupport() {
@@ -58,16 +60,12 @@ private AlpnHeaderSupport() {
5860
*/
5961
public static String formatValue(final List<String> protocolIds) {
6062
Args.notEmpty(protocolIds, "protocolIds");
61-
final StringBuilder sb = new StringBuilder();
62-
boolean first = true;
63+
final List<String> tokens = new ArrayList<>(protocolIds.size());
6364
for (final String id : protocolIds) {
64-
if (!first) {
65-
sb.append(", ");
66-
}
67-
sb.append(encodeId(id));
68-
first = false;
65+
tokens.add(encodeId(id));
6966
}
70-
return sb.toString();
67+
final Header header = MessageSupport.headerOfTokens(HEADER_NAME, tokens);
68+
return header.getValue();
7169
}
7270

7371
/**
@@ -107,27 +105,10 @@ public static String encodeId(final String id) {
107105

108106
/**
109107
* Decodes percent-encoded token to raw ID using UTF-8.
110-
* Accepts lowercase hex; malformed/incomplete sequences are left literal.
111108
*/
112109
public static String decodeId(final String token) {
113110
Args.notBlank(token, "token");
114-
final byte[] buf = new byte[token.length()];
115-
int bi = 0;
116-
for (int i = 0; i < token.length(); ) {
117-
final char c = token.charAt(i);
118-
if (c == '%' && i + 2 < token.length()) {
119-
final int hi = hexVal(token.charAt(i + 1));
120-
final int lo = hexVal(token.charAt(i + 2));
121-
if (hi >= 0 && lo >= 0) {
122-
buf[bi++] = (byte) ((hi << 4) | lo);
123-
i += 3;
124-
continue;
125-
}
126-
}
127-
buf[bi++] = (byte) c;
128-
i++;
129-
}
130-
return new String(buf, 0, bi, StandardCharsets.UTF_8);
111+
return PercentCodec.decode(token, StandardCharsets.UTF_8);
131112
}
132113

133114
// RFC7230 tchar minus '%' (RFC7639 requires '%' be percent-encoded)
@@ -167,17 +148,4 @@ private static void appendPctEncoded(final int b, final StringBuilder sb) {
167148
sb.append(HEXADECIMAL[(b >>> 4) & 0x0F]);
168149
sb.append(HEXADECIMAL[b & 0x0F]);
169150
}
170-
171-
private static int hexVal(final char c) {
172-
if (c >= '0' && c <= '9') {
173-
return c - '0';
174-
}
175-
if (c >= 'A' && c <= 'F') {
176-
return 10 + (c - 'A');
177-
}
178-
if (c >= 'a' && c <= 'f') {
179-
return 10 + (c - 'a');
180-
}
181-
return -1;
182-
}
183151
}

0 commit comments

Comments
 (0)