Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change calendar for existing event on iOS doesn't work #1461

Open
sancoder opened this issue Mar 22, 2024 · 16 comments
Open

Change calendar for existing event on iOS doesn't work #1461

sancoder opened this issue Mar 22, 2024 · 16 comments

Comments

@sancoder
Copy link

Running Radicale 3.1.9 on Linux (Debian; nginx as reverse proxy, ssl via letsencrypt).
For calendar sharing we use symlinks the following way:
/var/lib/collections/collection-root has one folder calendars and few user folders which are symlinks to calendars folder in the same directory.
Every user can see (!), read and write to other users' calendars.

The problem is that after event was created, changing calendar for the event has no effect. The user who made the change (put it from calendar1 to calendar2) sees the change. All other users don't see the change and see the old version.

That's weird because all other changes work as expected.

Download ics file via web interface I can find event in the original calendar, but not in the calendar the event was put into.
That explains why all users see event in the "old" calendar.
That doesn't explain why the user who made the change continues to see the change.

Will try to dig deeper into this some time later. In the meantime if anyone could test and reproduce the same feature - it would be helpful.

@pbiering
Copy link
Collaborator

I have similar setup here, having shared calendar by softlinking, clients are

  • Thunderbird
  • Android (DaVx)
  • iOS

I had similar issue in the past and finally it was solved by fixing code in the "move.py" section together with verifcation of the reverse proxy config in case "radicale" is behind the proxy. Your description look like the same, the event is only moved on iOS client, but not successful executed on server side. Check log of "radicale", it should mention here something. If required, enable debug mode.

@sancoder
Copy link
Author

sancoder commented Apr 9, 2024

Ran radicale from console, and indeed here is what I got

[2024-04-09 05:07:36 +0000] [145517/Thread-28] [INFO] MOVE request for '/user/9-uuid-A/A-uuid-6.ics' received from 127.0.0.1 (forwarded for '7-ip-address-3') using 'iOS/17.4.1 (21E236) dataaccessd/1.0'
[2024-04-09 05:07:36 +0000] [145517/Thread-28] [INFO] Unsupported destination address: 'https://my.server.name/user/F-uuid-6/A-uuid-6.ics'
[2024-04-09 05:07:36 +0000] [145517/Thread-28] [INFO] MOVE response status for '/user/9-uuid-A/A-uuid-6.ics' in 0.002 seconds: 502 Bad Gateway

