Согласно RFC 2616, раздел 2.2 , значения заголовка HTTP обычно должны кодироваться с использованием ISO-8859-1.
Здесь bit.ly отправляет неверный ответ - заголовок Location: кодируется с использованием UTF-8, поэтому символ em-dash представлен тремя отдельными байтами (0xe2, 0x80, 0x94).
HttpURLConnection
декодирует байты с использованием ISO-8859-1, поэтому они становятся тремя символами (â
и двумя неопределенными символами), , но выглядит так, как будто вы перекодируете их с использованием UTF-8 (производя 2 байт на символ, поскольку все три имеют значения> = 0x80) перед применением кодировки URL .
Firefox, скорее всего, обрабатывает данные как ISO-8859-1 на всем протяжении; затем проблема устраняется, если позже применяется кодировка URL.
Вы можете сделать то же самое путем URL-кодирования значения, возвращаемого getHeaderField()
; поскольку диапазон Unicode от U + 0080 до U + 00FF идентичен диапазону байтов ISO-8859-1 0x80-0xFF, символы, не входящие в ASCII, можно кодировать, приводя их к значениям int
:
/**
* Takes a URI that was decoded as ISO-8859-1 and applies percent-encoding
* to non-ASCII characters. Workaround for broken origin servers that send
* UTF-8 in the Location: header.
*/
static String encodeUriFromHeader(String uri) {
StringBuilder sb = new StringBuilder();
for(char ch : badLocation.toCharArray()) {
if(ch < (char)128) {
sb.append(ch);
} else {
// this is ONLY valid if the uri was decoded using ISO-8859-1
sb.append(String.format("%%%02X", (int)ch));
}
}
return sb.toString();
}