0.52.0 (2025-11-10)

+ Event handlers can now be in a hierarchy. If calling remove_handler on a handler that has children, they are removed as well.
+ MSW: Added fz::async_pipe
+ Add operator< and operator== for strtokenizer
+ Added fz::read_file overload accepting a filename
- Fixes to mutex debugging to fix destruction order issues on program exit
- Certificate verification: Display friendly error message in case of GNUTLS_CERT_INVALID_OCSP_STATUS

0.51.1 (2025-07-31)

+ Added fz::get_final_link_target
- *nix: Fixed reporting the type of file if following symlinks in fz::local_filesys::get_file_info

0.51.0 (2025-07-16)

+ Added nocreate flag to fz::file::open::creation_flags, if set only files that already exist can be opened
+ Added sha1 and sha512 to fz::hash_accumulator
+ Added update_uint32_be and update_with_length to fz::hash_accumulator
+ *nix: fz::socket can now be used to connect to Unix Domain Sockets
+ Added flag to fz::uri to assume an authority when parsing schemless URIs
+ fz::get_file_info and fz::local_filesys::set_modification_time now return fz::result
- Improvements to timer handling if using event loops with the threadless flag

0.50.0 (2025-03-26)

+ Added 'fresh' fz::file::open::creation_flags. If set, file creation fails if a file with the same name already exists
+ Added fz::get_digest_size for hash algorithms
+ Impersonation changes for working with Active Directory users
+ Transparent fz::less_/equal_insensitive_ascii comparators
+ Generalized fz::starts_/ends_with
- fz::socket_base::close is now public
- Fixes to mutex-debugging functionality
- Fixes to fz::is_pem heuristic 

0.49.0 (2024-10-15)

+ Added fz::to_integral_o that returns an optional
+ If mutex-debugging is enabled, attempts to destroy a still locked mutex are now detected
+ fz::file can now also be oppened in append mode
+ MSW: Added users, authenticated_users and system entities to security_descriptor_builder
- fz::to_integral now verifies that the value fits into the return type instead of silently truncating

0.48.1 (2024-07-09)

- Allow comparing strtokenizer::iterator with each other
- MSW: fz::recursive_remove now exposes calls SHFileOperations, as the caller might need special steps to ensure modality

0.48.0 (2024-06-26)

+ fz::percent_decode can now optionally treat plus as space
+ Added file::get_modification_time
- EROFS is now mapped to fsresult::noperm
- fz::aio_waiter has been removed due to thread-safety issues
- *nix: Only link with -ldl if required by dlsym
- Fixed error code if no parent can be found during mkdir

0.47.0 (2024-04-15)

+ PKCS#11 support, provided GnuTLS has been compiled with PKCS#11 support enabled
- Added parameter to fz::remove_dir that allows returning an error if the directory did not exist
- Add logging of aio reader/writers cannot be opened, fix return value of reader when trying to read nothing
- HTTP: Delay sending subsequent requests after having received a response with "Connection: close" set
- Listen sockets are now created with the SO_REUSEADDR (SO_EXCLUSIVEADDRUSE on Windows) flag set
- Added cert_type::codesign as key purpose to certificate request and creation functions in fz::tls_layer

0.46.0 (2024-02-06)

+ fz::process: Add io redirection mode that excluded stderr
+ fz::remove_file and remove_dir now take additional parameter and return fz::result
+ Added transitional fz::file::read2 and fz::file::write2 returning fz::rwresult, old read/write have been marked deprecated
- HTTP: Fix redirect if "Connection: close" header is set

0.45.0 (2023-10-11)

+ fz::hash_accumulator now also works with hmac_sha256
+ Added is_digest and digest_size to fz::hash_acumulator
+ MSW: Added function to delete registry values
- Fixed a crash and a stall in the HTTP client

0.44.0 (2023-06-28)

+ Exportable hash accumulator state
+ Add for RSA key support for JWS
+ JWT creation
+ Conversion functions from X.509 private keys to JWK
- Added logging when certificate is untrusted by system trust store

0.43.0 (2023-05-26)

+ Added fz::tls_layer::generate_cert_from_csr
- fz::event_loop performance improvements when timers are in use

0.42.2 (2023-04-25)

- Further HTTP client fixes

0.42.1 (2023-04-21)

