46 UcxBuffer *request, |
46 UcxBuffer *request, |
47 UcxBuffer *response) |
47 UcxBuffer *response) |
48 { |
48 { |
49 curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "PROPFIND"); |
49 curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "PROPFIND"); |
50 |
50 |
51 // implement own redirection follower |
|
52 long follow = 0; |
|
53 curl_easy_getinfo(handle, CURLOPT_FOLLOWLOCATION, &follow); |
|
54 curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 0L); |
|
55 const int maxredirect = 16; |
|
56 |
|
57 // always try to get information about possible children |
51 // always try to get information about possible children |
58 int depth = 1; |
52 int depth = 1; |
|
53 |
|
54 int maxretry = 2; |
59 |
55 |
60 struct curl_slist *headers = NULL; |
56 struct curl_slist *headers = NULL; |
61 CURLcode ret = 0; |
57 CURLcode ret = 0; |
62 |
58 |
63 curl_easy_setopt(handle, CURLOPT_UPLOAD, 1); |
59 curl_easy_setopt(handle, CURLOPT_UPLOAD, 1); |
68 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, ucx_buffer_write); |
64 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, ucx_buffer_write); |
69 curl_easy_setopt(handle, CURLOPT_WRITEDATA, response); |
65 curl_easy_setopt(handle, CURLOPT_WRITEDATA, response); |
70 UcxMap *respheaders = ucx_map_new(32); |
66 UcxMap *respheaders = ucx_map_new(32); |
71 util_capture_header(handle, respheaders); |
67 util_capture_header(handle, respheaders); |
72 |
68 |
73 for(int i=0;i<=maxredirect;i++) { |
69 for(int i=0;i<maxretry;i++) { |
74 char *url = NULL; |
70 if (depth == 1) { |
75 curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url); |
71 headers = curl_slist_append(headers, "Depth: 1"); |
76 if(url) { |
72 } else if (depth == -1) { |
77 size_t ulen = strlen(url); |
73 headers = curl_slist_append(headers, "Depth: infinity"); |
78 if(ulen > 0) { |
|
79 if (depth == 1) { |
|
80 headers = curl_slist_append(headers, "Depth: 1"); |
|
81 } else { |
|
82 headers = curl_slist_append(headers, "Depth: 0"); |
|
83 } |
|
84 } else { |
|
85 return CURLE_URL_MALFORMAT; |
|
86 } |
|
87 } else { |
74 } else { |
88 return CURLE_URL_MALFORMAT; |
75 headers = curl_slist_append(headers, "Depth: 0"); |
89 } |
76 } |
90 headers = curl_slist_append(headers, "Content-Type: text/xml"); |
77 headers = curl_slist_append(headers, "Content-Type: text/xml"); |
91 curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); |
78 curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); |
92 |
79 |
93 // reset buffers and perform request |
80 // reset buffers and perform request |
96 ret = curl_easy_perform(handle); |
83 ret = curl_easy_perform(handle); |
97 curl_slist_free_all(headers); |
84 curl_slist_free_all(headers); |
98 headers = NULL; |
85 headers = NULL; |
99 |
86 |
100 /* |
87 /* |
101 * Handle three cases: |
88 * Handle two cases: |
102 * 1. We get a Location header (it's a redirect) |
89 * 1. We communicate with IIS and get a X-MSDAVEXT_Error: 589831 |
103 * => follow the URL we get from the server |
|
104 * 2. We communicate with IIS and get a X-MSDAVEXT_Error: 589831 |
|
105 * => try with depth 0 next time, it's not a collection |
90 * => try with depth 0 next time, it's not a collection |
106 * 3. Other cases |
91 * 2. Other cases |
107 * => the server handled our request and we can stop requesting |
92 * => the server handled our request and we can stop requesting |
108 */ |
93 */ |
109 char *location = NULL; |
|
110 char *msdavexterror; |
94 char *msdavexterror; |
111 curl_easy_getinfo(handle, CURLINFO_REDIRECT_URL, &location); |
|
112 msdavexterror = ucx_map_cstr_get(respheaders, "x-msdavext_error"); |
95 msdavexterror = ucx_map_cstr_get(respheaders, "x-msdavext_error"); |
113 int iishack = depth == 1 && |
96 int iishack = depth == 1 && |
114 msdavexterror && !strncmp(msdavexterror, "589831;", 7); |
97 msdavexterror && !strncmp(msdavexterror, "589831;", 7); |
115 |
98 |
116 if(location) { |
99 if(iishack) { |
117 // redirect |
|
118 curl_easy_setopt(handle, CURLOPT_URL, location); |
|
119 } else if(iishack) { |
|
120 depth = 0; |
100 depth = 0; |
121 } else { |
101 } else { |
122 break; |
102 break; |
123 } |
103 } |
124 } |
104 } |
125 |
105 |
126 ucx_map_free_content(respheaders, free); |
106 ucx_map_free_content(respheaders, free); |
127 ucx_map_free(respheaders); |
107 ucx_map_free(respheaders); |
128 |
|
129 // reset followlocation option |
|
130 curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, follow); |
|
131 |
108 |
132 return ret; |
109 return ret; |
133 } |
110 } |
134 |
111 |
135 UcxBuffer* create_allprop_propfind_request() { |
112 UcxBuffer* create_allprop_propfind_request() { |