aboutsummaryrefslogtreecommitdiff
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2026 M. Shulhan <ms@kilabit.info>

= pakakeh.go CHANGELOG
:std_url: https://pkg.go.dev
:sectanchors:
:stylesheet: default, changelog.css
:toc:

This Go module usually released every month, at the first week of the month.

link:CHANGELOG_2025.html[Changelog in 2025].
Changelog for `pakakeh.go` module since v0.59.0 until v0.60.2.

link:CHANGELOG_2024.html[Changelog in 2024^].
This is changelog for `pakakeh.go` module since v0.52.0 until v0.58.1.

link:CHANGELOG_2023.html[Changelog in 2023^].
This is changelog for `pakakeh.go` module since v0.43.0 until v0.51.0.

link:CHANGELOG_2022.html[Changelog in 2022^].
This is changelog for `pakakeh.go` module since v0.33.0 until v0.42.0.

link:CHANGELOG_2021.html[Changelog in 2021^].
This is changelog for `pakakeh.go` module since v0.22.0 until v0.32.0.

link:CHANGELOG_2020.html[Changelog in 2020^].
This is changelog for `pakakeh.go` module since v0.12.0 until v0.21.0.

link:CHANGELOG_2018-2019.html[Changelog from 2018 to 2019^].
This is changelog for `pakakeh.go` module since v0.1.0 until v0.11.0.

Legend,

* 🪵: Breaking changes
* 🌱: New feature
* 🌼: Enhancement
* 💧: Chores