- Small HTTP client improvements to force IPv4/IPv6 for new connections, add a header count limit, and to make a buffer pool optional

0.42.0 (2023-04-12)

+ Added an HTTP client
- Sources are now distributed in a .tar.xz
- buffer_writer now clears the buffer when opened
- Fixes and performance improvements for fz::xml::parser
- *nix: fz::file::size() now returns -1 on character devices

0.41.1 (2023-02-22)

- Fixed a crash signalling aio waiters
- Added listen_socket::from_descriptor

0.41.0 (2023-01-12)

+ Added fz::xml::parser and fz::xml::namespace_parser
+ Added fz::is_valid_utf8
+ Added fz::utf16le_to_utf8_append and fz::utf16be_to_utf8_append

0.40.0 (2022-12-12)

+ Added fz::unicode_codepoint_to_utf8_append
+ Added fz::strtokenizer
+ Added fz::check_certificate_status

0.39.2 (2022-10-11)

- Fixed removing aio_waiters/event_handlers from aio_waitable
- Fixed start offset in view_reader
- Fix buffer_writer not releasing added buffers

0.39.1 (2022-09-12)

- MSW: Fixed a possible hang in fz::process:kill

0.39.0 (2022-09-05)

+ Added readwrite mode to fz::file.
+ MSW: Added fz::dll and fz::shdlls glue
+ Added fz::ascii_layer
- *nix: Fixed mmap error handling in fz::aio_buffer_pool
- Fixed a potential deadlock in the aio code
- Fixed an issue with calling conventions on 32bit Windows
- MSW: fz::datetime::get_tm now works for dates past Y2K38 on toolchains with 32bit time_t
- MSW: Fixed an error reading from fz::process

0.38.1 (2022-07-20)

+ fz::aio_waitable now also accepts event handlers in addition to aio_waiter
- Split fz::process::kill into separate stop and kill functions

0.38.0 (2022-07-08)

+ Added readers and writers for asynchronous disk I/O operating on a buffer pool
+ Added fz::current_username()
+ Added fz::event_handler::stop_add_timer
+ Added overload for fz::event_handler::add_timer that takes a deadline
+ Added fz::file::set_modification_time
+ Added fz::get_network_interfaces
+ *nix: fz::socket can now accept Unix-domain sockets, added fz::socket::send_fd and fz::socke::read_fd
- *nix: When impersonating, limit supplementary groups to NGROUPS_MAX

0.37.2 (2022-04-29)

+ Added a null_logger that doesn't do anything
- MSW: fz::mkdir with restricted permissions now uses inheritable ACLs
- MSW: Minor performance improvements reading from fz::process and explicit cancellation of pending I/O when killing child processes.

0.37.1 (2022-04-08)

+ Added convenience functions ot fz::json
- MSW: Fixed spawning fz::process with blocking communication

0.37.0 (2022-04-01)

+ *nix: password-less impersonation can take an optional group
+ Added demo https client showcasing usage of fz::socket and fz::tls_layer
+ Added some compile-time checks for fz::sprintf arguments
+ MSW: Added fz::registry
+ Added a way to use non-blocking read/write with fz::process
- Added fz::logger_interface::log_u which assumes string arguments are in UTF-8 as opposed to the character set used by the current locale
- Disallow spawning additional threads while fz::thread_pool is in the process of being destroyed
- *nix: poll() is now mandatory, the select() based socket event loop has been removed
- Simplified fz::socket implementation through use of internal fz::poller

0.36.0 (2022-02-02)

+ Added parameter to tls_layer::set_alpn to control which peer has priority over which ALPN is chosen.
+ Added fz::hmac_sha1
+ Mutex debugging framework to detect locking order inversions that may lead to deadlocks
+ Add additional io_redirect mode to fz::process_spawn where the parent-side handles for stdin/out/err are always closed
- fz::json: Handle object members with empty string as name
- Minor performance improvements to removing timers and to spawning processes

0.35.0 (2021-12-08)

+ *nix: Added fz::forkblock which can be used to safely set FD_CLOEXEC on descriptors even if the system lacks SOCK_CLOCKEXEC, MSG_CMSG_CLOEXEC, pipe2 or accept4
+ macOS: Impersonation support
+ Added fz::tls_layer::set_unexpected_eof_cb, in some situations it may be desirable that unexpected closure is not reported as a hard errror
- Added various convenience overloads for fz::buffer
- Performance improvement for fz::json::to_string

