nicoscandolo commented on code in PR #2251:
URL: https://github.com/apache/stormcrawler/pull/2251#discussion_r4340483938


##########
core/src/main/java/org/apache/stormcrawler/util/CharsetIdentification.java:
##########
@@ -61,6 +61,18 @@ public class CharsetIdentification {
      */
     public static String getCharsetFast(
             final Metadata metadata, final byte[] content, final int 
maxLengthCharsetDetection) {
+        return getCharsetFast(metadata, content, maxLengthCharsetDetection, 
"");

Review Comment:
   Done: both 3-arg methods are `@Deprecated`, with a `@deprecated` note 
pointing to the prefixed overload. No production code calls them anymore. The 
existing `CharsetIdentificationTest` cases still exercise them.
   



##########
core/src/main/java/org/apache/stormcrawler/util/CharsetIdentification.java:
##########
@@ -61,6 +61,18 @@ public class CharsetIdentification {
      */
     public static String getCharsetFast(
             final Metadata metadata, final byte[] content, final int 
maxLengthCharsetDetection) {
+        return getCharsetFast(metadata, content, maxLengthCharsetDetection, 
"");
+    }
+
+    /**
+     * Same as {@link #getCharsetFast(Metadata, byte[], int)}, reading the 
HTTP Content-Type under
+     * the prefix the fetcher stores the response headers with 
(protocol.md.prefix).
+     */
+    public static String getCharsetFast(
+            final Metadata metadata,
+            final byte[] content,
+            final int maxLengthCharsetDetection,
+            final String protocolMetadataPrefix) {

Review Comment:
   Done, on both overloads: `@param protocolMetadataPrefix` with the separator 
note, and `@since 4.0`.
   



##########
core/src/main/java/org/apache/stormcrawler/util/CharsetIdentification.java:
##########
@@ -69,7 +81,7 @@ public static String getCharsetFast(
         }
 
         // then look at what we get from HTTP headers
-        charset = getCharsetFromHTTP(metadata);
+        charset = getCharsetFromHTTP(metadata, protocolMetadataPrefix);

Review Comment:
   Agreed, worth a line. Suggested wording:
   
   > With the default `protocol.md.prefix`, the charset in the HTTP 
`Content-Type` was never read (#2250). It is now. With `detect.charset.fast: 
true` the server header takes precedence, as the HTML spec says, so pages whose 
header disagrees with their `<meta charset>` will decode differently. With the 
default `detect.charset.fast: false`, the header is used when it agrees with 
the meta charset.
   



##########
core/src/main/java/org/apache/stormcrawler/util/CharsetIdentification.java:
##########
@@ -105,7 +129,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);

Review Comment:
   Good catch, made it explicit: when the header and the meta disagree, the 
meta charset is the hint (`htmlCharset != null ? htmlCharset : httpCharset`). 
That keeps what prefixed deployments did before the fix.
   
   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.
   



##########
core/src/test/java/org/apache/stormcrawler/bolt/JSoupParserBoltTest.java:
##########
@@ -365,4 +369,36 @@ void testBaseHrefOutlinkResolution() throws IOException {
                 
"https://www.example.be/fr/rayons/stockage-archivage-de-donnees/218725";,
                 statusTuples.get(0).get(0));
     }
+
+    /**
+     * The fetcher stores the response headers under protocol.md.prefix, so 
the charset declared in
+     * the Content-Type has to be read with that prefix. Without it the header 
is never seen, the
+     * header and the meta charset can never agree, and ICU guesses a UTF-8 
page whose detection
+     * window is plain ASCII as ISO-8859-1, see issue #2250.
+     */
+    @Test
+    void prefixedContentTypeCharsetIsUsed() throws IOException {

Review Comment:
   Done:
   - The bolt test is parameterized on `detect.charset.fast`. In fast mode it 
runs without a meta charset, since the meta would be returned otherwise.
   - Added `fastDetectionReadsThePrefixedContentType` and 
`detectionReadsThePrefixedContentType` to `CharsetIdentificationTest`.
   
   I checked that reverting the fast-path call in `JSoupParserBolt` to the 
3-arg form now fails the fast case, and that ignoring the prefix in the 
overloads fails all the new tests.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to