diff --git a/browser/html/cool.html.m4 b/browser/html/cool.html.m4
index 1e28026e4611c..cdefe50b715b0 100644
--- a/browser/html/cool.html.m4
+++ b/browser/html/cool.html.m4
@@ -254,6 +254,7 @@ m4_ifelse(MOBILEAPP, [true],
data-saved-ui-state = "%SAVED_UI_STATE%"
data-wasm-enabled = "%WASM_ENABLED%"
data-indirection-url = "%INDIRECTION_URL%"
+ data-geolocation-setup = "%GEOLOCATION_SETUP%"
/>
])
diff --git a/browser/js/global.js b/browser/js/global.js
index a706aa247276c..b16c7c82d386d 100644
--- a/browser/js/global.js
+++ b/browser/js/global.js
@@ -288,6 +288,7 @@ class InitializerBase {
window.savedUIState = true;
window.wasmEnabled = false;
window.indirectionUrl = "";
+ window.geolocationSetup = false;
window.tileSize = 256;
@@ -406,6 +407,7 @@ class BrowserInitializer extends InitializerBase {
window.savedUIState = element.dataset.savedUiState.toLowerCase().trim() === "true";
window.wasmEnabled = element.dataset.wasmEnabled.toLowerCase().trim() === "true";
window.indirectionUrl = element.dataset.indirectionUrl;
+ window.geolocationSetup = element.dataset.geolocationSetup.toLowerCase().trim() === "true";
}
postMessageHandler(e) {
@@ -1385,54 +1387,63 @@ function getInitializerClass() {
global.parent.postMessage(JSON.stringify(msg), '*');
};
- var http = new XMLHttpRequest();
- let url = global.indirectionUrl + '?Uri=' + encodeURIComponent(that.uri);
- http.open('GET', url, true);
- http.responseType = 'json';
- http.addEventListener('load', function() {
- if (this.status === 200) {
- var uriWithRouteToken = http.response.uri;
- global.expectedServerId = http.response.serverId;
- var params = (new URL(uriWithRouteToken)).searchParams;
- global.routeToken = params.get('RouteToken');
- global.app.console.log('updated routeToken: ' + global.routeToken);
- that.innerSocket = new WebSocket(uriWithRouteToken);
- that.innerSocket.binaryType = that.binaryType;
- that.innerSocket.onerror = function() {
- that.readyState = that.innerSocket.readyState;
- that.onerror();
- };
- that.innerSocket.onclose = function() {
- that.readyState = 3;
- that.onclose();
- that.innerSocket.onerror = function () {};
- that.innerSocket.onclose = function () {};
- that.innerSocket.onmessage = function () {};
- };
- that.innerSocket.onopen = function() {
- that.readyState = 1;
- that.onopen();
- };
- that.innerSocket.onmessage = function(e) {
- that.readyState = that.innerSocket.readyState;
- that.onmessage(e);
- };
- } else if (this.status === 202) {
- if (!(window.app && window.app.socket && window.app.socket._reconnecting)) {
+ this.sendRouteTokenRequest = function (requestUri) {
+ var http = new XMLHttpRequest();
+ // let url = global.indirectionUrl + '?Uri=' + encodeURIComponent(that.uri);
+ http.open('GET', requestUri, true);
+ http.responseType = 'json';
+ http.addEventListener('load', function () {
+ if (this.status === 200) {
+ var uriWithRouteToken = http.response.uri;
+ global.expectedServerId = http.response.serverId;
+ var params = (new URL(uriWithRouteToken)).searchParams;
+ global.routeToken = params.get('RouteToken');
+ global.app.console.log('updated routeToken: ' + global.routeToken);
+ that.innerSocket = new WebSocket(uriWithRouteToken);
+ that.innerSocket.binaryType = that.binaryType;
+ that.innerSocket.onerror = function () {
+ that.readyState = that.innerSocket.readyState;
+ that.onerror();
+ };
+ that.innerSocket.onclose = function () {
+ that.readyState = 3;
+ that.onclose();
+ that.innerSocket.onerror = function () { };
+ that.innerSocket.onclose = function () { };
+ that.innerSocket.onmessage = function () { };
+ };
+ that.innerSocket.onopen = function () {
+ that.readyState = 1;
+ that.onopen();
+ };
+ that.innerSocket.onmessage = function (e) {
+ that.readyState = that.innerSocket.readyState;
+ that.onmessage(e);
+ };
+ } else if (this.status === 202) {
+ if (!(window.app && window.app.socket && window.app.socket._reconnecting)) {
that.sendPostMsg(http.response.errorCode);
+ }
+ var timeoutFn = function (requestUri) {
+ console.warn('Requesting again for routeToken');
+ this.open('GET', requestUri, true);
+ this.send();
+ }.bind(this);
+ setTimeout(timeoutFn, 3000, requestUri);
+ } else {
+ global.app.console.error('Indirection url: error on incoming response ' + this.status);
+ that.sendPostMsg(-1);
}
- var timeoutFn = function (indirectionUrl, uri) {
- console.warn('Requesting again for routeToken');
- this.open('GET', indirectionUrl + '?Uri=' + encodeURIComponent(uri), true);
- this.send();
- }.bind(this);
- setTimeout(timeoutFn, 3000, global.indirectionUrl, that.uri);
- } else {
- global.app.console.error('Indirection url: error on incoming response ' + this.status);
- that.sendPostMsg(-1);
- }
- });
- http.send();
+ });
+ http.send();
+ };
+
+ let requestUri = global.indirectionUrl + '?Uri=' + encodeURIComponent(that.uri);
+ if (global.geolocationSetup) {
+ let timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
+ requestUri += "&TimeZone=" + timeZone;
+ }
+ this.sendRouteTokenRequest(requestUri);
};
global.createWebSocket = function(uri) {
diff --git a/coolwsd.xml.in b/coolwsd.xml.in
index 6f18d815fd8a8..dfae6e60a07c3 100644
--- a/coolwsd.xml.in
+++ b/coolwsd.xml.in
@@ -322,6 +322,9 @@
+
+ false
+
@LOCK_CONFIGURATION@
diff --git a/wsd/ClientRequestDispatcher.cpp b/wsd/ClientRequestDispatcher.cpp
index 3e130c8a60dd1..88db2864c8431 100644
--- a/wsd/ClientRequestDispatcher.cpp
+++ b/wsd/ClientRequestDispatcher.cpp
@@ -2002,6 +2002,27 @@ std::string ClientRequestDispatcher::getDiscoveryXML()
#if !MOBILEAPP
+/// Get IANA timezone name
+static std::string getIANATimezone()
+{
+ const char* tzfile = "/etc/localtime";
+ char buf[PATH_MAX];
+
+ ssize_t len = readlink(tzfile, buf, sizeof(buf) - 1);
+ if (len != -1)
+ {
+ buf[len] = '\0';
+ std::string fullPath(buf);
+
+ std::string prefix = "../usr/share/zoneinfo/";
+ if (fullPath.substr(0, prefix.size()) == prefix)
+ {
+ return fullPath.substr(prefix.size());
+ }
+ }
+ return std::string();
+}
+
/// Create the /hosting/capabilities JSON and return as string.
static std::string getCapabilitiesJson(bool convertToAvailable)
{
@@ -2054,6 +2075,15 @@ static std::string getCapabilitiesJson(bool convertToAvailable)
if (const char* podName = std::getenv("POD_NAME"))
capabilities->set("podName", podName);
+ bool geoLocationSetup =
+ config::getBool(std::string("indirection_endpoint.geolocation_setup.enable"), false);
+ if (geoLocationSetup)
+ {
+ std::string timezoneName = getIANATimezone();
+ if (!timezoneName.empty())
+ capabilities->set("timezone", std::string(timezoneName));
+ }
+
std::ostringstream ostrJSON;
capabilities->stringify(ostrJSON);
return ostrJSON.str();
diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp
index 6de6544e29396..32ca3ebf3a253 100644
--- a/wsd/FileServer.cpp
+++ b/wsd/FileServer.cpp
@@ -1366,6 +1366,11 @@ FileServerRequestHandler::ResourceAccessDetails FileServerRequestHandler::prepro
Poco::URI indirectionURI(config.getString("indirection_endpoint.url", ""));
Poco::replaceInPlace(preprocess, std::string("%INDIRECTION_URL%"), indirectionURI.toString());
+ bool geoLocationSetup = config.getBool("indirection_endpoint.geolocation_setup.enable");
+ if (geoLocationSetup)
+ Poco::replaceInPlace(preprocess, std::string("%GEOLOCATION_SETUP%"),
+ boolToString(geoLocationSetup));
+
const std::string mimeType = "text/html";
// Document signing: if endpoint URL is configured, whitelist that for