0.34.2 (2021-10-26)

+ fz::file::open now returns fz::result
- fz::tls_layer: Additional fixes for trust path extration
- MSW: fz::local_filesys::get_next_file now handles directory contents returned by the kernel in oversized buffers with embedded nulls

0.34.1 (2021-10-19)

- *nix: Handle supplementary groups when impersonating
- *nix: fz::recv_fd now sets the MSG_CMSG_CLOEXEC flag
- *nix: fz::local_filesys::get_link_target now handles link targets larger than 1024 bytes
- MSW: Restrict DLL search path for system DLLs to the system32 directory
- fz::tls_layer: Fixed how trust path extration interacts with CRLs

0.34.0 (2021-10-11)

- MSW: Load shell32.dll and ole32.dll on-demand at runtime, it is not available in all environments
- Made fz::local_filesys movable

0.33.0 (2021-09-29)

+ MSW: Add local_filesys::begin_find_files overload accepting a directory HANDLE
+ If peer certificate chain is trusted by the system trust store, tls_session_info::get_certificates now returns the actual path to the trust anchor, use tls_session_info::get_peer_certificates to get the peer certificates as received by the server. GnuTLS 3.7.0 or later is required.
- JSON: Correctly handle \u-encoded UTF-16 surrogate pairs

0.32.0 (2021-09-14)

+ MSW: Impersonation support
- Allow more direct control over session ticket/PSK generation under TLS 1.3, requires GnuTLS 3.6.14 or later
- Ensure an error is returned if accepting a socket fails
- Fixed appending to fz::buffer

0.32.0-beta1 (2021-08-30)

+ *nix: Impersonation support
+ *nix: Sending of file descriptors over Unix Domain Sockets
* nix: Add local_filesys::begin_find_files overload accepting a directory file descriptor
+ Allow creating fz::file from a file descriptors/handle, add function to detach the descriptor/handle
+ Added fz::datetime::operator>=
+ Added fz::duration::absolute()
- fz::sprintf no longer crashes on x and X conversion specifiers if a negative signed integer is passed as argument
- Replace std::random_device as the C++ standard allows it to not be random
- JSON: Fixed crash if assigning values from nested values
- JWS: Fixed memory leak and padding of signature components

0.31.1 (2021-08-09)

+ Added iterator for JSON arrays
- *nix: SIGPIPE is now set to SIG_IGN the first time a pipe or socket gets created
- Handle empty search string in replace_subscripts

0.31.0 (2021-07-28)

+ Added simple JSON parser
+ Added basic JWS generator
- Made fz::file movable
- Fixed empty creation_flag for fz::file if other flags are also passed

0.30.0 (2021-07-09)

+ Added a flag to fz::file::creation_flags to create files with permissions only granting the current user and administrators access
+ Added mkdir_permissions flags to fz::mkdir

0.29.0 (2021-07-02)

+ Added fz::tls_layer::set_min_tls_ver and for testing purposes set_max_tls_ver
+ The TLS layer now also supports server-side session resumption with TLS <= 1.2 clients not supporting session tickets
+ Added fz::rename_file
+ MSW: Added libfilezilla/glue/windows.hpp to set proper defines before including windows.h
+ Added fz::move_assign_through_move_constructor for classes that depend on normal destruction order even on move assignment
- Fixed memory leak in fz::tls_layer::set_alpn
- IPv6 listen sockets are now always created with IPV6_V6ONLY to unify behavior across platforms
- Fixes for issues found by --socketdebug
- Fixed warnings when bool arguments are passed to fz::sprintf
- Fixed warnings in fz::to_integral<bool>

0.28.0 (2021-05-03)

+ Added fz::hostname_lookup
+ Added fz::datetime::set_rfc3339
+ Added fz::load_certificates and fz::load_certificates_file
+ Added fz::base64_encode_append
- Moved some common functionality shared by multiple layers to socket_layer itself
- Fixed a crash with older versions of GnuTLS if the system trust store cannot be loaded

0.27.1 (2021-03-15)

