diff --git a/viewer/__init__.py b/viewer/__init__.py index 6c7228cb4..61a7e0fd4 100644 --- a/viewer/__init__.py +++ b/viewer/__init__.py @@ -6,7 +6,8 @@ import logging import sys from builtins import range -from os import getenv, path +from os import getenv, path, environ +import socket from signal import SIGALRM, SIGUSR1, signal from time import sleep @@ -46,10 +47,12 @@ connect_to_redis, get_balena_device_info, get_node_ip, + get_node_mac_address, is_balena_app, string_to_bool, url_fails, ) + from lib import diagnostics from viewer.scheduling import Scheduler from viewer.zmq import ZMQ_HOST_PUB_URL, ZmqSubscriber except Exception: @@ -154,7 +157,36 @@ def load_browser(): global browser logging.info('Loading browser...') - browser = sh.Command('ScreenlyWebview')(_bg=True, _err_to_out=True) + # Prepare headers data for WebView via environment variables + try: + anthias_hostname = socket.gethostname() + except Exception: + anthias_hostname = '' + + try: + git_branch = diagnostics.get_git_branch() + git_short_hash = diagnostics.get_git_short_hash() + anthias_version = ( + f"{git_branch}@{git_short_hash}" + if git_branch and git_short_hash else '' + ) + except Exception: + anthias_version = '' + + try: + anthias_mac = get_node_mac_address() + except Exception: + anthias_mac = '' + + env = dict(environ) + if anthias_hostname: + env['ANTHIAS_HOSTNAME'] = anthias_hostname + if anthias_version: + env['ANTHIAS_VERSION'] = anthias_version + if anthias_mac: + env['ANTHIAS_MAC'] = anthias_mac + + browser = sh.Command('ScreenlyWebview')(_bg=True, _err_to_out=True, _env=env) while ( 'Screenly service start' not in browser.process.stdout.decode('utf-8') ): diff --git a/webview/ScreenlyWebview.pro b/webview/ScreenlyWebview.pro index 82aaf6989..1dea0ebdb 100644 --- a/webview/ScreenlyWebview.pro +++ b/webview/ScreenlyWebview.pro @@ -5,7 +5,8 @@ CONFIG += c++11 SOURCES += src/main.cpp \ src/mainwindow.cpp \ - src/view.cpp + src/view.cpp \ + src/requestinterceptor.cpp # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = @@ -15,4 +16,5 @@ include(src/deployment.pri) HEADERS += \ src/mainwindow.h \ - src/view.h + src/view.h \ + src/requestinterceptor.h diff --git a/webview/src/requestinterceptor.cpp b/webview/src/requestinterceptor.cpp new file mode 100644 index 000000000..ace5f6a91 --- /dev/null +++ b/webview/src/requestinterceptor.cpp @@ -0,0 +1,29 @@ +#include "requestinterceptor.h" + +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) +#include + +RequestInterceptor::RequestInterceptor(QObject* parent) + : QWebEngineUrlRequestInterceptor(parent) +{ + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + hostname = env.value("ANTHIAS_HOSTNAME").toUtf8(); + version = env.value("ANTHIAS_VERSION").toUtf8(); + mac = env.value("ANTHIAS_MAC").toUtf8(); +} + +void RequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) +{ + if (!hostname.isEmpty()) { + info.setHttpHeader("X-Anthias-hostname", hostname); + } + if (!version.isEmpty()) { + info.setHttpHeader("X-Anthias-version", version); + } + if (!mac.isEmpty()) { + info.setHttpHeader("X-Anthias-mac", mac); + } +} +#endif + + diff --git a/webview/src/requestinterceptor.h b/webview/src/requestinterceptor.h new file mode 100644 index 000000000..4a4ec2ec5 --- /dev/null +++ b/webview/src/requestinterceptor.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) +#include +#include +#include +#include + +class RequestInterceptor : public QWebEngineUrlRequestInterceptor +{ +public: + explicit RequestInterceptor(QObject* parent = nullptr); + void interceptRequest(QWebEngineUrlRequestInfo &info) override; + +private: + QByteArray hostname; + QByteArray version; + QByteArray mac; +}; +#endif + + diff --git a/webview/src/view.cpp b/webview/src/view.cpp index 18729ded4..8c5bd7ee8 100644 --- a/webview/src/view.cpp +++ b/webview/src/view.cpp @@ -10,8 +10,10 @@ #include #include #include +#include #include "view.h" +#include "requestinterceptor.h" View::View(QWidget* parent) : QWidget(parent) @@ -44,6 +46,13 @@ View::View(QWidget* parent) : QWidget(parent) isAnimatedImage = false; connect(animationTimer, &QTimer::timeout, this, &View::updateMovieFrame); + +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) + // Attach request interceptor to inject headers + RequestInterceptor* interceptor = new RequestInterceptor(this); + webView1->page()->profile()->setUrlRequestInterceptor(interceptor); + webView2->page()->profile()->setUrlRequestInterceptor(interceptor); +#endif } View::~View() @@ -135,6 +144,19 @@ void View::loadImage(const QString &preUri) // Start loading the next image QNetworkRequest request(src); + // Inject the same headers for image fetches + QByteArray hostname = qgetenv("ANTHIAS_HOSTNAME"); + QByteArray version = qgetenv("ANTHIAS_VERSION"); + QByteArray mac = qgetenv("ANTHIAS_MAC"); + if (!hostname.isEmpty()) { + request.setRawHeader("X-Anthias-hostname", hostname); + } + if (!version.isEmpty()) { + request.setRawHeader("X-Anthias-version", version); + } + if (!mac.isEmpty()) { + request.setRawHeader("X-Anthias-mac", mac); + } QNetworkReply* reply = networkManager->get(request); connect(reply, &QNetworkReply::finished, this, [=]() {