Skip to content

fix(tied-hash + ssleay): each-after-delete + HTTPS via HTTP::Tiny#576

Merged
fglock merged 2 commits intomasterfrom
fix/tied-hash-each-and-ssleay-https
Apr 27, 2026
Merged

fix(tied-hash + ssleay): each-after-delete + HTTPS via HTTP::Tiny#576
fglock merged 2 commits intomasterfrom
fix/tied-hash-each-and-ssleay-https

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Apr 27, 2026

Summary

Investigated jcpan -t Net::HTTPS::Any and fixed two distinct bugs that
together unblock the full test suite (10/10 passing, including the live
HTTPS GET/POST integration tests).

1. Tied-hash each skipped entries after delete

RuntimeTiedHashIterator was eagerly calling NEXTKEY at the end of
next() to cache the upcoming key. When user code mutated the tied
hash between each calls (e.g. delete $h{$k} inside
while (my ($k) = each %h)), the cached key already pointed past the
entry whose internal index had just shifted — so an entry was silently
skipped.

Real Perl calls FIRSTKEY / NEXTKEY exactly once per each()
invocation
. Moved the fetch into hasNext() so it happens lazily
inside the next each(), after any user-visible mutation.

Fixes Tie::IxHash's t/each-delete.t (which Net::HTTPS::Any depends on
via tie my %hash, 'Tie::IxHash', ... for ordered query args).

2. Net::SSLeay couldn't do HTTPS

PerlOnJava ships no OpenSSL backend, but it does ship HTTP::Tiny,
which already speaks HTTPS via the JVM TLS stack. Wired
get_https / post_https / do_https to delegate to HTTP::Tiny:

  • Parses the make_headers-style header string back into a hash
  • Calls HTTP::Tiny->new->request(...)
  • Repackages the response as Net::SSLeay's
    ($page, "HTTP/1.1 200 OK", @flat_headers) return shape

Also added the high-level helpers (get_https, post_https,
make_headers, make_form, sslcat, do_https, print_errs, …) to
@EXPORT_OK so use Net::SSLeay qw(get_https post_https ...) compiles.

Variants that need raw OpenSSL semantics (sslcat, *_https3,
*_https4, *_httpx, dump_peer_certificate, …) still raise
"not implemented" — those would need a JSSE-backed socket layer.

Test plan

  • make passes (full unit test suite green)
  • Tie::IxHash test suite: 29/29 pass (was 27/29)
  • jcpan -t Net::HTTPS::Any: 10/10 pass, including
    t/get-netssleay.t (live GET to www.fortify.net) and
    t/post-netssleay.t (live POST to accounts.google.com /
    www.google.com)
  • Smoke test: Net::SSLeay::get_https('example.com', 443, '/', ...)
    returns HTTP/1.1 200 OK with the expected body and headers

Generated with Devin

fglock and others added 2 commits April 27, 2026 20:14
The tied-hash iterator was eagerly calling NEXTKEY at the end of next()
to cache the upcoming key.  When user code mutated the tied hash between
each() calls (e.g. `delete $h{$k}` inside `while (my ($k) = each %h)`),
that cached key was already past the entry whose internal index just
shifted — so the affected key was silently skipped.

Real Perl calls FIRSTKEY/NEXTKEY exactly once per each() invocation.
Move the fetch into hasNext() so the call happens lazily, inside the
next each(), after any user-visible mutation has taken effect.

Fixes Tie::IxHash's t/each-delete.t (and unblocks Net::HTTPS::Any,
which depends on Tie::IxHash).

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
PerlOnJava ships no OpenSSL backend, but it does ship HTTP::Tiny — which
already speaks HTTPS via the JVM TLS stack.  Map Net::SSLeay's high-level
HTTP helpers onto HTTP::Tiny so modules built on Net::SSLeay (e.g.
Net::HTTPS::Any) work out of the box.

Changes to src/main/perl/lib/Net/SSLeay.pm:

* Add the high-level HTTP/HTTPS helpers and utility subs to @EXPORT_OK
  (get_https, post_https, do_https, make_headers, make_form, sslcat, …)
  so `use Net::SSLeay qw(...)` with an explicit import list compiles.

* Replace the _not_implemented stubs for get_https / post_https /
  do_https with a small shim:
    - parses the make_headers-style header string back into a hash
    - calls HTTP::Tiny->new->request(...)
    - repackages the response as Net::SSLeay's
      ($page, "HTTP/1.1 200 OK", @flat_headers).

Variants that need raw OpenSSL semantics (sslcat, *_https3, *_https4,
*_httpx, dump_peer_certificate, …) still raise "not implemented".

Result: Net::HTTPS::Any's full test suite now passes 10/10, including
the live HTTPS GET/POST integration tests.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@fglock fglock merged commit a671ecc into master Apr 27, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant