diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c
index 4b4eec0185..f9bff4fb97 100644
--- a/src/journal-remote/journal-gatewayd.c
+++ b/src/journal-remote/journal-gatewayd.c
@@ -1005,10 +1005,10 @@ static int parse_argv(int argc, char *argv[]) {
static int run(int argc, char *argv[]) {
_cleanup_(MHD_stop_daemonp) struct MHD_Daemon *d = NULL;
struct MHD_OptionItem opts[] = {
- { MHD_OPTION_NOTIFY_COMPLETED,
- (intptr_t) request_meta_free, NULL },
{ MHD_OPTION_EXTERNAL_LOGGER,
(intptr_t) microhttpd_logger, NULL },
+ { MHD_OPTION_NOTIFY_COMPLETED,
+ (intptr_t) request_meta_free, NULL },
{ MHD_OPTION_END, 0, NULL },
{ MHD_OPTION_END, 0, NULL },
{ MHD_OPTION_END, 0, NULL },
diff --git a/src/socket-activate/socket-activate.c b/src/socket-activate/socket-activate.c
index 1caa30d7d4..2e19d125c3 100644
--- a/src/socket-activate/socket-activate.c
+++ b/src/socket-activate/socket-activate.c
@@ -443,6 +443,7 @@ static int parse_argv(int argc, char *argv[]) {
static int run(int argc, char **argv) {
_cleanup_close_ int epoll_fd = -EBADF;
+ _cleanup_strv_free_ char **exec_argv = NULL;
int r, n;
log_show_color(true);
@@ -453,6 +454,12 @@ static int run(int argc, char **argv) {
if (r <= 0)
return r;
+ exec_argv = strv_copy(arg_args);
+ if (!exec_argv)
+ return log_oom();
+
+ assert(strv_length(exec_argv) > 0);
+
r = install_chld_handler();
if (r < 0)
return r;
@@ -475,14 +482,14 @@ static int run(int argc, char **argv) {
log_info("Communication attempt on fd %i.", event.data.fd);
if (arg_accept) {
- r = do_accept(argv[optind], argv + optind, event.data.fd);
+ r = do_accept(exec_argv[0], exec_argv, event.data.fd);
if (r < 0)
return r;
} else
break;
}
- return exec_process(argv[optind], argv + optind, SD_LISTEN_FDS_START, (size_t) n);
+ return exec_process(exec_argv[0], exec_argv, SD_LISTEN_FDS_START, (size_t) n);
}
DEFINE_MAIN_FUNCTION(run);
diff --git a/test/TEST-04-JOURNAL/test.sh b/test/TEST-04-JOURNAL/test.sh
index 09516d11f5..96fc8b7049 100755
--- a/test/TEST-04-JOURNAL/test.sh
+++ b/test/TEST-04-JOURNAL/test.sh
@@ -13,11 +13,11 @@ test_append_files() {
mkdir -p "$workspace/test-journals/"
cp -av "${TEST_BASE_DIR:?}/test-journals/"* "$workspace/test-journals/"
- inst_binary unzstd
-
- (
- command -v logger >/dev/null 2>&1 && inst_binary logger
- )
+ image_install curl unzstd
+ image_install -o openssl
+ # Necessary for RH-based systems, otherwise MHD fails with:
+ # microhttpd: Failed to initialise TLS session.
+ image_install -o /etc/crypto-policies/back-ends/gnutls.config
}
do_test "$@"
diff --git a/test/units/testsuite-04.journal-gatewayd.sh b/test/units/testsuite-04.journal-gatewayd.sh
new file mode 100755
index 0000000000..1efdc3cae0
--- /dev/null
+++ b/test/units/testsuite-04.journal-gatewayd.sh
@@ -0,0 +1,116 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+# pipefail is disabled intentionally, as `curl | grep -q` is very SIGPIPE happy
+
+if [[ ! -x /usr/lib/systemd/systemd-journal-gatewayd ]]; then
+ echo "Built without systemd-journal-gatewayd support, skipping the test"
+ exit 0
+fi
+
+TEST_MESSAGE="-= This is a test message $RANDOM =-"
+TEST_TAG="$(systemd-id128 new)"
+
+echo "$TEST_MESSAGE" | systemd-cat -t "$TEST_TAG"
+journalctl --sync
+TEST_CURSOR="$(journalctl -q -t "$TEST_TAG" -n 0 --show-cursor | awk '{ print $3; }')"
+BOOT_CURSOR="$(journalctl -q -b -n 0 --show-cursor | awk '{ print $3; }')"
+
+/usr/lib/systemd/systemd-journal-gatewayd --version
+/usr/lib/systemd/systemd-journal-gatewayd --help
+
+# Default configuration (HTTP, socket activated)
+systemctl start systemd-journal-gatewayd.socket
+
+# /browse
+# We should get redirected to /browse by default
+curl -Lfs http://localhost:19531 | grep -qF "
Journal"
+curl -Lfs http://localhost:19531/browse | grep -qF "Journal"
+(! curl -Lfs http://localhost:19531/foo/bar/baz)
+(! curl -Lfs http://localhost:19531/foo/../../../bar/../baz)
+
+# /entries
+# Accept: text/plain should be the default
+curl -Lfs http://localhost:19531/entries | \
+ grep -qE " $TEST_TAG\[[0-9]+\]: $TEST_MESSAGE"
+curl -Lfs --header "Accept: text/plain" http://localhost:19531/entries | \
+ grep -qE " $TEST_TAG\[[0-9]+\]: $TEST_MESSAGE"
+curl -Lfs --header "Accept: application/json" http://localhost:19531/entries | \
+ jq -se ".[] | select(.MESSAGE == \"$TEST_MESSAGE\")"
+# FIXME: drop the condition once https://github.com/systemd/systemd/issues/28059 is resolved
+if ! systemd-detect-virt -cq; then
+ curl -Lfs --header "Accept: application/json" http://localhost:19531/entries?boot | \
+ jq -se ".[] | select(.MESSAGE == \"$TEST_MESSAGE\")"
+fi
+curl -Lfs --header "Accept: application/json" http://localhost:19531/entries?SYSLOG_IDENTIFIER="$TEST_TAG" | \
+ jq -se "length == 1 and select(.[].MESSAGE == \"$TEST_MESSAGE\")"
+# Show 10 entries starting from $BOOT_CURSOR, skip the first 5
+curl -Lfs --header "Accept: application/json" --header "Range: entries=$BOOT_CURSOR:5:10" http://localhost:19531/entries | \
+ jq -se "length == 10"
+# Check if the specified cursor refers to an existing entry and return just that entry
+curl -Lfs --header "Accept: application/json" --header "Range: entries=$TEST_CURSOR" http://localhost:19531/entries?discrete | \
+ jq -se "length == 1 and select(.[].MESSAGE == \"$TEST_MESSAGE\")"
+# No idea how to properly parse this (jq won't cut it), so let's at least do some sanity checks that every
+# line is either empty or begins with data:
+curl -Lfs --header "Accept: text/event-stream" http://localhost:19531/entries | \
+ awk '!/^(data: \{.+\}|)$/ { exit 1; }'
+# Same thing as journalctl --output=export
+mkdir /tmp/remote-journal
+curl -Lfs --header "Accept: application/vnd.fdo.journal" http://localhost:19531/entries | \
+ /usr/lib/systemd/systemd-journal-remote -o /tmp/remote-journal/system.journal --split-mode=none -
+journalctl --directory=/tmp/remote-journal -t "$TEST_TAG" --grep "$TEST_MESSAGE"
+rm -rf /tmp/remote-journal
+
+# /machine
+curl -Lfs http://localhost:19531/machine | jq
+
+# /fields
+curl -Lfs http://localhost:19531/fields/MESSAGE | grep -qE -- "$TEST_MESSAGE"
+curl -Lfs http://localhost:19531/fields/_TRANSPORT
+(! curl -Lfs http://localhost:19531/fields)
+(! curl -Lfs http://localhost:19531/fields/foo-bar-baz)
+
+systemctl stop systemd-journal-gatewayd.{socket,service}
+
+if ! command -v openssl >/dev/null; then
+ echo "openssl command not available, skipping the HTTPS tests"
+ exit 0
+fi
+
+# Generate a self-signed certificate for systemd-journal-gatewayd
+#
+# Note: older OpenSSL requires a config file with some extra options, unfortunately
+cat >/tmp/openssl.conf <Journal"
+curl -Lfsk https://localhost:19531/entries | \
+ grep -qE " $TEST_TAG\[[0-9]+\]: $TEST_MESSAGE"
+curl -Lfsk --header "Accept: application/json" https://localhost:19531/entries | \
+ jq -se ".[] | select(.MESSAGE == \"$TEST_MESSAGE\")"
+curl -Lfsk https://localhost:19531/machine | jq
+curl -Lfsk https://localhost:19531/fields/_TRANSPORT
+
+kill "$GATEWAYD_PID"
diff --git a/test/units/testsuite-04.journal.sh b/test/units/testsuite-04.journal.sh
index 58c3661391..5e8a0235c5 100755
--- a/test/units/testsuite-04.journal.sh
+++ b/test/units/testsuite-04.journal.sh
@@ -52,15 +52,13 @@ grep -q '^PRIORITY=6$' /tmp/output
(! grep '^SYSLOG_FACILITY=' /tmp/output)
# --truncate shows only first line, skip under asan due to logger
-if [ -z "${ASAN_OPTIONS+x}${UBSAN_OPTIONS+x}" ] && command -v logger >/dev/null 2>&1 ;then
- ID=$(journalctl --new-id128 | sed -n 2p)
- logger -t "$ID" $'HEAD\nTAIL\nTAIL'
- journalctl --sync
- journalctl -q -b -t "$ID" | grep -q HEAD
- journalctl -q -b -t "$ID" | grep -q TAIL
- journalctl -q -b -t "$ID" --truncate-newline | grep -q HEAD
- journalctl -q -b -t "$ID" --truncate-newline | grep -q -v TAIL
-fi
+ID="$(systemd-id128 new)"
+echo -e 'HEAD\nTAIL\nTAIL' | systemd-cat -t "$ID"
+journalctl --sync
+journalctl -b -t "$ID" | grep -q HEAD
+journalctl -b -t "$ID" | grep -q TAIL
+journalctl -b -t "$ID" --truncate-newline | grep -q HEAD
+journalctl -b -t "$ID" --truncate-newline | grep -q -v TAIL
# '-b all' negates earlier use of -b (-b and -m are otherwise exclusive)
journalctl -b -1 -b all -m >/dev/null