Building lighttpd on Windows¶
lighttpd native _WIN32¶
lighttpd native _WIN32 may be built static or shared (dll) using autotools or CMake with compiler toolchain mingw (cygwin or msys) or MS Visual Studio.
lighttpd native _WIN32 limitations¶
- not implemented
- server.c: no daemonize, but can be installed as a Windows service
- server.c: no multiple workers
- server.c: no lighttpd -1 one-shot mode
- log.c: no syslog option (no Windows Event Log) - _WIN32 accepts both
/
and\
as path separators
lighttpd code has not been reviewed to normalize _WIN32\
to/
.
(possible security exposure) - _WIN32 environment paths may begin with volume
C:/
instead of with/
.
(possible security exposure)
lighttpd code has not been reviewed to normalize _WIN32 paths.
lighttpd code assumes in many places that full path begins with/
.
lighttpd might not work across multiple volumes. - _WIN32 NTFS alternate data streams not rejected
(possible security exposure)
https://redmine.lighttpd.net/issues/1335 - _WIN32 filesystem functions do not properly handle UTF-8
(ASCII works when UNICODE is not defined; wide-char works with UNICODE)
Some UTF-8 to wide-char compat translation funcs provided in fs_win32.[ch],
but not comprehensive. unlink(), rmdir(), chdir() not provided, or others ...
(move, replace, etc and other use of _WIN32 ...A() funcs might need to be
replaced with funcs which convert from UTF-8 to wide-char and use ...W()) - NTFS fails attempt to rename files atomically if either file is open.
lighttpd uses this idiom in file caches (deflate.cache-dir disabled on _WIN32)
lighttpd mod_webdav will fail if a PUT or MOVE is attepted on open an file.
Many file operations other than read may fail due to this NTFS limitation. - lighttpd mod_webdav has not been ported and will have multiple issues,
including but not limited to atomic file renames, non-ASCII UTF-8 file support - lighttpd does not attempt to detect setCaseSensitiveInfo dir attribute
- ...
Microsoft fuglies¶
SOCKET
is(long long unsigned)
, not(int)
as in POSIX file descriptors.
In practice (sample size n=1),SOCKET
appears to be <INT_MAX
, except for
INVALID_SOCKET
((long long unsigned)-1)
, which casts back to(int)-1
.
While it does not appear necessary to rewrite all code to use SOCKET instead
of int, it would be nice that IFF true, that it be documented by Microsoft.
Both the size of the type (64-bit) and the sign(unsigned)
is unfriendly to
porting code. It is suggested that historicallySOCKET
was a pointer value
cast to(uintptr_t)
(good job with type-safety $MS!). In 32-bit, int and
pointers are the same size, but not in 64-bit. Perhaps this was changed at
some point in $MS evolution, but is not well documented, as at least initial
assignments are smallish integers in 200's and 300's. $MS is able to
distinguish between file descriptors(int)
and(SOCKET)
since both are
supported bySetHandleInformation()
,ReadFile()
,WriteFile()
, so we can
conclude that $MS did not propagate that logic elsewhere, but probably could.
((HANDLE)(uint64_t)sockfd)
;((HANDLE)_get_osfhandle(fd))
(e.g. file and pipes)SOCKET
and file descriptors are not allowed as lowest available integer,
so using an array indexed by file descriptors is not a good pattern to apply.select()
andWSAPoll()
work only withSOCKET
, not with files or pipes.
(seeWaitForSingleObject()
WaitForMultipleObjects()
and related functions)
(alsoWSAEventSelect()
+WSAWaitForMultipleEvents()
)select()
is not a bitmap; client code aroundselect()
often needs to be
reworked. [1] The macros such asFD_ISSET
must be applied toSOCKET
, and not
to arbitrary integer in range from [0,FD_SETSIZE
)
https://devblogs.microsoft.com/oldnewthing/20221102-00/?p=107343
https://devblogs.microsoft.com/oldnewthing/20161221-00/?p=94985- filesystem redirection (stdin/stdout/stderr) to sockets is possible, but:
- filehandles must be inheritable (default)
- sockets must be non-overlapped (not default)
-socket()
creates sockets withWSA_FLAG_OVERLAPPED
-WSASocket()
has flag option to omitWSA_FLAG_OVERLAPPED
- programs generally need
SYSTEMROOT
defined in the environment to run properly #define WIN32_LEAN_AND_MEAN
must be defined before#include <windows.h>
or else you may get (undesirable) winsock 1.1 header visibility
https://learn.microsoft.com/en-us/windows/win32/winsock/creating-a-basic-winsock-application
For some apps,#include <winsock2.h>
is sufficient instead of#include <windows.h>
Must link with-lws2_32
#ifdef _MSC_VER
#pragma comment(lib, "ws2_32.lib")
#endifconnect()
on non-blocking socket errors withWSAGetLastError()
WSAWOULDBLOCK
,
notEINPROGRESS
dup()
anddup2()
can not be used onSOCKET
(seeWSADuplicateSocket()
)dup2()
does not return the newfd; incompatible interfacestat()
on a directory fails if string has trailing/
or\
stat()
returnsENOENT
instead ofENOTDIR
for CGIPATH_INFO
,
e.g. /real/file.cgi/path/infostat()
fails on //?/c:/... paths- error codes:
WSAGetLastError()
for sockets; do not checkerrno
- error codes:
GetLastError()
(except for sockets), and sometimeserrno
- Microsoft NTFS does not allow move/rename file operations on open files.
(Attempts to do so result in Permission denied; file already in use.)
A typical POSIX idiom of atomic rename fails on NTFS if either old or new
file is open. This breaks in lighttpd in numerous places where a cache is
updated and the new file is kept open during the rename, and then served to
the client. Forcing the file to be closed and then reopened around the
rename introduces a race condition in what is ultimately sent to the client.
(While this race is introduced in mod_deflate cache, mod_webdav and other
modules might still suffer/fail from this NTFS limitation.) - UCRT
<sys/types.h>
unconditionally definesoff_t
as long (4 bytes on_WIN32
)
if_CRT_DECLARE_NONSTDC_NAMES
is defined. Any application or library which
supports large files and expects 64-bitoff_t
needs to take steps to
workaround this (e.g. defineoff_t
,_off_t
,_OFF_T_DEFINED
in advance). - ...
[1] https://learn.microsoft.com/en-us/windows/win32/winsock/select-and-fd---2
Select, FD_SET, and FD_XXX Macros
Since sockets are not represented by the UNIX-style, small, non-negative integer, the implementation of the select function was changed in Windows Sockets. Each set of sockets is still represented by the FD_SET structure, but instead of being stored as a bitmask, the set is implemented as an array of sockets. To avoid potential problems, applications must adhere to the use of the FD_XXX macros to set, initialize, clear, and check the FD_SET structures.
lighttpd cygwin¶
lighttpd cygwin is maintained as a set of packages available from cygwin setup.exe
and supports nearly all the same features of lighttpd available on unix-like systems. However, extra precautions may need to be taken to protect a _WIN32 system (see below), so you are strongly advised against using lighttpd cygwin in production.
Updated by gstrauss 5 days ago · 12 revisions