[#v0_62_0]
== pakakeh.go v0.62.0 (2026-04-04)
//{{{

[#v0_62_0__cmd_httpdfs]
=== cmd/httpdfs

==== 🌱 Add option to set base path and shutdown idle duration

The `-base-path` option set the URL prefix for serving HTTP request.

The `-shutdown-idle` option set the duration when server will stop accepting
new connections and shutting down.


[#v0_62_0__lib_dns]
=== lib/dns

==== 🪵 lib/dns: refactoring DoT and DoH to use address instead of port

Using port makes the IP address of DNS-over-TLS (DoT) and DNS-over-HTTPS
(DoH) listen on the same address with UDP.
If we set `ListenAddress` to `0.0.0.0` and TLS termination is handled
by proxy, this cause DoT and DoH will also listen on all
addresses (the ports open to public).


[#v0_62_0__lib_http]
=== lib/http

==== 🌱 Add BasePath to the ServerOptions

The BasePath allow server to serve HTTP from custom prefix, other than "/".

Each request that server received will remove the BasePath first
from the [http.Request.URL.Path] before passing to the handler.
Each redirect that server sent will add the BasePath as the prefix
to redirect URL.

Any trailing slash in the BasePath will be removed.

==== 🌱 Implement server auto shutdown when idle

In the `ServerOptions`, we add option `ShutdownIdleDuration` when set to
non-zero value it will start a timer.
When the timer expired, the server will stop accepting new connection and
then shutting down.

This allow de-activating HTTP server when no connections received after
specific duration to reduce the system resources.

==== 🌼 lib/http: fix possible data race in SSE connection

When server's handler call Write or WriteRaw, there is possibility that
the worker for keeping the connection alive also call Write at the same
time, which cause the data race.


[#v0_62_0__lib_paseto]
=== lib/paseto

==== 🪵 Move paseto v2 under sub directory "v2"

There are new versions of paseto standard: version 3 and version 4.
To minimize conflicts in the future, we move the old implementation of
paseto v2 to sub directory "v2" with package name "pasetov2".

==== 🌱 lib/paseto/v4: new package that implements Paseto version 4

paseto/v4 provides a simple, ready to use, opinionated
implementation of Platform-Agnostic SEcurity TOkens (PASETO) version 4
as defined in
https://github.com/paseto-standard/paseto-spec/blob/master/docs/01-Protocol-Versions/Version4.md[paseto-v4].


[#v0_62_0__lib_uuidv7]
=== 🌱 lib/uuidv7

New package that implements UUID version 7.

The uuidv7 package provides type UUIDv7 as the container for UUID
version 7 that satisfy the [database/sql], [encoding/gob], and
[encoding/json].

The implementation follow RFC 9562.


//}}}
[#v0_61_0]
== pakakeh.go v0.61.0 (2026-02-09)
//{{{

[#v0_61_0__all]
=== all

==== 💧 all: convert license and copyright to use SPDX identifiers

With the help of
https://kilabit.info/project/spdxconv/[spdxconv]
tool, we able to bulk update all files license and copyright format to
comply with SPDX formats.


[#v0_61_0__cmd_https]
=== cmd/httpdfs

==== 🌼 cmd/httpdfs: implement systemd socket activation

The httpdfs program now can be activated using
https://man.archlinux.org/man/systemd.socket.5[systemd.socket(5)].


[#v0_61_0__lib_dns]
=== lib/dns

==== 🌼 lib/dns: use separate ServeMux for handling DoH

Using the [http.DefaultServeMux] will cause panic when the server
restarted manually using Stop-Start flow.

==== 🌼 lib/dns: skip caching empty answer only for query type A

Previously, we did not store response with empty RR answer for all record
types.
Meanwhile, some domains still does not have AAAA(28) and HTTPS(65) records
set, but browser will requesting them.
So, to minimize traffic for those query we skip caching only for query type
A and cache the rest of types.

==== 🌼 lib/dns: remove DebugLevelDNS

The DebugLevelDNS log the error on DNS level, for example empty answer,
error on name, class not implemented, refused; which is now on by
default.

==== 🌱 lib/dns: add option to set hook on server when receiving answer

The hook function, OnAnswerReceived, will be triggered when server
receive valid answer but before its put to caches.

==== 🌱 lib/dns: add method to set TTL on Message

The SetTTL method set all RRs answer time to live.

==== 🌼 lib/dns: print the answer TTL in DebugLevelCache

The log level cache changed to the following format,

----
... {MSG_ID QNAME TYPE TTL} ...
----

where MSG_ID is the message ID, QNAME is the question name, TYPE is the
type of question, and TTL is the time-to-live of the answer.

==== 🌼 lib/dns: simplify log message for DebugLevelCache

For each logged request, there should be one line of response logged,
success or fail.

This changes remove redundant log "^" (request forwarded) and
"~" (answer is expired).
The final log would be only "+" (new answer cached), or "#" (answer
updated), or "!" (error).

==== 🌼 lib/dns: increase the client default timeout from 6 to 60 seconds

The 6 seconds timeout will works only on fast, stable connection.

On some environment with bad network connection, it will cause I/O timeout
during recv and this affect the whole internet connections, like
browsing.
Since the browser wait for domain to be resolved but it does
not get the response, it send another query.
The next query also got timeout again.

Increasing to 10-30 seconds also does not help on that environment.
After some tests, 60 seconds is the lower timeout limit that reduce
the I/O timeout.

It is better that we receive the response and store it to caches, so
the next query can be handled quickly, rather than timeout and retrying
with the same error.

This method accept second paramter "format", default to
'%h,%at,%an,%ae,%s' which print short hash, author commit timestamp,
author name, author email, and subject; respectively separated by comma.


[#v0_61_0__lib_git]
=== lib/git

==== 🌱 lib/git: expose the API for IgnorePattern

The IgnorePattern is not exclusive to git only. Some program, like
REUSE, use the same pattern in the REUSE.toml path configuration.

==== 🌱 lib/git: add method LogFollow

The LogFollow method return history of single file `path`, following
rename.

==== 🌱 lib/git: add Git type with method IsIgnored

The Git type is for working with single git repository.

The [Git.IsIgnored] method is to check if the `path` is ignored by
git.
This is processed by matching it with all of the pattern in the
".gitignore" file from the path directory and its parent until the
root of Git repository.

The Git type implement Equaler interface.
The Equaler interface provide the method Equal that when implemented
can be used to compare two instances of struct.

==== 🌱 lib/git: implement Gitignore

Gitignore is a type that represent ".gitignore" file.

There are two ways to populate Gitignore, by using [LoadGitignore]
function, or by using [Gitignore.Parse] method.

After the Gitignore created, one can check if a path is ignored by
using [Gitignore.IsIgnored] method, relative to the Gitignore directory.


[#v0_61_0__lib_http]
=== lib/http

==== 🪵 lib/http: change HandleFS redirect status code to 301

According to MDN
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Redirections[Redirections in HTTP]
the HTTP status 302 Found use case is for "Web page (that) is temporarily
unavailable for unforeseen reasons.".

This probably to re-route the page until the original page is fixed.
While HTTP status 301 is for "Reorganization of a website.".

Since the redirection in HandleFS only happen when user access directory
without slash, we should make it permanent.

==== 🌼 lib/http: set HandleFS to always end with slash "/"

Previously, if request to directory does not end with "/", the HTTP
server will return the index.html of that directory.
This cause relative link inside the index.html broken when visited from
browser.

This changes make the request to directory always end with "/" by
redirecting the request with status 303 Found.

==== 🌱 lib/http: add field Listener to ServerOptions

The field Listener allow user to pass [net.Listener] for accepting new
connection using [http.Serve] or [http.ServeTLS].

==== 🪵 lib/http: add second return value, statusCode, to FSHandler

Non-zero status code indicates that the function already response
to the request, and the server will return immediately.

Zero status code indicates that the function did not process the request,
it is up to server to process the returned node `out`.


[#v0_61_0__lib_ini]
=== lib/ini

==== 🌼 lib/ini: improve error message when parsing variable name

Display the invalid character in the error message with quote, so space
can detected.
Also, export the error variable so external caller can detect it using the
variable.


[#v0_61_0__lib_os]
=== lib/os

==== 🌱 lib/os: add function IsBinaryStream

The IsBinaryStream return true if the content has more than 75%
non-printable characters, excluding spaces.

While at it, replace the body of IsBinary with it and update the
test cases to use the internal files.


[#v0_61_0__lib_systemd]
=== lib/systemd

==== 🌱 lib/systemd: new package for socket-based activation

The `lib/systemd` package implement function `Listeners` that return list of
file descriptor as [net.Listener], that enable program to run with
systemd.socket(5) based activation.


[#v0_61_0__lib_test]
=== lib/test

==== 🌼 lib/test: ignore line prefixed with "//"

The first line in test data file may contains line prefixed with "//"
as comment.
The use case is for license and copyright lines.

==== 🌱 lib/test: implement method ExtractInput on Data

Given the path to directory `destDir`, create all of the
[test.Data.Input] with key as its file name.

If the input name contains "/", the path before the base name will be
created along with its parent as long as it is under the `destDir`.

For example, given input name "a/b/c.txt", it will create path "a/b/"
inside `destDir` first, followed by file "c.txt" inside that path.

==== 🌼 lib/test: export the constant for default data file name suffix

Also, fix typo on the LoadDataDir regarding suffix by replacing it with
the exported constant.

//}}}