Skip to content

Commit 9ce9e85

Browse files
committed
Optimize normalizeValue for headers
1 parent 65eec08 commit 9ce9e85

1 file changed

Lines changed: 22 additions & 24 deletions

File tree

  • http/http-api/src/main/java/software/amazon/smithy/java/http/api

http/http-api/src/main/java/software/amazon/smithy/java/http/api/HeaderUtils.java

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ public final class HeaderUtils {
1212
// Header name lookup table: 0=invalid, 1=valid lower, 2=valid upper.
1313
private static final byte[] HEADER_NAME_TABLE = new byte[128];
1414

15-
// Header value lookup table: true = allowed character
16-
private static final boolean[] VALID_VALUE_CHAR = new boolean[256];
17-
1815
static {
1916
for (char c = 'a'; c <= 'z'; c++) {
2017
HEADER_NAME_TABLE[c] = 1;
@@ -26,16 +23,6 @@ public final class HeaderUtils {
2623
for (int i = 0; i < validChars.length(); i++) {
2724
HEADER_NAME_TABLE[validChars.charAt(i)] = 1;
2825
}
29-
30-
// Valid value chars per RFC 7230 field-content: SP, HTAB, VCHAR, obs-text
31-
VALID_VALUE_CHAR[' '] = true;
32-
VALID_VALUE_CHAR['\t'] = true;
33-
for (int c = 0x21; c <= 0x7E; c++) {
34-
VALID_VALUE_CHAR[c] = true;
35-
}
36-
for (int c = 0x80; c <= 0xFF; c++) {
37-
VALID_VALUE_CHAR[c] = true;
38-
}
3926
}
4027

4128
private HeaderUtils() {}
@@ -102,25 +89,36 @@ static String normalizeName(String name) {
10289
* @throws IllegalArgumentException if the value contains invalid characters
10390
*/
10491
public static String normalizeValue(String value) {
105-
// Simulate String.trim(), but we only want to trim leading and trailing ' ' and '\t'.
10692
int len = value.length();
107-
int end = len - 1;
108-
int start = trimStart(value, end);
109-
end = trimEnd(value, start);
110-
if (start > end) {
111-
return "";
93+
if (len == 0) {
94+
return value;
11295
}
11396

114-
for (int i = start; i <= end; i++) {
97+
// Peek at the boundaries to detect whether trimming is needed.
98+
char first = value.charAt(0);
99+
char last = value.charAt(len - 1);
100+
boolean trimNeeded = first == ' ' || first == '\t' || last == ' ' || last == '\t';
101+
102+
// Ensure valid chars match obs-text
103+
for (int i = 0; i < len; i++) {
115104
char c = value.charAt(i);
116-
if (c > 255 || !VALID_VALUE_CHAR[c]) {
105+
if (c > 0xFF || (c < 0x20 && c != '\t') || c == 0x7F) {
117106
throw invalidHeaderValueChar(value);
118107
}
119108
}
120109

121-
return (start == 0 && end == len - 1)
122-
? value
123-
: value.substring(start, end + 1);
110+
if (!trimNeeded) {
111+
return value;
112+
}
113+
114+
int end = len - 1;
115+
int start = trimStart(value, end);
116+
end = trimEnd(value, start);
117+
if (start > end) {
118+
return "";
119+
}
120+
121+
return value.substring(start, end + 1);
124122
}
125123

126124
private static int trimStart(String s, int end) {

0 commit comments

Comments
 (0)