- Fixed a socket event sequencing invariant violation in tls_layer
- Fixed query_string constructor leaving object in undefined state if set fails
- Fixed arguments passed from the templated equal_constime helper

0.27.0 (2021-03-04)

+ Added fz::normalize_hypens to replace all hyphen-like characters in a string with the good old hyphen-minus
+ Added fz::pbkdf2_hmac_sha256
+ Added visibility_helper.hpp to simplify exporting symbols in shared libraries
+ Added fz::compound_rate_limited_layer to which multiple rate limiters can be dynamically added/removed
+ Added redirect_io parameter to fz::process::spawn
+ Added --enable-socketdebug configure argument to check for invariant violation when handling socket events
+ Added a optional preamble to server_handshake that is sent after initializing the session, but before the SERVER_HELLO
- Various fixes to socket event retriggering if socket_interface::set_event_handler is used
- Fixed a nullpointer dereference in fz::tls_layer if a hostname is set prior to creating a session

0.26.0 (2020-12-17)

+ Added fz::buffer::capacity()
+ fz::buffer::append now also accepts single characters and std::vector
+ Added fz::nonowning_buffer
+ MSW: Added fz::process::handle()
+ *nix: Allow passing extra file descriptors to child processes
+ fz::to_wstring_from_utf8 now accepts std::string_view and fz::buffer
+ fz::replace_substrings and fz::replaced_substrings now accept string views and single characters
- Reset bucket data if it gets removed from a rate_limiter

0.25.0 (2020-10-13)

+ Added fz::invoker to asynchronously call functions to run in a specific thread independent of the caller's thread
- Added additional checks to fz::buffer to leave the buffer in a valid state in out-of-memory situations and to prevent mis-use
- Detect a particular socket buffer tuning issue under Linux where setting a receiver buffer size shrinks the window scale factor
- Reordered a few data members to reduce the amount of structure padding due to alignment

0.24.1 (2020-08-27)

- fz::to_integral can now handle strongly typed enum return types

0.24.0 (2020-08-21)

+ Added fz::equal_consttime
- fz::sprintf now works corrcetly if arguments are passed as (w)string_view

0.23.0 (2020-07-07)

+ Added reader/writer locks
- fz::mkdir can now return the the longest created path in case of partial failures

0.22.0 (2020-05-12)

+ Added a flag to fz::file to allow creation of files with permissions only granting the current user access
+ Added fz::mkdir to create local directories, optionally recursive and with permissions to only grant the current user access to the final directory
- MSW: Improvements handling directory reparse points
- Lengthen partial certificate chains in fz::tls_info to include any found trust anchor if using the system trust store
- Mark self-signed certificates in the in fz::x509_certificate
- Fix constructing fz::uri from default-constructed string_view

0.21.0 (2020-04-20)

+ macOS: fz::spawn_detached_process can now start application bundles
+ Changed arguments of fz::local_filesys::get_next_file to be consistent with fz::local_filesys::get_file_info
- Improved error detection for fz::spawn_detached-process on *nix systems that support the pipe2 syscall with O_CLOEXEC

0.20.2 (2020-03-10)

+ Add encrypt_key and decrypt_key to fz::symmetric key
- fz::datetime::set_rfc822 now parses the zone offset
- Removed unneeded asserts from format.hpp

0.20.1 (2020-02-24)

- Fix potential crash after removing the last speed limit bucket
- TLS: Fix reported key exchange algorithm and improve details

0.20.0 (2020-02-14)

+ Added fz::symmetric_key
+ Added itertions parameter to fz::private_key::from_password
+ Added fz::base32_encode and fz::base32_decode
+ Unified all decode functions to always return a vector, added alternatives returning string with a _s suffix in the function name
+ Changed equal_insensitive_ascii to take (w)string_view

0.19.3 (2019-12-19)

- Rate limiting: Fix a divide by zero when distributing overflow

0.19.2 (2019-12-19)

+ Rate limiting: Added debt repay mechanism to bucket removal
- *nix: Fix returned permissions in fz::local_filesys::get_file_info/get_next_file

0.19.1 (2019-11-15)

+ Return error information to fz::local_filesys::begin_find_files
- Fix for version.hpp not getting installed

0.19.0 (2019-11-07)

