Hi everyone,
My company is considering a possible integration of Collabora Online within its application and, accordingly, I’m building a small proof-of-concept.
My current POC is very simple, I’ve been following the “Step by step tutorial” and I’ve used Flask to build my WOPI host with a simple “Hello world” example.
I’m running Collabora on a docker container with the following compose.yml:
services:
collabora-app:
image: collabora/code
container_name: collabora-app
ports:
- "127.0.0.1:8085:9980"
environment:
- domain=mydomain.com
- extra_params=--o:ssl.enable=false --o:hostname=mydomain.com --o:ssl.termination=true
- aliasgroup1=https://mydomain.com
extra_hosts:
- "mydomain.com:host-gateway"
My Flask application will be running locally on port 5000.
My host is a VM with hostname mydomain.com
(where its DNS have also the same name - mydomain.com
). Since I’m running my VM on the internet I’m only exposing port 443 and I’m using Nginx as a reverse proxy.
Also locally, mydomain.com
is mapped to 127.0.0.1, i.e., in my VM /etc/hosts I have:
127.0.0.1 mydomain.com
My correspondent Nginx conf is:
location /flask/ {
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:5000/;
}
location ^~ /browser {
proxy_pass http://127.0.0.1:8085;
proxy_set_header Host $host;
}
location ^~ /hosting/discovery {
proxy_pass http://127.0.0.1:8085;
proxy_set_header Host $host;
}
location ^~ /hosting/capabilities {
proxy_pass http://127.0.0.1:8085;
proxy_set_header Host $host;
}
location ~ ^/cool/(.*)/ws$ {
proxy_pass http://127.0.0.1:8085;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_read_timeout 36000s;
}
location ~ ^/(c|l)ool {
proxy_pass http://127.0.0.1:8085;
proxy_set_header Host $host;
}
location ^~ /cool/adminws {
proxy_pass http://127.0.0.1:8085;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_read_timeout 36000s;
}
location / {
proxy_pass http://127.0.0.1:8085/;
proxy_set_header Host $host;
proxy_buffering off;
}
And with this setup everything works just fine!
Now here’s where my problem starts. In a real production VM I will have my main web-application (which will replace my Flask test-bench of this test) being server to the root URL. This will makes me the need to use a “suffix” in the URL for Collabora access.
Accordingly, I decided to use “/collabora/” as suffix and changed my Nginx conf:
# static files
location ^~ /collabora/browser {
proxy_pass http://127.0.0.1:8085/browser;
proxy_set_header Host $host;
}
# WOPI discovery URL
location ^~ /collabora/hosting/discovery {
proxy_pass http://127.0.0.1:8085/hosting/discovery;
proxy_set_header Host $host;
}
# Capabilities
location ^~ /collabora/hosting/capabilities {
proxy_pass http://127.0.0.1:8085/hosting/capabilities;
proxy_set_header Host $host;
}
# main websocket
location ~ ^/collabora/cool/(.*)/ws$ {
proxy_pass http://127.0.0.1:8085/cool/$1/ws;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_read_timeout 36000s;
}
# download, presentation and image upload
location ~ ^/collabora/(c|l)ool {
proxy_pass http://127.0.0.1:8085/$1ool;
proxy_set_header Host $host;
}
# Admin Console websocket
location ^~ /collabora/cool/adminws {
proxy_pass http://127.0.0.1:8085/cool/adminws;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_read_timeout 36000s;
}
location /collabora/ {
proxy_pass http://127.0.0.1:8085/;
proxy_set_header Host $host;
proxy_buffering off;
}
With this change I quickly realize that the “urlsrc” links wouldn’t reflect my change, since they were still pointing to the standard source:
https://mydomain.com/browser/d5ebff5/cool.html?
instead of:
https://mydomain.com/collabora/browser/d5ebff5/cool.html?
Which leads my to several 404 not found errors.
After some searching i’ve found out the need to include --o:net.service_root=/collabora
on my docker setup in order to reflect the change of having the suffix. Accordingly I changed my compose.yml to:
services:
collabora-app:
image: collabora/code
container_name: collabora-app
ports:
- "127.0.0.1:8085:9980"
environment:
- domain=mydomain.com
- extra_params=--o:ssl.enable=false --o:hostname=mydomain.com --o:ssl.termination=true --o:net.service_root=/collabora --o:server_name=mydomain.com
- aliasgroup1=https://mydomain.com
extra_hosts:
- "mydomain.com:host-gateway"
This change makes Collabora accessible (locally in the host) through 127.0.0.1:8085/collabora/
Accordingly, I changed Nginx conf file as well:
location ^~ /collabora/browser {
proxy_pass http://127.0.0.1:8085/collabora/browser;
proxy_set_header Host $host;
}
location ^~ /collabora/hosting/discovery {
proxy_pass http://127.0.0.1:8085/collabora/hosting/discovery;
proxy_set_header Host $host;
}
location ^~ /collabora/hosting/capabilities {
proxy_pass http://127.0.0.1:8085/collabora/hosting/capabilities;
proxy_set_header Host $host;
}
location ~ ^/collabora/cool/(.*)/ws$ {
proxy_pass http://127.0.0.1:8085/collabora/cool/$1/ws;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_read_timeout 36000s;
}
location ~ ^/collabora/(c|l)ool {
proxy_pass http://127.0.0.1:8085/collabora/$1ool;
proxy_set_header Host $host;
}
location ^~ /collabora/cool/adminws {
proxy_pass http://127.0.0.1:8085/collabora/cool/adminws;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_read_timeout 36000s;
}
location /collabora/ {
proxy_pass http://127.0.0.1:8085/collabora/;
proxy_set_header Host $host;
proxy_buffering off;
}
With this change, all the urls seem to have the “right link”, i.e, in https://mydomain.com/collabora/hosting/discovery
we can see now the “correct” urlsrc values.
Now, when I try to run the very same example I end up with:
WebSocket connection to 'wss://mydomain.com/collabora/cool/https%3A%2F%2Fmydomain.com%2Fflask%2Fwopi%2Ffiles%2F1233%3Faccess_token%3Dtest%26access_token_ttl%3D0/ws?WOPISrc=https%3A%2F%2Fmydomain.com%2Fflask%2Fwopi%2Ffiles%2F1233&compat=/ws' failed: Error during WebSocket handshake: Unexpected response code: 400
Checking/inspecting the websocket call the request URL I have:
wss://mydomain.com/collabora/cool/https%3A%2F%2Fmydomain.com%2Fflask%2Fwopi%2Ffiles%2F1233%3Faccess_token%3Dtest%26access_token_ttl%3D0/ws?WOPISrc=https%3A%2F%2Fmydomain.com%2Fflask%2Fwopi%2Ffiles%2F1233&compat=/ws
From Collabora docker logs I can see:
collabora-app | wsd-00001-00036 2024-10-08 15:05:51.056804 +0000 [ websrv_poll ] ERR #31: #31 Exception while processing incoming request: [GET /collabora/cool/https:/mydomain.com/flask/wopi/files/1233%3Faccess_token=test&access_token_ttl=0/ws?WOPISrc=https%3A%2F%2Fmydomain.com%2Fflask%2Fwopi%2Ffiles%2F12...]: Bad URI syntax| wsd/ClientRequestDispatcher.cpp:915
I’m not sure what the Bad URI means, but I guess something is happening between Nginx and Collabora.
I’ve been trying different configs with Nginx back and forth and trying to learn as much as I can by searching around on the web but, unfortunately, I haven’t made any progress by a week now.
Am I missing any config from Collabora to handle prefixes correctly? Or am I missing something from Nginx side to handle websockets properly?
Any help would be deeply appreciated!
Thank you!