Repository navigation
#2250 CharsetIdentification: read the content type under the protocol prefix #2251
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
Changes from all commits
e3e5bcf
6e8deda
652a1aa
eca1b76
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,10 +57,15 @@ public class CharsetIdentification { | |
| * guess and if that fails too returns UTF-8. This approach is expected to be faster but maybe | ||
| * less reliable than getCharset. | ||
| * | ||
| * @since 1.18 | ||
| * @param protocolMetadataPrefix prefix of the response headers in the metadata, including its | ||
| * separator (e.g. {@code "protocol."}); empty if they are not prefixed | ||
| * @since 4.0 | ||
| */ | ||
| public static String getCharsetFast( | ||
| final Metadata metadata, final byte[] content, final int maxLengthCharsetDetection) { | ||
| final Metadata metadata, | ||
| final byte[] content, | ||
| final int maxLengthCharsetDetection, | ||
| final String protocolMetadataPrefix) { | ||
|
|
||
| // let's look at the BOM first | ||
| String charset = getCharsetFromBOM(content); | ||
|
|
@@ -69,7 +74,7 @@ public static String getCharsetFast( | |
| } | ||
|
|
||
| // then look at what we get from HTTP headers | ||
| charset = getCharsetFromHTTP(metadata); | ||
| charset = getCharsetFromHTTP(metadata, protocolMetadataPrefix); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth a line in the release notes: under the default config this step was effectively dead before, so in fast mode the meta charset won. Now the server header takes precedence with no further check. That follows the HTML spec, but sites with a wrong default header (e.g.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, worth a line. Suggested wording:
|
||
| if (charset != null) { | ||
| return charset; | ||
| } | ||
|
|
@@ -92,11 +97,18 @@ public static String getCharsetFast( | |
| /** | ||
| * Identifies the charset of a document based on the following logic: guess from the | ||
| * ByteOrderMark - else if the same charset is specified in the http headers and the html | ||
| * metadata then use it - otherwise use ICU's charset detector to make an educated guess and if | ||
| * that fails too returns UTF-8. | ||
| * metadata then use it - otherwise use ICU's charset detector to make an educated guess, with | ||
| * the html metadata or else the http headers as a hint, and if that fails too returns UTF-8. | ||
| * | ||
| * @param protocolMetadataPrefix prefix of the response headers in the metadata, including its | ||
| * separator (e.g. {@code "protocol."}); empty if they are not prefixed | ||
| * @since 4.0 | ||
| */ | ||
| public static String getCharset( | ||
| Metadata metadata, byte[] content, int maxLengthCharsetDetection) { | ||
| Metadata metadata, | ||
| byte[] content, | ||
| int maxLengthCharsetDetection, | ||
| String protocolMetadataPrefix) { | ||
|
|
||
| // let's look at the BOM first | ||
| String BOMCharset = getCharsetFromBOM(content); | ||
|
|
@@ -105,7 +117,7 @@ public static String getCharset( | |
| } | ||
|
|
||
| // then look at what we get from HTTP headers and HTML content | ||
| String httpCharset = getCharsetFromHTTP(metadata); | ||
| String httpCharset = getCharsetFromHTTP(metadata, protocolMetadataPrefix); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Side effect to be aware of: before,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch, made it explicit: when the header and the meta disagree, the meta charset is the hint ( One side effect: without a prefix the header was already read, so for those setups a disagreement now passes the meta as the hint instead of no hint. Since ICU barely uses the hint, I didn't add a test for it: I couldn't build a realistic page whose result depends on it without the test relying on ICU internals. Happy to change it if you'd rather keep no hint on disagreement. |
||
| String htmlCharset = getCharsetFromMeta(content, maxLengthCharsetDetection); | ||
|
|
||
| // both exist and agree | ||
|
|
@@ -116,12 +128,7 @@ public static String getCharset( | |
| } | ||
|
|
||
| // let's guess from the text - using a hint or not | ||
| String hintCharset = null; | ||
| if (httpCharset != null && htmlCharset == null) { | ||
| hintCharset = httpCharset; | ||
| } else if (httpCharset == null && htmlCharset != null) { | ||
| hintCharset = htmlCharset; | ||
| } | ||
| String hintCharset = htmlCharset != null ? htmlCharset : httpCharset; | ||
|
|
||
| String textCharset = getCharsetFromText(content, hintCharset, maxLengthCharsetDetection); | ||
| if (textCharset != null) { | ||
|
|
@@ -133,8 +140,9 @@ public static String getCharset( | |
| } | ||
|
|
||
| /** Returns the charset declared by the server if any. */ | ||
| private static String getCharsetFromHTTP(Metadata metadata) { | ||
| return getCharsetFromContentType(metadata.getFirstValue(HttpHeaders.CONTENT_TYPE)); | ||
| private static String getCharsetFromHTTP(Metadata metadata, String protocolMetadataPrefix) { | ||
| return getCharsetFromContentType( | ||
| metadata.getFirstValue(HttpHeaders.CONTENT_TYPE, protocolMetadataPrefix)); | ||
| } | ||
|
|
||
| /** Detects any BOMs and returns the corresponding charset. */ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: please add
@param protocolMetadataPrefix(noting it must include its separator, e.g."protocol.", likeMetadata#putAll(Metadata, String)documents) and an@sincetag, since the existing method has@since 1.18. Same for thegetCharsetoverload.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, on both overloads:
@param protocolMetadataPrefixwith the separator note, and@since 4.0.