+ Addded rate limiting code and a new rate-limited socket layer
+ Added fz::mutex::try_lock
+ Implemented libtool's library versioning scheme for shared library builds of libfilezilla

0.18.2 (2019-09-16)

+ Added operator== and != to fz::uri

0.18.1 (2019-08-14)

+ Added fz::buffer::resize

0.18.0 (2019-08-02)

+ Added fz::spawn_detached_process
+ Add operator+ to fz::duration
+ *nix: If available, use eventfd instead of a self-pipe
+ fz::to_integral and fz::hex_decode now work with string literals
+ Added fz::listen_socket::fast_accept that only returns a descriptor instead of a fully-initialized fz::socket for use in a tight accept-and-dispatch loop
+ Functions in libfilezilla/iputils.hpp now take string_view as arguments
+ Added fz::socket::set_flags which can atomically enable or disable flags
- fz::socket not returns an error instead of silently failing in case of file descriptor exhaustion
- Fix socket errors sometimes not being forwarded in fz::tls_layer when when writing fails in the underlying layer
- Fix double-closing of socket descriptios if connection establishment fails
- fz::tls_layer now fails the handshake instead of waiting indefinitely if started on a layer that has progressed passed the connected state
- Small compile-time improvements to fz::sprintf

0.17.1 (2019-06-21)

+ Added support for detached signatures
- Fixed crash if using the system trust store

0.17.0 (2019-06-17)

+ libfilezilla now requires C++17
+ Changed a lot of functions to use std::string_view
+ Added fz::socket_layer as base class for layers on top of sockets
+ Added fz::tls_layer, a Transport Layer Security layer, requiring GnuTLS 3.5.7 or later
+ Added fz::translate for gettext-style translatable strings. GNU Gettext is now a built-time (but not runtime) dependency
+ Added fz::bitscan and fz::bitscan_reverse to get the index of least and most significant bit set
+ Added fz::logger_interface as a base for logging system
- *nix: Small speed-up of fz::local_filesys through the use of fstatat()

0.16.0 (2019-04-21)

+ Add fz::socket
+ Add operator*= to fz::duration
+ fz::event_loop can now also be created using fz::thread_pool or threadless.
- fz::async_task now releases the thread back to the pool immediately when the task has completed without waiting for the join
- *nix: Fix file descriptor leaks on exec()

0.15.1 (2018-11-22)

+ Add argument to fz::strtok to return empty tokens
- Fix compatibility issue with Nettle < 3.3
- Fix fz::random_bytes on MinGW
- Fix memory leak in fz::buffer

0.15.0 (2018-10-19)

+ libfilezilla now depends on Nettle >= 3.1
+ Added fz::sha512, fz::sha256, fz::sha1 and fz::md5 hash functions
+ Added fz::hash_accumulator
+ Added fz::hmac_sha256 HMAC function
+ Added asymmetric encryption scheme using X25519
+ Added signature scheme using Ed25519
- Changed and documented semantics of the return value of fz::remove_file, removing a non-existing file is not an error

0.14.0 (2018-10-04)

+ Added fz::equal_insensitive_ascii
+ Added insensitive_ascii parameter to fz::starts_with and fz::ends_with
- Fixed namespace of to_wstring in wx glue

0.13.2 (2018-09-21)

- Fix regression in fz::shared_value::clear
- Fix parsing of URIs without path

0.13.1 (2018-09-10)

+ Made fz::scoped_lock movable
- Fix a few compiler warnings

0.13.0 (2018-07-16)

+ Add bool return value to replace_substrings to indicate whether something has been replaced.
+ fz::sprintf: Added %c format specifier
- MSW: Work around problematic DLL export of templates, timers now work if libfilezilla has been built as DLL

0.12.3 (2018-06-08)

+ Event handlers can now removed themselves while inside a callback
+ Added fz::query_string::pairs()

0.12.2 (2018-05-05)

+ Added parameters to base64_encode to control alphabet and padding
+ Improved performance of less_insensitive_ascii
+ *nix: Faster conversion between UTF-8 and wchar_t strings. 

0.12.1 (2018-02-23)

+ Added fz::buffer::operator== and operator!=
- Fixed bug in fz::buffer::get(size_t)

0.12.0 (2018-02-16)

+ Added fz::datetime::operator bool
+ Added fz::datetime::get_rfc822 and fz::datetime::set_rfc822

