Skip to content

Commit 8bf9e03

Browse files
authored
Workarounds for servers not supporting multiplexing auth
Fixes #564
1 parent 146ca93 commit 8bf9e03

3 files changed

Lines changed: 55 additions & 10 deletions

File tree

AI_POLICY.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ started receiving pull requests with code changes generated by AI (and
1212
I've seen people posting screenshots of simple questions and answers
1313
from ChatGPT in forum discussions, without contributing anything else).
1414

15-
As of 2025-11, I've spent some time testing Claude. I'm actually
15+
As of 2025-12, I've spent some time testing Claude. I'm actually
1616
positively surprised, it's doing a much better job than what I had
1717
expected. The AI may do things faster, smarter and better than a good
1818
coder. Sometimes. Other times it may spend a lot of "tokens" and a
@@ -59,12 +59,12 @@ experiences is that the AI performs best when being "supervised" and
5959
should be informed about both in the pull request itself and in the
6060
git commit message. The most common way to do this is to add
6161
"Assisted-by: (name of AI-tool)" at the end of the message. Claude
62-
seems to sign off with "Co-Authored-By: Claude
63-
<noreply@anthropic.com>" when it's doing commits, that's also OK.
62+
seems to sign off with `Co-Authored-By: Claude
63+
<noreply@anthropic.com>` when it's doing commits, that's also OK.
6464

6565
* **YOU** should be ready to follow up and respond to feedback and
6666
questions on the contribution. If all you do is to relay it to the
67-
AI and relaying the AI thoughts back to the pull request, then
67+
AI and relaying the AI output back to the pull request, then
6868
you're not adding value to the project and you're not transparent
6969
and honest. You should at least do a quick QA on the AI-answer and
7070
acknowledge that it was generated by the AI.

caldav/compatibility_hints.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ class FeatureSet:
9292
"delete-calendar.free-namespace": {
9393
"description": "The delete operations clears the namespace, so that another calendar with the same ID/name can be created"
9494
},
95+
"http": { },
96+
"http.multiplexing": {
97+
"description": "chulka/baikal:nginx is having Problems with using HTTP/2 with multiplexing, ref https://github.com/python-caldav/caldav/issues/564. I haven't (yet) been able to reproduce this locally, so no check for this yet. We'll define it as fragile in the radicale config as for now"
98+
},
9599
"save-load": {
96100
"description": "it's possible to save and load objects to the calendar"
97101
},
@@ -264,6 +268,26 @@ def __init__(self, feature_set_dict=None):
264268
if feature_set_dict:
265269
self.copyFeatureSet(feature_set_dict, collapse=False)
266270

271+
272+
def set_feature(self, feature, value=True):
273+
if isinstance(value, dict):
274+
fc = {feature: value}
275+
elif isinstance(value, str):
276+
fc = {feature: {"support": value}}
277+
elif value is True:
278+
fc = {feature: {"support": "full"}}
279+
elif value is False:
280+
fc = {feature: {"support": "unsupported"}}
281+
elif value is None:
282+
fc = {feature: {"support": "unknown"}}
283+
else:
284+
assert False
285+
self.copyFeatureSet(fc, collapse=False)
286+
feat_def = self.find_feature(feature)
287+
feat_type = feat_def.get('type', 'server-feature')
288+
sup = fc[feature].get('support', feat_def.get('default', 'full'))
289+
290+
267291
## TODO: Why is this camelCase while every other method is with under_score? rename ...
268292
def copyFeatureSet(self, feature_set, collapse=True):
269293
for feature in feature_set:
@@ -880,6 +904,7 @@ def dotted_feature_set_list(self, compact=False):
880904
}
881905

882906
baikal = { ## version 0.10.1
907+
"http.multiplexing": "fragile", ## ref https://github.com/python-caldav/caldav/issues/564
883908
"save-load.journal": {'support': 'ungraceful'},
884909
#'search.comp-type-optional': {'support': 'ungraceful'}, ## Possibly this has been fixed?
885910
'search.recurrences.expanded.todo': {'support': 'unsupported'},

caldav/davclient.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -599,18 +599,19 @@ def __init__(
599599
"""
600600
headers = headers or {}
601601

602-
## Deprecation TODO: give a warning, user should use get_davclient or auto_calendar instead
603-
604-
try:
605-
self.session = requests.Session(multiplexed=True)
606-
except TypeError:
607-
self.session = requests.Session()
602+
## Deprecation TODO: give a warning, user should use get_davclient or auto_calendar instead. Probably.
608603

609604
if isinstance(features, str):
610605
features = getattr(caldav.compatibility_hints, features)
611606
self.features = FeatureSet(features)
612607
self.huge_tree = huge_tree
613608

609+
try:
610+
multiplexed = self.features.is_supported("http.multiplexing")
611+
self.session = requests.Session(multiplexed=multiplexed)
612+
except TypeError:
613+
self.session = requests.Session()
614+
614615
url, discovered_username = _auto_url(
615616
url,
616617
self.features,
@@ -1100,6 +1101,24 @@ def request(
11001101
and self.password
11011102
and isinstance(self.password, bytes)
11021103
):
1104+
## TODO: this has become a mess and should be refactored.
1105+
## (Arguably, this logic doesn't belong here at all.
1106+
## with niquests it's possible to just pass the username
1107+
## and password, maybe we should try that?)
1108+
1109+
## Most likely we're here due to wrong username/password
1110+
## combo, but it could also be a multiplexing problem.
1111+
if (
1112+
self.features.is_supported("http.multiplexing", return_defaults=False)
1113+
is None
1114+
):
1115+
self.session = requests.Session()
1116+
self.features.set_feature("http.multiplexing", "unknown")
1117+
## If this one also fails, we give up
1118+
ret = self.request(str(url_obj), method, body, headers)
1119+
self.features.set_feature("http.multiplexing", False)
1120+
return ret
1121+
11031122
## Most likely we're here due to wrong username/password
11041123
## combo, but it could also be charset problems. Some
11051124
## (ancient) servers don't like UTF-8 binary auth with
@@ -1115,6 +1134,7 @@ def request(
11151134

11161135
self.username = None
11171136
self.password = None
1137+
11181138
return self.request(str(url_obj), method, body, headers)
11191139

11201140
if error.debug_dump_communication:

0 commit comments

Comments
 (0)