Revision history for HTTP-Handy

1.07  2026-06-06 JST (Japan Standard Time)

    Fixes:
      - t/lib/INA_CPAN_Check.pm: emit exactly one TAP plan line per test
        file. Each check_* helper previously called plan_tests() itself,
        while the .t files also called plan_tests(count_*); this produced
        multiple "1..N" lines in a single file. Under a real TAP harness
        (prove / Test::Harness, as used by CPAN Testers) this raised
        "More than one plan found in TAP output" and made the affected
        files FAIL, even though every individual "ok" line passed when the
        scripts were run by hand. Affected files: t/9010-encoding.t,
        t/9030-distribution.t, t/9040-style.t. The plan_tests() call is
        now removed from every check_* helper, leaving the .t file as the
        sole owner of the plan line.
      - t/lib/INA_CPAN_Check.pm: count_A() now returns the actual number
        of MANIFEST entries instead of a fixed 1, so that the plan
        computed by t/9030-distribution.t matches the number of A1 checks
        that check_A() emits.
      - t/lib/INA_CPAN_Check.pm: remove the mid-stream plan_skip() calls
        from check_A() and check_C(); the MANIFEST-absent guard is handled
        by the .t file and by count_C() before any plan line is printed.
      - t/lib/INA_CPAN_Check.pm: check_K() now honours the k3_exempt
        option passed by t/9040-style.t. The argument was previously
        discarded by "my ($root) = @_;", so the intended exemption of
        accessor-style hash names (%env, %opts, %args) never took effect;
        the K3 detector also did not capture the hash name. check_K() now
        accepts "k3_exempt => REGEX", captures the returned hash name via
        /return \%(\w*)/, and skips a "return \%name" only when the name
        matches the supplied pattern. Behaviour is unchanged when
        k3_exempt is not passed (every "return \%..." is still flagged),
        so distributions that call check_K($root) without the option are
        unaffected.
      - t/lib/INA_CPAN_Check.pm: add a regression guard for the two TAP
        defect classes above. plan_tests() now refuses to emit a second
        "1..N" line, and an end-of-run reconciliation reports
        "planned X but ran Y" (setting a non-zero exit) when the emitted
        plan does not match the number of ok()/not-ok() lines. Both
        problems now FAIL immediately on a plain "perl t/foo.t", not only
        under a real harness.
      - t/lib/INA_CPAN_Check.pm: add selfcheck_suite(), which runs t/*.t
        (and xt/*.t) in a child Perl and verifies one plan line per file,
        plan == number of ok/not-ok lines, and no failures.
      - pmake.bat: at "pmake dist" time, after the existing source checks,
        run INA_CPAN_Check::selfcheck_suite() as check3 and abort the
        build if any test file fails the plan-sanity check (disable with
        --no-check3). Bump $PMAKE_BAT_VERSION to 0.34.
      - t/lib/INA_CPAN_Check.pm: pass \@files / \@pm_files (a reference)
        instead of [ @files ] (an anonymous copy) to _find_pm_t() in
        _scan_code(), check_D(), check_E(), and check_K(). The copy form
        meant the collected file list never reached the caller, so E1
        (no shebang in lib/*.pm) and K3 (return { %hash } form) silently
        scanned zero files and always passed.

1.06  2026-06-03 JST (Japan Standard Time)

    Fixes:
      - lib/HTTP/Handy.pm: HTTP::Handy::Input::read() no longer emits
        "Use of uninitialized value $_[1] in substr" when the caller
        passes an undefined buffer (the common "my $buf; $input->read(
        $buf, $len)" idiom, as used by PSGI request body readers). The
        in-place 4-argument substr now treats an undefined buffer as
        empty first, matching the built-in read() contract. The result
        was already correct; this only silences the warning under
        use warnings / $^W.

1.05  2026-05-17 JST (Japan Standard Time)

    Fixes:
      - Replace \do{local*_} globref pattern with named glob string
        (Package::FH::H<n>) in _log_message(), serve_static(), and
        _open_access_log(). Perl 5.005_03 does not support readline/
        print/binmode/close via globref; the named glob string approach
        works on Perl 5.005_03 and all later versions.
      - lib/HTTP/Handy.pm: add missing =head1 AUTHOR section (the author
        line was present but lacked the =head1 heading; MetaCPAN requires
        a proper =head1 AUTHOR section to populate the author sidebar).

1.04  2026-04-04 JST (Japan Standard Time)

    Fixes:
    - t/9050-pod.t: replace G11 implementation with Pod::Checker OO
      interface (Pod::Checker->new / num_errors / num_warnings) and
      split into G11 (errors) + G12 (warnings); plan updated from
      11 to 12 tests per .pm file.
    - t/9050-pod.t: skip G11 Pod::Checker errors check when
      Pod::Checker < 1.51 to avoid false FAILs caused by mis-reported
      errors for valid L</section>, L</"section">, and L<URL> syntax
      on older Perl installations (CPAN Testers FAIL fix).
    - t/9050-pod.t: skip G12 Pod::Checker warnings check when
      Pod::Checker < 1.60 to avoid false FAILs caused by mis-reported
      warnings for valid L<> link syntax on older Perl installations.
    - t/9050-pod.t: fix warnings stub guard to use
      !defined(&warnings::import) form (consistent with other 9xxx
      tests).

1.03  2026-03-24 JST (Japan Standard Time)

    Tests:
    - Added t/lib/INA_CPAN_Check.pm: shared test library providing
      TAP harness, file utilities, MANIFEST helpers, version/META
      parsers, code scanner, and check_A through check_K
      implementations (aligned with DB-Handy 1.07).
    - Added t/9001-load.t: module load, $VERSION, sub-package
      HTTP::Handy::Input, public methods (run/serve_static/etc.),
      and INA_CPAN_Check library export verification.
    - Added t/9010-encoding.t: US-ASCII, trailing whitespace, and
      end-of-file newline checks (replaces t/0007-usascii.t).
    - Added t/9020-perl5compat.t: Perl 5.005_03 syntax checks P1-P14
      covering .pm, .t, and eg/*.pl (replaces t/0008-perl5compat.t;
      adds P13 @-/@+ prohibition and P14 header order check).
    - Added t/9030-distribution.t: MANIFEST, version consistency,
      META integrity, Changes format, Makefile.PL, and test-suite
      consistency (replaces t/0009-cpan_precheck.t categories A-J).
    - Added t/9040-style.t: coding style E and K checks
      (replaces t/0009-cpan_precheck.t categories E/K).
    - Added t/9050-pod.t: POD structure/content G1-G11 including
      VERSION format, TABLE OF CONTENTS completeness, DIAGNOSTICS
      coverage, and Pod::Checker syntax check
      (replaces t/0006-pod.t).
    - Added t/9060-readme.t: README required sections check.
    - Added t/9070-examples.t: eg/ script quality E1-E6
      (no shebang, CVE fix, FindBin, boilerplate order,
      filename comment, Demonstrates section).
    - Added t/9080-cheatsheets.t: doc/ cheat sheet native script,
      section numbering, and [XX] header tag checks.
    - Removed t/0001-load.t: superseded by t/9001-load.t.
    - Removed t/0006-pod.t: superseded by t/9050-pod.t.
    - Removed t/0007-usascii.t: superseded by t/9010-encoding.t.
    - Removed t/0008-perl5compat.t: superseded by t/9020-perl5compat.t.
    - Removed t/0009-cpan_precheck.t: superseded by t/9030-t/9080.

    Fixes:
    - lib/HTTP/Handy.pm: warnings stub now guards with
      !defined(&warnings::import) to suppress "import redefined"
      warnings when multiple modules are loaded in sequence.
    - lib/HTTP/Handy.pm: DIAGNOSTICS =item for "Cannot bind" error
      corrected to E<lt>hostE<gt>:E<lt>portE<gt> form so that the
      G10 DIAGNOSTICS-coverage check passes.
    - t/0005-psgi-env.t: replaced my(undef,...) with array-index
      form for Perl 5.005_03 compatibility (P3 check).

1.02  2026-03-24 JST (Japan Standard Time)

    Documentation:
    - POD =head1 VERSION: corrected from "1.01" to "Version 1.02"
      (aligned with DB-Handy and LTSV-LINQ style).
    - POD =head1 TABLE OF CONTENTS: moved to correct position
      (after SYNOPSIS, before DESCRIPTION); was incorrectly placed
      after SEE ALSO.
    - eg/: removed shebang line (#!/usr/bin/perl) from all four
      eg/*.pl files (consistent with LTSV-LINQ 1.06 style).
    - doc/psgi_cheatsheet.*.txt: all 21 language cheat sheets
      rewritten; MN, MY, BN, HI, KM, KO, NE, SI, TH, TW, ZH, UR
      now use their respective native scripts (Cyrillic, Burmese,
      Bengali, Devanagari, Khmer, Hangul, Sinhala, Thai,
      Traditional/Simplified Chinese, Arabic); FR, TR, VI updated
      with proper diacritics and locale-specific characters.

1.01  2026-03-22 JST (Japan Standard Time)

    New features:
    - _iso_time(): new internal function returns the current local time as
      YYYY-MM-DDTHH:MM:SS using only localtime and sprintf.  Replaces the
      earlier use of POSIX::strftime, removing the POSIX dependency entirely.
    - _init_directories(): called once by run() at server startup.  Creates
      an Apache-like directory layout (logs/, logs/access/, logs/error/,
      run/, htdocs/, conf/) under the current working directory if the
      directories do not already exist.
    - Access log file rotation: in addition to STDERR, each LTSV access log
      line is now written to logs/access/YYYYMMDDHHm0.log.ltsv (10-minute
      rotation).  The filehandle is kept open between requests and reopened
      automatically when the interval changes.
    - Error log file: _log_message() now appends each startup/error message
      to logs/error/error.log in addition to STDERR.

    Robustness fixes:
    - serve_static(): replaced bareword filehandle (local *FH) with a
      lexical filehandle via eval q{open($fh,'<',$file)} on Perl 5.6+ and
      \do{local *_} on 5.005_03.
    - Response header processing: shift(@h) now falls back to '' (was undef).
    - Body joining: join('', @$body) is now guarded by "if @$body".

    Coding style aligned with DB-Handy and LTSV-LINQ:
    - Module header: added Compatible/Platform comment block.
    - use strict/warnings order unified: use strict -> BEGIN{warnings stub}
      -> use warnings; local $^W = 1; -> BEGIN { pop @INC } (DB-Handy style).
    - Section separators changed from # ---...--- (66 chars) to
      ###...### (79 chars) matching DB-Handy.
    - pmake.bat: install target now greps lib/**/*.pm only (DB-Handy style).

    Documentation:
    - REQUIREMENTS: removed POSIX from the module list (no longer used).
    - SERVER STARTUP: added Directory Initialisation and Error Log sections.
    - POD: added DIAGNOSTICS, BUGS AND LIMITATIONS, DESIGN PHILOSOPHY,
      and TABLE OF CONTENTS sections.
    - LICENSE -> COPYRIGHT AND LICENSE (aligned with DB-Handy).
    - AUTHOR: corrected to "INABA Hitoshi E<lt>ina.cpan@gmail.comE<gt>".
    - README: rewritten to DB-Handy structure with COMPATIBILITY (Perl
      5.005_03 philosophy), TARGET USE CASES, and COPYRIGHT AND LICENSE.

    Test suite improvements (knowledge from DB-Handy and LTSV-LINQ):

    Naming and style (from DB-Handy and LTSV-LINQ):
    - Renamed test files to 4-digit zero-padded format (0001-, 0002-, ...).
    - Rewrote functional test harnesses (t/0002-0005) to DB-Handy style:
      ###### header block, $PASS/$FAIL/$T variables, 1-line ok/is/like,
      print "1..N\n" plan, exit($FAIL ? 1 : 0) at end.
    - Added use strict, warnings compatibility stub, CVE-2016-1238
      mitigation, and use FindBin / use lib to all test files.
    - Removed shebang line (#!/usr/bin/perl) from all test files.

    New test files:
    - t/0008-perl5compat.t: Perl 5.005_03 compatibility checks (P1-P12).
    - t/0009-cpan_precheck.t: comprehensive pre-publication check suite
      (categories A-K, 198 tests).
    - t/0010-log.t: 28 tests for _iso_time, _init_directories,
      _open_access_log, and _log_message.
      END block now closes ACCESS_LOG_FH and restores STDERR before
      File::Path::rmtree to avoid "Permission denied" on Windows
      (open filehandles prevent deletion on Windows NTFS).

    Samples and documentation:
    - eg/01_hello_world.pl: minimal PSGI app (routing, query string, env dump).
    - eg/02_static_files.pl: serve_static, cache_max_age, mime_type.
    - eg/03_form_post.pl: POST body, parse_query, multi-value fields,
      Post-Redirect-Get pattern.
    - eg/04_ltsv_viewer.pl: is_htmx, LTSV log parsing, multiple status codes.
    - doc/psgi_cheatsheet.*.txt: PSGI cheat sheets in 21 languages covering
      run() options, $env keys, response format, utility methods, routing
      patterns, and links to the official PSGI specification.

    Additional documentation fixes:
    - POD DEMO section: corrected run command from
      "perl HTTP::Handy.pm" to "perl lib/HTTP/Handy.pm" (distribution
      directory form); added installed form using -MHTTP::Handy.
    - README: added DEMO section with corrected run command.
    - doc/psgi_cheatsheet.*.txt: corrected run command in all 21
      language cheat sheets.
    - POD: added INCLUDED DOCUMENTATION section listing eg/ and doc/ files.
    - POD: added DIAGNOSTICS entry for 'max_post_size' must be a number.
    - POD: TABLE OF CONTENTS now includes SEE ALSO.
    - README: added INCLUDED DOCUMENTATION section.
    - $VERSION declared via use vars (aligned with DB-Handy style).

1.00  2026-02-23 JST (Japan Standard Time)

    - First release on CPAN.