0.11.2 (2018-01-05)

+ Added fz::starts_with and fz::ends_with
- Fix usage of delete in the fz::buffer destructor

0.11.1 (2017-10-30)

+ Added fz::file::fsync() to sync data to disk

0.11.0 (2017-09-29)

+ Add fz::buffer class
- *nix: fz::process::spawn no longer calls async-signal-unsafe functions between forking and calling execv in the child.

0.10.1 (2017-08-14)

- MSW: Improve handling of reparse points in fz::local_filesys

0.10.0 (2017-07-09)

+ Added fz::percent_encode and fz::percent_encode
+ Added fz::uri and fz::query_string
+ Added fz::less_insensitive_ascii for case-insensitive strings in maps
- Moved encoding functions from string.hpp to encode.hpp
- Use pkg-config instead of cppunit-config to look for cppunit.

0.9.2 (2017-05-25)

+ Added fz::random_bytes to obtain a vector of the passed size of uniformly distributed random bytes
+ Added fz::ltrim and fz::rtim
+ Added parameter to trim functions which characters to trim
+ It is now possible to detach threads from async_task

0.9.1 (2017-02-20)

+ Added a small helper function to fz::file to get the current position in the file
+ Added another version of fz::to_wstring_from_utf8 that takes a char buffer + length
- Fixed extraction of single-character tokens in fz::strtok

0.9.0 (2016-11-28)

+ Added parameter to fz::to_integral to specify which value is returned on error.
+ Added fz::remove_file
+ Added fz::hex_encode and fz::hex_decode

0.8.0 (2016-10-25)

+ Added fz::str_toupper_ascii to complement fz::str_tolower_ascii
+ Added fz::trim and fz::trimmed for removing leading and trailing whitespace from string
+ Added fz::str_is_ascii
- Fixed zero-padding for x and X string format conversion specifiers

0.7.1 (2016-10-03)

- OS X: Work around a nasty bug in XCode where programs explicitly compiled for older versions of OS X were silently pulling in features exclusive to the new version, resulting in crashes at runtime
- MSW: Fix detection of thread creation failures

0.7.0 (2016-09-24)

+ Add fz::base64_decode and fz::base64_encode
+ Add fz::strtok string tokenizer
+ Added non-throwing fz::to_integral
+ Implemented + (always sign) and - (left align) flags for fz::sprintf

0.6.1 (2016-07-27)

- Fix UTF-8 conversion functions and added a testcase

0.6.0 (2016-07-20)

+ Add fz::sprintf, a safe replacement for for the C sprintf function

0.5.3 (2016-06-20)

+ Add fz::replace_substrings to search and replace substrings in std::(w)string
- Explicitly request large file support on 32bit systems

0.5.2 (2016-05-20)

+ Add fz::shared_optional::is_same that checks whether two instances share the same underlying pointer value, like a shallow equal.
+ Add fz::int_to_hex_char as reverse to fz::hex_char_to_int

0.5.1 (2016-05-09)

+ Add constructore to sparse_optional taking pointers
- Fix compilation on systems where iconv's second argument is const

0.5.0 (2016-04-15)

- Handle timestamps where midnight is represented as 24:00:00.000 of the previous day
- Fix inverted return value of fz::datetime::empty()
- Increase performance of event loop if not using timers
- Better compatibility with runtimes that change the src pointer passed to mbsrtowcs or wcsrtombs

0.4.0.1 (2016-02-22)

- Fix compile error in testcase

0.4.0 (2016-02-21)

+ Added shared_optional and sparse_optional classes

0.3.1 (2016-01-31)

- Fixed compile errors affecting some platforms
- Minor documentation fixes

0.3.0 (2016-01-12)

+ Added functions to deal with IP address strings
- Added testcase to verify string conversion functions. Some MinGW installations have broken wcsrtombs and mbsrtowcs implementations.

0.2.0 (2015-11-19)

+ Added local_filesys class
+ Added recursive_remove class
+ Added to_utf8 function to string.hpp as counterpart to the to_(w)string_from_utf8 functions
+ Added missing libfilezilla/glue/wx.hpp header mentioned in the FAQ
- Fixed compile errors

0.1.0 (2015-11-02)

+ First public release of libfilezilla
