Replace Hackney with Req as default HTTP client - #179
Closed
bglusman wants to merge 3 commits into
Closed
Conversation
Erlang/OTP 29 tightened :calendar.time_to_seconds/1 to reject hours
outside 0..23. The IANA tz database legally uses "24:00" for end-of-day
transition boundaries, which time_for_rule/transform_until_datetime parse
to an hour-24 datetime (e.g. {{2024, 3, 31}, {24, 0, 0}}). Passing that to
:calendar.datetime_to_gregorian_seconds/1 — which calls time_to_seconds/1
internally — crashed period building on OTP 29 with a FunctionClauseError.
OTP <= 28 accepted it and returned the value for the equivalent next-day
00:00.
Add Tzdata.Util.datetime_to_gregorian_seconds/1, which computes the value
directly (date_to_gregorian_days * 86400 + h*3600 + m*60 + s) so any hour
(including 24) is handled, matching the pre-OTP-29 result. Route both
Tzdata.Util.datetime_to_utc/3 and Tzdata.PeriodBuilder.datetime_to_utc/3
through it. Add a regression test.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Addresses security concerns with Hackney (CVE-2018-1000007, AIKIDO-2026-10122). Req provides a modern, actively maintained HTTP client built on Mint. Changes: - Add Req as required dependency, remove Hackney - Implement Tzdata.HTTPClient.Req with redirect support - Set Req as default HTTP client in configuration - Hackney implementation remains available for backward compatibility - Update README with migration information Co-Authored-By: Matt Wynne <[email protected]>
Author
|
Opened against the parent repository by mistake while preparing a fork-specific port. Closing this draft; the intended PR targets bglusman/tzdata. |
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.
Purpose
Port and adapt lau/tzdata#165 onto this fork so Req becomes tzdata's default HTTP client and Hackney is no longer a required production dependency. This prepares SCHIP for a follow-up change that can update its tzdata ref and remove Hackney separately.
The original commit by Ryan Spore, co-authored by Matt Wynne, is preserved in this branch's history.
Implementation
Tzdata.HTTPClient.Reqand makes it the default adapter.>= 0.5.10 and < 1.0.0, including SCHIP's locked Req 0.6.2.Tzdata.Finchpool; Req supervises and uses its own pool.Req.Testcoverage; real IANA requests remain available as explicitly included integration tests.Validation
mix format --check-formattedon all changed Elixir files — passed.mix deps.unlock --check-unused— passed.mix test test/tzdata/http_client/req_test.exs— 7/7 passed with locked Req 0.5.17, SCHIP's Req 0.6.2, and Req 0.7.2.mix test test/integration/req_download_test.exs --include integration— 5/5 passed against IANA with Req 0.5.17, 0.6.2, and 0.7.2.mix test --exclude doctest— 49 passed, 5 skipped, 22 excluded.mix deps.tree --only prod— Req/Finch production tree contains no Hackney.mix testunder local Elixir 1.20/OTP 29: 64/65 passed; the single failing historical-transition doctest is pre-existing and reproduces unchanged onorigin/masterunder OTP 29. The draft PR's Elixir 1.14/OTP 25 GitHub Actions run will be the supported-runtime check.mix compile --warnings-as-errorsunder Elixir 1.20/OTP 29 is blocked by pre-existing/dependency warnings, including the existing unusedrequire Tzdata.Util; the supported-runtime GitHub Actions compile check is pending.Change Impact
Scope: diff
Files changed: 12
Functions changed: 8
Cross-app: no
Depth reached: 3
Test files identified: 2
Affected Areas
Tzdata.DataLoader.http_client/0changes the default adapter used by downloads, HEAD metadata, and file-size checks.Tzdata.HTTPClient.Req.get/3,head/3, andrequest/4provide the new default Req implementation.Tzdata.HTTPClient.Hackney.get/3,head/3, andensure_hackney!/0preserve Hackney as an explicitly configured legacy adapter with runtime dependency checks.Tzdata.ReleaseUpdaterandTzdata.DataBuilderare downstream automatic IANA polling, download, and release-loading paths.Tzdata.Mixfilechanges the dependency, configured adapter, and supported Elixir baseline.test/tzdata/http_client/req_test.exsandtest/integration/req_download_test.exscover the new adapter.Category Hints
Risk Assessment
Risk level: medium
Rationale: This changes an existing shared runtime path for every consumer using tzdata's default automatic-update behavior, including its external IANA integration and supported Elixir baseline. Focused unit and tagged integration coverage keep the change below high risk.
Key Factors
Tzdata.DataLoader,Tzdata.ReleaseUpdater, andTzdata.DataBuilder.Skills Used
opening-pull-requestsv1.1.0analyzing-change-impact(unversioned; last reviewed 2026-06-04)developing-with-tdd(unversioned; last reviewed 2026-06-01)searching-elixir-code(unversioned; last reviewed 2026-01-24)writing-elixir-code(unversioned; last reviewed 2026-06-01)