Answer the addressbook ctag PROPFIND minimally
Minimization round 1: that ask names exactly getctag and sync-token,
so the other collection properties and the 404-propstat block are
dropped. If macOS stalls here, bisect by adding them back one at a
time, most likely resourcetype or supported-report-set first.

Assisted-by: GLM 5.2 via pi
change nyslmutrwlzkslvxpyzntvxxyymtnnmk
commit 8d82ae6ba4382e80b895c21e310fc27aac016b58
author Alpha Chen <alpha@kejadlen.dev>
date
parent xvmtzzzp
diff --git a/lib/pro_tacts/web.rb b/lib/pro_tacts/web.rb
index 7709388..9483607 100644
--- a/lib/pro_tacts/web.rb
+++ b/lib/pro_tacts/web.rb
@@ -200,61 +200,16 @@ module ProTacts
               XML
             else
               # Full property request (Depth:0 collection info)
-              supported_props = <<~XML
-                <d:displayname>Contacts</d:displayname>
-                <d:resourcetype>
-                  <d:collection/>
-                  <card:addressbook/>
-                </d:resourcetype>
-                <d:supported-report-set>
-                  <d:supported-report>
-                    <d:report><card:addressbook-multiget/></d:report>
-                  </d:supported-report>
-                  <d:supported-report>
-                    <d:report><card:addressbook-query/></d:report>
-                  </d:supported-report>
-                  <d:supported-report>
-                    <d:report><d:sync-collection/></d:report>
-                  </d:supported-report>
-                </d:supported-report-set>
-                <d:sync-token>http://pro-tacts/sync/1</d:sync-token>
-                <d:current-user-privilege-set>
-                  <d:privilege><d:read/></d:privilege>
-                  <d:privilege><d:write/></d:privilege>
-                </d:current-user-privilege-set>
-                <d:owner>
-                  <d:href>/dav/principal/</d:href>
-                </d:owner>
-                <card:max-resource-size>102400</card:max-resource-size>
-                <cs:getctag>#{collection_ctag}</cs:getctag>
-              XML
-
-              unsupported_props = <<~XML
-                <d:add-member/>
-                <d:quota-available-bytes/>
-                <d:quota-used-bytes/>
-                <d:resource-id/>
-                <card:max-image-size/>
-                <cs:me-card/>
-                <cs:push-transports/>
-                <cs:pushkey/>
-              XML
-
               collection_response = <<~XML
                 <d:response>
                   <d:href>/dav/addressbook/</d:href>
                   <d:propstat>
                     <d:prop>
-                      #{supported_props}
+                      <cs:getctag>#{collection_ctag}</cs:getctag>
+                      <d:sync-token>http://pro-tacts/sync/1</d:sync-token>
                     </d:prop>
                     <d:status>HTTP/1.1 200 OK</d:status>
                   </d:propstat>
-                  <d:propstat>
-                    <d:prop>
-                      #{unsupported_props}
-                    </d:prop>
-                    <d:status>HTTP/1.1 404 Not Found</d:status>
-                  </d:propstat>
                 </d:response>
               XML
 
@@ -264,7 +219,6 @@ module ProTacts
                   <d:propstat>
                     <d:prop>
                       <d:getetag>#{contact_etag}</d:getetag>
-                      <d:resourcetype/>
                     </d:prop>
                     <d:status>HTTP/1.1 200 OK</d:status>
                   </d:propstat>
diff --git a/test/fixtures/macos-exchange/05-propfind-addressbook-ctag/response b/test/fixtures/macos-exchange/05-propfind-addressbook-ctag/response
index f664764..727e6d6 100644
--- a/test/fixtures/macos-exchange/05-propfind-addressbook-ctag/response
+++ b/test/fixtures/macos-exchange/05-propfind-addressbook-ctag/response
@@ -7,50 +7,11 @@ Content-Type: text/xml
   <d:href>/dav/addressbook/</d:href>
   <d:propstat>
     <d:prop>
-      <d:displayname>Contacts</d:displayname>
-<d:resourcetype>
-  <d:collection/>
-  <card:addressbook/>
-</d:resourcetype>
-<d:supported-report-set>
-  <d:supported-report>
-    <d:report><card:addressbook-multiget/></d:report>
-  </d:supported-report>
-  <d:supported-report>
-    <d:report><card:addressbook-query/></d:report>
-  </d:supported-report>
-  <d:supported-report>
-    <d:report><d:sync-collection/></d:report>
-  </d:supported-report>
-</d:supported-report-set>
-<d:sync-token>http://pro-tacts/sync/1</d:sync-token>
-<d:current-user-privilege-set>
-  <d:privilege><d:read/></d:privilege>
-  <d:privilege><d:write/></d:privilege>
-</d:current-user-privilege-set>
-<d:owner>
-  <d:href>/dav/principal/</d:href>
-</d:owner>
-<card:max-resource-size>102400</card:max-resource-size>
-<cs:getctag>ctag-1</cs:getctag>
-
+      <cs:getctag>ctag-1</cs:getctag>
+      <d:sync-token>http://pro-tacts/sync/1</d:sync-token>
     </d:prop>
     <d:status>HTTP/1.1 200 OK</d:status>
   </d:propstat>
-  <d:propstat>
-    <d:prop>
-      <d:add-member/>
-<d:quota-available-bytes/>
-<d:quota-used-bytes/>
-<d:resource-id/>
-<card:max-image-size/>
-<cs:me-card/>
-<cs:push-transports/>
-<cs:pushkey/>
-
-    </d:prop>
-    <d:status>HTTP/1.1 404 Not Found</d:status>
-  </d:propstat>
 </d:response>