(I changed user name, sernver name, ip address, and uuid's).

@pbiering
Copy link
Collaborator

pbiering commented Apr 9, 2024

The "MOVE" code was extended related to such detection between 3.1.8 and 3.19, are you using latest version? And can you confirm your "nginx" configuration is similar to what is documented? https://radicale.org/master.html#reverse-proxy

@sancoder
Copy link
Author

sancoder commented Apr 9, 2024

Yes, I am definitely on 3.1.9. Just ran python -m radicale --version and the output was 3.1.9.
As to nginx config, I remember it didn't work as expected so I changed it to this

server {
    listen 443 ssl;
    server_name my.server.name;
    ssl_certificate     /etc/letsencrypt/live/my.server.name/cert.pem;
    ssl_certificate_key /etc/letsencrypt/live/my.server.name/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    location / {
        proxy_pass      http://127.0.0.1:5232/;
        proxy_set_header     X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass_header    Authorization;
    }
    location /radicale/ {
        proxy_pass      http://127.0.0.1:5232/;
        proxy_set_header     X-Script-Name /radicale;
        proxy_set_header     X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass_header    Authorization;
    }
}

That config was made after I found a comment how to setup radicale to work with iOS.

@sancoder
Copy link
Author

sancoder commented Apr 9, 2024

Sorry, I think the link to reddit is not the real source of the config. Looks like I saved a wrong one to my notes.

@pbiering
Copy link
Collaborator

pbiering commented Apr 9, 2024

Is it working now? If not, the related code is here: https://github.com/Kozea/Radicale/blob/master/radicale/app/move.py

Check also why your config misses

proxy_set_header  Host $http_host;

@sancoder
Copy link
Author

sancoder commented Apr 10, 2024

Investigated.
to_netloc_with_port = my.server.name:443
while
get_server_netloc(environ, force_port=True) = my.server.name:5232

Condition on line 57 of move.py fails, and we see "Unsupported destination"

@sancoder
Copy link
Author

My guess is that initial code was to compare netloc1 and netloc2 without ports but someone wanted to run several servers on one machine utilizing different ports, and hence comparison is with ports.
My expectation from radicale would be to work without comparing ports, so no issues when running behind reverse proxy. If someone (author?) has better alternative feel free to share.

@sancoder
Copy link
Author

sancoder commented Apr 10, 2024

That works (for me at least)

diff --git a/radicale/app/move.py b/radicale/app/move.py
index 5bd8a57..6df226b 100644
--- a/radicale/app/move.py
+++ b/radicale/app/move.py
@@ -27,7 +27,7 @@ from radicale.app.base import Access, ApplicationBase
 from radicale.log import logger
 
 
-def get_server_netloc(environ: types.WSGIEnviron, force_port: bool = False):
+def get_server_netloc(environ: types.WSGIEnviron):
     if environ.get("HTTP_X_FORWARDED_HOST"):
         host = environ["HTTP_X_FORWARDED_HOST"]
         proto = environ.get("HTTP_X_FORWARDED_PROTO") or "http"
@@ -37,10 +37,7 @@ def get_server_netloc(environ: types.WSGIEnviron, force_port: bool = False):
         host = environ.get("HTTP_HOST") or environ["SERVER_NAME"]
         proto = environ["wsgi.url_scheme"]
         port = environ["SERVER_PORT"]
-    if (not force_port and port == ("443" if proto == "https" else "80") or
-            re.search(r":\d+$", host)):
-        return host
-    return host + ":" + port
+    return host
 
 
 class ApplicationPartMove(ApplicationBase):
@@ -50,11 +47,7 @@ class ApplicationPartMove(ApplicationBase):
         """Manage MOVE request."""
         raw_dest = environ.get("HTTP_DESTINATION", "")
         to_url = urlparse(raw_dest)
-        to_netloc_with_port = to_url.netloc
-        if to_url.port is None:
-            to_netloc_with_port += (":443" if to_url.scheme == "https"
-                                    else ":80")
-        if to_netloc_with_port != get_server_netloc(environ, force_port=True):
+        if to_url.netloc != get_server_netloc(environ):
             logger.info("Unsupported destination address: %r", raw_dest)
             # Remote destination server, not supported
             return httputils.REMOTE_DESTINATION

@pbiering pbiering added this to the 3.2.0 milestone Apr 11, 2024
@pbiering
Copy link
Collaborator

will investigate next days

@pbiering
Copy link
Collaborator

pbiering commented May 3, 2024

Is your case also working if you simply change this line

-        if to_netloc_with_port != get_server_netloc(environ, force_port=True):
-        if to_netloc_with_port != get_server_netloc(environ, force_port=False):

BTW: nobody else is currently complaining about issues with MOVE since the last code change here (2023-04)

@sancoder
Copy link
Author

sancoder commented May 5, 2024

As I said above, to_netloc_with_port = my.server.name:443 so even if the right part of the condition will be without port, there is no chance it will work.

@sancoder
Copy link
Author

sancoder commented May 5, 2024

Is there a way to determine (in code) whether radicale is working behind reverse proxy? If yes, the condition should be without port, if no as it was.

@sancoder
Copy link
Author

sancoder commented May 5, 2024

BTW: I was considering not to use radicale because of the bug. Maybe this is the reason why noone else complains?

@pbiering
Copy link
Collaborator

pbiering commented May 6, 2024

"MOVE" is working fine behind an Apache reverse proxy using config sniplet from documentation
https://radicale.org/master.html#reverse-proxy

Can you add following line to your "nginx" configuration

    proxy_set_header  X-Forwarded-Proto "https";

This is conditionally set in the Apache example in case HTTPS is active, see also #1301, the examples for other reverse proxies are missing this still potentially.

@sancoder
Copy link
Author

sancoder commented May 9, 2024

Added header to nginx config.
Changed code back to as it was.
Restarted nginx, restarted radicale.
Created a test event, changed calendar for the event.
Same result (unsupported destination).

Honestly, I don't understand how is it effective to try different stuff and see what sticks to the wall. Maybe better is to understand what is happening (see result of my investigation above)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants