<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pakakeh.go, branch v0.61.0</title>
<subtitle>Collections of packages and tools for working with Go programming language.</subtitle>
<id>http://git.kilabit.info/pakakeh.go/atom?h=v0.61.0</id>
<link rel='self' href='http://git.kilabit.info/pakakeh.go/atom?h=v0.61.0'/>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/pakakeh.go/'/>
<updated>2026-02-09T05:39:02Z</updated>
<entry>
<title>Release pakakeh.go v0.61.0 (2026-02-09)</title>
<updated>2026-02-09T05:39:02Z</updated>
<author>
<name>Shulhan</name>
<email>ms@kilabit.info</email>
</author>
<published>2026-02-08T15:17:33Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/pakakeh.go/commit/?id=c516c2c44df0074f43ff084c7e9e4cf12909dad1'/>
<id>urn:sha1:c516c2c44df0074f43ff084c7e9e4cf12909dad1</id>
<content type='text'>
=== all

💧 all: convert license and copyright to use SPDX identifiers

With the help of spdxconv tool, we able to bulk update all files license
and copyright format to comply with SPDX formats.

=== cmd/httpdfs

🌼 cmd/httpdfs: implement systemd socket activation

The httpdfs program now can be activated using systemd.socket(5).

=== 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.

=== 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.

=== lib/http

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

According to MDN 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.

=== 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.

=== 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.

=== 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.

=== 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.
</content>
</entry>
<entry>
<title>go.mod: update all dependencies</title>
<updated>2026-02-08T16:05:59Z</updated>
<author>
<name>Shulhan</name>
<email>ms@kilabit.info</email>
</author>
<published>2026-02-08T16:05:40Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/pakakeh.go/commit/?id=ef59171adc5d1c7099d7300d694f6e4cd510615d'/>
<id>urn:sha1:ef59171adc5d1c7099d7300d694f6e4cd510615d</id>
<content type='text'>
</content>
</entry>
<entry>
<title>_doc: split the changelog for 2025</title>
<updated>2026-02-08T11:46:23Z</updated>
<author>
<name>Shulhan</name>
<email>ms@kilabit.info</email>
</author>
<published>2026-02-08T11:46:23Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/pakakeh.go/commit/?id=7461efda2efa7eacf92376188ee0d7307e05f73e'/>
<id>urn:sha1:7461efda2efa7eacf92376188ee0d7307e05f73e</id>
<content type='text'>
While at it, use consistent title in the changelog files.
</content>
</entry>
<entry>
<title>_doc: remove ":sectlinks:" attribute from adoc files</title>
<updated>2026-02-08T11:34:11Z</updated>
<author>
<name>Shulhan</name>
<email>ms@kilabit.info</email>
</author>
<published>2026-02-08T11:34:11Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/pakakeh.go/commit/?id=9766d6417c9e87b8e34524836cbcd2622834b1c0'/>
<id>urn:sha1:9766d6417c9e87b8e34524836cbcd2622834b1c0</id>
<content type='text'>
The sectlinks attribute cause the sections header become
hyperlinks, which is misleading since it is not link to other
page or sites.
</content>
</entry>
<entry>
<title>_doc: fix typo on RFC 4686 "Analysis of Threats Motivating DKIM"</title>
<updated>2026-02-05T17:19:19Z</updated>
<author>
<name>Shulhan</name>
<email>ms@kilabit.info</email>
</author>
<published>2026-02-05T17:19:19Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/pakakeh.go/commit/?id=13f867b65e465a238123615af63ff39e0836049a'/>
<id>urn:sha1:13f867b65e465a238123615af63ff39e0836049a</id>
<content type='text'>
</content>
</entry>
<entry>
<title>lib/http: change HandleFS redirect status code to 301 Moved Permanently</title>
<updated>2026-02-05T12:29:05Z</updated>
<author>
<name>Shulhan</name>
<email>ms@kilabit.info</email>
</author>
<published>2026-02-05T12:29:05Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/pakakeh.go/commit/?id=fad13afac8b51e61ad5465c88021895a95403a15'/>
<id>urn:sha1:fad13afac8b51e61ad5465c88021895a95403a15</id>
<content type='text'>
According to MDN [Redirections in HTTP], the HTTP status 302 Found use
case is

	The Web page 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.

[Redirections in HTTP]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Redirections
</content>
</entry>
<entry>
<title>lib/http: handle file system with canonical directory end with slash "/"</title>
<updated>2026-02-05T12:26:29Z</updated>
<author>
<name>Shulhan</name>
<email>ms@kilabit.info</email>
</author>
<published>2026-02-05T12:26:29Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/pakakeh.go/commit/?id=3734420eec485bca8c18243741e1ad2a683515b7'/>
<id>urn:sha1:3734420eec485bca8c18243741e1ad2a683515b7</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>cmd/httpdfs: fix call to log.Fatal</title>
<updated>2026-02-05T11:54:20Z</updated>
<author>
<name>Shulhan</name>
<email>ms@kilabit.info</email>
</author>
<published>2026-02-05T11:54:20Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/pakakeh.go/commit/?id=f40153cfb1cd859538aeaad17f0a243b4ef0c52c'/>
<id>urn:sha1:f40153cfb1cd859538aeaad17f0a243b4ef0c52c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>lib/os: fix IsBinary that return true if file size less than 1024</title>
<updated>2026-02-03T10:22:23Z</updated>
<author>
<name>Shulhan</name>
<email>ms@kilabit.info</email>
</author>
<published>2026-02-03T10:22:00Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/pakakeh.go/commit/?id=128497e265bab37db8f2b1385f216342968c9854'/>
<id>urn:sha1:128497e265bab37db8f2b1385f216342968c9854</id>
<content type='text'>
If file size less than half of 1024, the rest of bytes will be `0` and it
will counted as binary character.
</content>
</entry>
<entry>
<title>cmd/httpdfs: implement systemd socket activation</title>
<updated>2026-02-02T14:05:15Z</updated>
<author>
<name>Shulhan</name>
<email>ms@kilabit.info</email>
</author>
<published>2026-02-02T14:05:15Z</published>
<link rel='alternate' type='text/html' href='http://git.kilabit.info/pakakeh.go/commit/?id=ca3002fb7041a863600042f013e12faf73caf227'/>
<id>urn:sha1:ca3002fb7041a863600042f013e12faf73caf227</id>
<content type='text'>
The httpdfs program now can be activated using systemd.socket(5).
</content>
</entry>
</feed>
