Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A mechanism for adding non-ASCII headers #4296

Merged
merged 3 commits into from
Sep 29, 2018
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
19 changes: 19 additions & 0 deletions okhttp-tests/src/test/java/okhttp3/HeadersTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,25 @@ public final class HeadersTest {
}
}

@Test public void addUnsafeNonAsciiRejectsUnicodeName() {
try {
Headers headers = new Headers.Builder()
.addUnsafeNonAscii("héader1", "value1")
.build();
fail("Should have complained about invalid value");
} catch (IllegalArgumentException expected) {
assertEquals("Unexpected char 0xe9 at 1 in header name: héader1",
expected.getMessage());
}
}

@Test public void addUnsafeNonAsciiAcceptsUnicodeValue() {
Headers headers = new Headers.Builder()
.addUnsafeNonAscii("header1", "valué1")
.build();
assertEquals("header1: valué1\n", headers.toString());
}

@Test public void ofThrowsOddNumberOfHeaders() {
try {
Headers.of("User-Agent", "OkHttp", "Content-Length");
Expand Down
26 changes: 21 additions & 5 deletions okhttp/src/main/java/okhttp3/Headers.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ public static Headers of(String... namesAndValues) {
for (int i = 0; i < namesAndValues.length; i += 2) {
String name = namesAndValues[i];
String value = namesAndValues[i + 1];
checkNameAndValue(name, value);
checkName(name);
checkValue(value, name);
}

return new Headers(namesAndValues);
Expand All @@ -241,7 +242,8 @@ public static Headers of(Map<String, String> headers) {
}
String name = header.getKey().trim();
String value = header.getValue().trim();
checkNameAndValue(name, value);
checkName(name);
checkValue(value, name);
namesAndValues[i] = name;
namesAndValues[i + 1] = value;
i += 2;
Expand All @@ -250,7 +252,7 @@ public static Headers of(Map<String, String> headers) {
return new Headers(namesAndValues);
}

static void checkNameAndValue(String name, String value) {
static void checkName(String name) {
if (name == null) throw new NullPointerException("name == null");
if (name.isEmpty()) throw new IllegalArgumentException("name is empty");
for (int i = 0, length = name.length(); i < length; i++) {
Expand All @@ -260,6 +262,9 @@ static void checkNameAndValue(String name, String value) {
"Unexpected char %#04x at %d in header name: %s", (int) c, i, name));
}
}
}

static void checkValue(String value, String name) {
if (value == null) throw new NullPointerException("value for name " + name + " == null");
for (int i = 0, length = value.length(); i < length; i++) {
char c = value.charAt(i);
Expand Down Expand Up @@ -303,7 +308,17 @@ public Builder add(String line) {
* Add a header with the specified name and value. Does validation of header names and values.
*/
public Builder add(String name, String value) {
checkNameAndValue(name, value);
checkName(name);
checkValue(value, name);
return addLenient(name, value);
}

/**
* Add a header with the specified name and value. Does validation of header names, allowing
* non-ASCII values.
*/
public Builder addUnsafeNonAscii(String name, String value) {
checkName(name);
return addLenient(name, value);
}

Expand Down Expand Up @@ -345,7 +360,8 @@ public Builder removeAll(String name) {
* found, the existing values are replaced.
*/
public Builder set(String name, String value) {
checkNameAndValue(name, value);
checkName(name);
checkValue(value, name);
removeAll(name);
addLenient(name, value);
return this;
Expand Down