Make the WARC digest algorithm configurable - #2110
Open
abhinav-phi wants to merge 1 commit into
Open
Conversation
WARCRecordFormat hard coded the algorithm for the WARC-Payload-Digest and WARC-Block-Digest fields to SHA-1 with no way for an operator to choose another algorithm. Add the configuration key warc.digest.algorithm which accepts sha1 (the default, kept for compatibility with CDX indexes and other downstream tooling) and sha256, and thread it through WARCHdfsBolt so that response, request, resource and metadata records all use it. The static getDigestSha1 helpers are kept and deprecated in favour of the new getDigest instance methods. apache#2106
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR addresses #2106 and fixes it.
Problem
WARCRecordFormat.getDigestSha1()computed a SHA-1 digest over the bytes and returned it assha1:<base32>. That fixed value was used for theWARC-Payload-DigestandWARC-Block-Digestheaders of response, resource, request and metadata records. There was no configuration key for the algorithm, so an operator who wants SHA-256 digests in their archives — which WARC 1.1 allows — could not have them without rewriting the records afterwards.SHA-1 digests are the convention across the WARC ecosystem and identify content for deduplication rather than authenticate it, so this is not urgent — but it was still a fixed choice in a place where the digested bytes come from the network. Operators whose own policy rules out SHA-1, or whose downstream tooling wants SHA-256, had no option.
Solution
Add a configuration key
warc.digest.algorithmand thread the configured algorithm through all record formats:sha1andsha256. The value is matched case-insensitively, an optional hyphen is ignored (sha256,SHA-256,SHA256are all accepted) and surrounding whitespace is trimmed.sha1remains the default: CDX indexes and revisit tooling downstream assumesha1:base32, and changing the default would break them. Deciding on a different default can be done separately from adding the option.md5) raises anIllegalArgumentExceptionwith a descriptive message when the bolt is prepared, instead of silently producing digests with a different algorithm than the one configured.Changes
external/warc/src/main/java/org/apache/stormcrawler/warc/WARCRecordFormat.javaDIGEST_ALGORITHM_PARAM(warc.digest.algorithm) and the supported valuesDIGEST_ALGORITHM_SHA1/DIGEST_ALGORITHM_SHA256.WARCRecordFormat(String protocolMDprefix, String digestAlgorithm); the existing single-argument constructor is unchanged in behaviour and keeps defaulting to SHA-1.getDigest(byte[])andgetDigest(byte[], byte[])emit the matchingsha1:/sha256:prefix. The digest used for records without content (digestNoContent) is now derived from the configured algorithm instead of a static SHA-1 constant.getDigestSha1(byte[])andgetDigestSha1(byte[], byte[])are kept for compatibility with code outside the module that calls them, now marked@Deprecatedin favour of the instance methods.external/warc/src/main/java/org/apache/stormcrawler/warc/WARCRequestRecordFormat.javaandMetadataRecordFormat.javagetDigestinstance methods so request and metadata records use the same algorithm as response and resource records.external/warc/src/main/java/org/apache/stormcrawler/warc/WARCHdfsBolt.javawarc.digest.algorithmfrom the topology configuration (defaultsha1) and passes it to every record format it instantiates, so a single setting governs the whole WARC output.Documentation
external/warc/README.md: documents the new key, the accepted values and the compatibility considerations around SHA-1.docs/src/main/asciidoc/configuration.adoc: addswarc.digest.algorithmto the WARC section of the configuration reference.Note on #2034
As requested in the issue, I checked PR #2034 ("WARC writer: WARC-Protocol header to follow WARC field proposals"): it is about the
WARC-Protocol/ cipher-suite headers and does not touch digest computation, so this is not a duplicate. It modifies the same file, so whichever merges second may need a trivial rebase.Testing
WARCDigestAlgorithmTest(9 tests):nullalgorithm value;getDigest(byte[])andgetDigest(byte[], byte[]), including empty content;SHA256,SHA-256,sha256,SHA-1);IllegalArgumentExceptionfor unsupported values (md5,sha512) on all three record format classes;WARC-Payload-Digest/WARC-Block-Digestcarry thesha256:prefix and the correct digest value, computed independently of the code under test.WARCHdfsBoltTest.testDigestAlgorithmConfigprepares the bolt withwarc.digest.algorithm: sha256and verifies that the written records (warcinfo, request, response) usesha256:digests.mvn -pl external/warc test: 22 tests run, 0 failures, 0 errors;checkstyle:checkreports 0 violations.