From 1360fe4e8de8a55482e68ef35bd5c379acdd0392 Mon Sep 17 00:00:00 2001 From: Toddr Bot Date: Sun, 5 Apr 2026 23:18:00 +0000 Subject: [PATCH 1/3] Remove dead code from async refactor - Remove _sync_io flag from HTTP.pm (set but never read) - Remove commented-out DESTROY sub from ACME2.pm - Remove commented-out Content-Type line from HTTP.pm Co-Authored-By: Claude Opus 4.6 --- lib/Net/ACME2.pm | 4 ---- lib/Net/ACME2/HTTP.pm | 7 ------- 2 files changed, 11 deletions(-) diff --git a/lib/Net/ACME2.pm b/lib/Net/ACME2.pm index 949907a..d861ddc 100644 --- a/lib/Net/ACME2.pm +++ b/lib/Net/ACME2.pm @@ -1190,10 +1190,6 @@ sub _die_generic { *create_new_account = *create_account; *create_new_order = *create_order; -# sub DESTROY { -# print "ACME2 destroyed at ${^GLOBAL_PHASE}\n"; -# } - 1; =head1 TODO diff --git a/lib/Net/ACME2/HTTP.pm b/lib/Net/ACME2/HTTP.pm index 7e397cf..fb553b1 100644 --- a/lib/Net/ACME2/HTTP.pm +++ b/lib/Net/ACME2/HTTP.pm @@ -39,11 +39,7 @@ our $verify_SSL = 1; sub new { my ( $class, %opts ) = @_; - my $is_sync; - $opts{'ua'} ||= do { - $is_sync = 1; - require Net::ACME2::HTTP_Tiny; Net::ACME2::HTTP_Tiny->new( verify_SSL => $verify_SSL ); }; @@ -53,7 +49,6 @@ sub new { _acme_key => $opts{'key'}, _key_id => $opts{'key_id'}, _retries_left => $_MAX_RETRIES, - _sync_io => $is_sync, }, $class; return bless $self, $class; @@ -144,8 +139,6 @@ sub _post { sub { my $jws = shift; - # local $opts_hr->{'headers'}{'Content-Type'} = 'application/jose+json'; - return Net::ACME2::PromiseUtil::do_then_catch( sub { return $self->_request_and_set_last_nonce( From 5ee07d66fe9bcbe47a718eb31273a73890f933e5 Mon Sep 17 00:00:00 2001 From: Toddr Bot Date: Sun, 5 Apr 2026 23:18:13 +0000 Subject: [PATCH 2/3] Guard empty lines in Curl.pm header parsing Trailing CRLF in HTTP headers produces an empty line after split. Without this guard, the empty line would be parsed as a malformed header and trigger an uninitialized-value warning on $value. Co-Authored-By: Claude Opus 4.6 --- lib/Net/ACME2/Curl.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Net/ACME2/Curl.pm b/lib/Net/ACME2/Curl.pm index 1d414dd..39d62fe 100644 --- a/lib/Net/ACME2/Curl.pm +++ b/lib/Net/ACME2/Curl.pm @@ -136,6 +136,8 @@ sub _imitate_http_tiny { my %headers; for my $line ( split m<\x0d?\x0a>, $head ) { + next if !length $line; + if (defined $reason) { my ($name, $value) = split m<\s*:\s*>, $line, 2; $name =~ tr; From 3a045a18c42f2b293a76039de6ef5670104a5f0d Mon Sep 17 00:00:00 2001 From: Toddr Bot Date: Sun, 5 Apr 2026 23:18:30 +0000 Subject: [PATCH 3/3] Improve naming and add explanatory comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename _directory_promise to _directory_cache — in sync mode this caches a plain hashref, not a promise, so the old name was misleading - Add comment explaining why badNonce retry uses mutation on _retries_left instead of local() (promise chain compatibility) Co-Authored-By: Claude Opus 4.6 --- lib/Net/ACME2.pm | 2 +- lib/Net/ACME2/HTTP.pm | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/Net/ACME2.pm b/lib/Net/ACME2.pm index d861ddc..d8692b8 100644 --- a/lib/Net/ACME2.pm +++ b/lib/Net/ACME2.pm @@ -1043,7 +1043,7 @@ sub _key_thumbprint { sub _get_directory { my ($self) = @_; - return $self->{'_directory_promise'} ||= do { + return $self->{'_directory_cache'} ||= do { my $dir_path = $self->DIRECTORY_PATH(); my $http = $self->{'_http'}; diff --git a/lib/Net/ACME2/HTTP.pm b/lib/Net/ACME2/HTTP.pm index fb553b1..d15629b 100644 --- a/lib/Net/ACME2/HTTP.pm +++ b/lib/Net/ACME2/HTTP.pm @@ -163,6 +163,10 @@ sub _post { my $resp; + # NB: We mutate $self->{'_retries_left'} rather than + # using local() because this code may run inside a + # promise chain where local's dynamic scope doesn't + # extend across async callbacks. if ( eval { $err->get('acme')->type() =~ m<:badNonce\z> } ) { if (!$self->{'_retries_left'}) { warn( "$url: Received “badNonce” error, and no retries left!\n" );