Compare commits
4 Commits
b0ffa8417c
...
2b4e6d3a4d
Author | SHA1 | Date | |
---|---|---|---|
2b4e6d3a4d | |||
d9e4b2e4d7 | |||
643514a9c7 | |||
7c2d19ed24 |
50
.github/workflows/ci-alpine.yml
vendored
Normal file
50
.github/workflows/ci-alpine.yml
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
name: "Checks (alpine, many platforms)"
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
linux-alpine:
|
||||
runs-on: ubuntu-latest
|
||||
name: linux-alpine-${{ matrix.platform }}
|
||||
# abort if x86_64 fails
|
||||
continue-on-error: ${{ matrix.platform != 'x86_64' }}
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
platform: ['x86_64','x86','armhf','armv7','aarch64','ppc64le','riscv64','s390x']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: jirutka/setup-alpine@v1
|
||||
with:
|
||||
# riscv64 currently requires 'edge'
|
||||
branch: edge
|
||||
arch: ${{ matrix.platform }}
|
||||
packages: >
|
||||
build-base
|
||||
meson
|
||||
libev-dev
|
||||
ragel
|
||||
glib-dev
|
||||
lua5.1-dev
|
||||
zlib-dev
|
||||
bzip2-dev
|
||||
pkgconf
|
||||
openssl-dev
|
||||
gnutls-dev
|
||||
libidn-dev
|
||||
libunwind-dev
|
||||
python3
|
||||
py3-curl
|
||||
- name: meson setup
|
||||
shell: alpine.sh {0}
|
||||
run: meson setup mesonbuilddir
|
||||
- name: meson compile
|
||||
shell: alpine.sh {0}
|
||||
run: meson compile -C mesonbuilddir
|
||||
- name: meson test
|
||||
shell: alpine.sh {0}
|
||||
run: meson test -C mesonbuilddir -v
|
67
.github/workflows/ci-linux.yml
vendored
Normal file
67
.github/workflows/ci-linux.yml
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
name: "Checks (Ubuntu: gcc+clang)"
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{github.workflow}}-${{github.head_ref}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
linux-build-docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pkgs=(
|
||||
ruby
|
||||
ruby-nokogiri
|
||||
ruby-kramdown
|
||||
libxml2-utils
|
||||
)
|
||||
sudo apt-get install "${pkgs[@]}"
|
||||
- name: Build docs
|
||||
run: |
|
||||
mkdir -p out
|
||||
ruby doc/compile.rb out
|
||||
cp doc/*.css doc/*.js out
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: lighttpd2-docs
|
||||
path: out
|
||||
|
||||
linux-ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
name: linux-ubuntu-${{ matrix.compiler }}
|
||||
strategy:
|
||||
matrix:
|
||||
compiler: ['gcc', 'clang']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- if: ${{ matrix.compiler == 'clang' }}
|
||||
uses: egor-tensin/setup-clang@v1
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pkgs=(
|
||||
meson
|
||||
libev-dev
|
||||
ragel
|
||||
libglib2.0-dev
|
||||
liblua5.1-dev
|
||||
zlib1g-dev
|
||||
libbz2-dev
|
||||
pkg-config
|
||||
libssl-dev
|
||||
libgnutls28-dev
|
||||
libidn-dev
|
||||
libunwind8-dev
|
||||
python3
|
||||
python3-pycurl
|
||||
)
|
||||
sudo apt-get install "${pkgs[@]}"
|
||||
- name: meson setup
|
||||
run: meson setup mesonbuilddir
|
||||
- name: meson compile
|
||||
run: meson compile -C mesonbuilddir
|
||||
- name: meson test
|
||||
run: meson test -C mesonbuilddir -v
|
52
.github/workflows/ci-macos.yml
vendored
Normal file
52
.github/workflows/ci-macos.yml
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
name: "Checks (macOS)"
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{github.workflow}}-${{github.head_ref}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
macOS:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pkgs=(
|
||||
meson
|
||||
libev
|
||||
ragel
|
||||
glib
|
||||
lua@5.1
|
||||
zlib
|
||||
bzip2
|
||||
openssl@3
|
||||
gnutls
|
||||
libidn
|
||||
python3
|
||||
python-pycurl
|
||||
md5sha1sum
|
||||
)
|
||||
brew install "${pkgs[@]}"
|
||||
- name: meson setup
|
||||
run: meson setup -D unwind=false mesonbuilddir
|
||||
- name: meson compile
|
||||
run: meson compile -C mesonbuilddir
|
||||
- name: prepare environment for tests
|
||||
run: |
|
||||
sudo ifconfig lo0 alias 127.0.0.2 up
|
||||
|
||||
# try to create a tmpdir with a short relative path (for shorter unix socket paths)
|
||||
NEWTMPDIR=~/tmp
|
||||
ln -sf "${TMPDIR}" "${NEWTMPDIR}"
|
||||
echo "TMPDIR=$NEWTMPDIR" >> "$GITHUB_ENV"
|
||||
echo "PATH=$(brew --prefix python)/libexec/bin:$PATH" >> "$GITHUB_ENV"
|
||||
|
||||
if [ ! -f $(brew --prefix python)/libexec/bin/python3 ]; then
|
||||
# the brew path only provides "python", not "python3"...
|
||||
ln -s python $(brew --prefix python)/libexec/bin/python3
|
||||
fi
|
||||
- name: meson test
|
||||
run: |
|
||||
meson test -C mesonbuilddir -v
|
@ -17,11 +17,16 @@
|
||||
|
||||
/** see li_module_load */
|
||||
#define MODULE_DEPENDS(mods, name) do { \
|
||||
if (!li_module_load(mods, name)) { \
|
||||
ERROR(mods->main, "Couldn't load dependency '%s'", name); \
|
||||
GError *err = NULL; \
|
||||
if (!li_module_load(mods, name, &err)) { \
|
||||
ERROR(mods->main, "Couldn't load dependency '%s': %s", name, err->message); \
|
||||
g_error_free(err); \
|
||||
return FALSE; \
|
||||
} } while(0)
|
||||
|
||||
#define LI_MODULES_ERROR li_modules_error_quark()
|
||||
LI_API GQuark li_modules_error_quark(void);
|
||||
|
||||
typedef struct liModule liModule;
|
||||
|
||||
typedef struct liModules liModules;
|
||||
@ -58,7 +63,7 @@ LI_API void li_modules_free(liModules *mods);
|
||||
* returns NULL if it couldn't load the module.
|
||||
*
|
||||
* You should release modules after you used them with li_module_release or li_module_release_name */
|
||||
LI_API liModule* li_module_load(liModules *mods, const gchar* name);
|
||||
LI_API liModule* li_module_load(liModules *mods, const gchar* name, GError **error);
|
||||
|
||||
/* find module by name */
|
||||
LI_API liModule *li_module_lookup(liModules *mods, const gchar *name);
|
||||
|
@ -230,6 +230,7 @@ gboolean li_plugins_load_module(liServer *srv, const gchar *name) {
|
||||
liPlugins *ps = &srv->plugins;
|
||||
server_module *sm;
|
||||
const gchar* modname = name ? name : "core";
|
||||
GError *err = NULL;
|
||||
|
||||
sm = g_hash_table_lookup(ps->module_refs, modname);
|
||||
if (sm) return TRUE; /* already loaded */
|
||||
@ -240,9 +241,11 @@ gboolean li_plugins_load_module(liServer *srv, const gchar *name) {
|
||||
sm = server_module_new(srv, modname);
|
||||
g_hash_table_insert(ps->module_refs, sm->name, sm);
|
||||
if (name) {
|
||||
mod = li_module_load(ps->modules, name);
|
||||
mod = li_module_load(ps->modules, name, &err);
|
||||
|
||||
if (!mod) {
|
||||
ERROR(srv, "Couldn't load dependency '%s': %s", name, err->message);
|
||||
g_error_free(err);
|
||||
_server_module_release(sm);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -2,6 +2,10 @@
|
||||
#include <lighttpd/module.h>
|
||||
#include <lighttpd/utils.h>
|
||||
|
||||
GQuark li_modules_error_quark(void) {
|
||||
return g_quark_from_string("li-modules-error-quark");
|
||||
}
|
||||
|
||||
liModules *li_modules_new(gpointer main, const gchar *module_dir, gboolean module_resident) {
|
||||
liModules *m = g_slice_new(liModules);
|
||||
|
||||
@ -48,7 +52,7 @@ void li_modules_free(liModules* mods) {
|
||||
}
|
||||
|
||||
|
||||
liModule* li_module_load(liModules *mods, const gchar* name) {
|
||||
liModule* li_module_load(liModules *mods, const gchar* name, GError **err) {
|
||||
liModule *mod;
|
||||
liModuleInitCB m_init;
|
||||
GString *m_init_str, *m_free_str;
|
||||
@ -65,15 +69,23 @@ liModule* li_module_load(liModules *mods, const gchar* name) {
|
||||
mod = g_slice_new0(liModule);
|
||||
mod->name = g_string_new(name);
|
||||
mod->refcount = 1;
|
||||
mod->path = g_module_build_path(mods->module_dir, name);
|
||||
|
||||
mod->path = g_strconcat(mods->module_dir, G_DIR_SEPARATOR_S, name, NULL);
|
||||
mod->module = g_module_open(mod->path, G_MODULE_BIND_LAZY);
|
||||
|
||||
if (!mod->module) {
|
||||
g_string_free(mod->name, TRUE);
|
||||
if (err) g_set_error(err, LI_MODULES_ERROR, 1, "%s", g_module_error());
|
||||
g_free(mod->path);
|
||||
g_slice_free(liModule, mod);
|
||||
return NULL;
|
||||
|
||||
mod->path = g_module_build_path(mods->module_dir, name);
|
||||
mod->module = g_module_open(mod->path, G_MODULE_BIND_LAZY);
|
||||
|
||||
if (!mod->module) {
|
||||
g_string_free(mod->name, TRUE);
|
||||
g_free(mod->path);
|
||||
g_slice_free(liModule, mod);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* temporary strings for mod_xyz_init and mod_xyz_free */
|
||||
@ -86,6 +98,12 @@ liModule* li_module_load(liModules *mods, const gchar* name) {
|
||||
|| !g_module_symbol(mod->module, m_free_str->str, (gpointer *)&mod->free)
|
||||
|| m_init == NULL || mod->free == NULL) {
|
||||
|
||||
g_set_error(err, LI_MODULES_ERROR, 1,
|
||||
"li_module_load: couldn't load %s or %s from %s",
|
||||
m_init_str->str,
|
||||
m_free_str->str,
|
||||
mod->path);
|
||||
|
||||
/* mod_init or mod_free couldn't be located, something went wrong */
|
||||
g_string_free(m_init_str, TRUE);
|
||||
g_string_free(m_free_str, TRUE);
|
||||
@ -97,6 +115,11 @@ liModule* li_module_load(liModules *mods, const gchar* name) {
|
||||
|
||||
/* call mod_xyz_init */
|
||||
if (!m_init(mods, mod)) {
|
||||
g_set_error(err, LI_MODULES_ERROR, 1,
|
||||
"li_module_load: calling %s from %s failed",
|
||||
m_init_str->str,
|
||||
mod->path);
|
||||
|
||||
g_string_free(m_init_str, TRUE);
|
||||
g_string_free(m_free_str, TRUE);
|
||||
g_free(mod->path);
|
||||
|
@ -1238,6 +1238,7 @@ static gboolean core_workers_cpu_affinity(liServer *srv, liPlugin* p, liValue *v
|
||||
}
|
||||
|
||||
static gboolean core_module_load(liServer *srv, liPlugin* p, liValue *val, gpointer userdata) {
|
||||
GError *err = NULL;
|
||||
UNUSED(p); UNUSED(userdata);
|
||||
|
||||
if (!g_module_supported()) {
|
||||
@ -1272,8 +1273,9 @@ static gboolean core_module_load(liServer *srv, liPlugin* p, liValue *val, gpoin
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!li_module_load(srv->modules, name->str)) {
|
||||
ERROR(srv, "could not load module '%s': %s", name->str, g_module_error());
|
||||
if (!li_module_load(srv->modules, name->str, &err)) {
|
||||
ERROR(srv, "could not load module '%s': %s", name->str, err->message);
|
||||
g_error_free(err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,15 @@ class Service:
|
||||
self.proc: typing.Optional[subprocess.Popen] = None
|
||||
self.failed = False
|
||||
|
||||
def bind_unix_socket(self, *, sockfile: str, backlog: int = 8) -> socket.socket:
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
rel_sockfile = os.path.relpath(sockfile)
|
||||
if len(rel_sockfile) < len(sockfile):
|
||||
sockfile = rel_sockfile
|
||||
sock.bind(sockfile)
|
||||
sock.listen(8)
|
||||
return sock
|
||||
|
||||
def fork(self, *args: str, inp: typing.Union[tuple[()], FileWithFd, None] = ()) -> None:
|
||||
arguments = list(args) # convert tuple to list
|
||||
stdin: typing.Optional[FileWithFd]
|
||||
@ -245,9 +254,7 @@ class FastCGI(Service):
|
||||
def prepare_service(self) -> None:
|
||||
assert self.tests
|
||||
self.tests.install_dir(os.path.join("tmp", "sockets"))
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
sock.bind(os.path.relpath(self.sockfile))
|
||||
sock.listen(8)
|
||||
sock = self.bind_unix_socket(sockfile=self.sockfile)
|
||||
self.fork(*self.binary, inp=sock)
|
||||
|
||||
def cleanup_service(self) -> None:
|
||||
|
@ -21,9 +21,7 @@ class Memcached(Service):
|
||||
def prepare_service(self) -> None:
|
||||
assert self.tests
|
||||
self.tests.install_dir(os.path.join("tmp", "sockets"))
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
sock.bind(os.path.relpath(self.sockfile))
|
||||
sock.listen(8)
|
||||
sock = self.bind_unix_socket(sockfile=self.sockfile)
|
||||
self.fork(*self.binary, inp=sock)
|
||||
|
||||
def cleanup_service(self) -> None:
|
||||
|
@ -20,9 +20,7 @@ class SCGI(Service):
|
||||
def prepare_service(self) -> None:
|
||||
assert self.tests
|
||||
self.tests.install_dir(os.path.join("tmp", "sockets"))
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
sock.bind(os.path.relpath(self.sockfile))
|
||||
sock.listen(8)
|
||||
sock = self.bind_unix_socket(sockfile=self.sockfile)
|
||||
self.fork(*self.binary, inp=sock)
|
||||
|
||||
def cleanup_service(self) -> None:
|
||||
|
Loading…
Reference in New Issue
Block a user