52 long follow = 0; |
52 long follow = 0; |
53 curl_easy_getinfo(handle, CURLOPT_FOLLOWLOCATION, &follow); |
53 curl_easy_getinfo(handle, CURLOPT_FOLLOWLOCATION, &follow); |
54 curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 0L); |
54 curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 0L); |
55 const int maxredirect = 16; |
55 const int maxredirect = 16; |
56 |
56 |
|
57 // always try to get information about possible children |
|
58 int depth = 1; |
|
59 |
57 struct curl_slist *headers = NULL; |
60 struct curl_slist *headers = NULL; |
58 CURLcode ret = 0; |
61 CURLcode ret = 0; |
59 |
62 |
60 curl_easy_setopt(handle, CURLOPT_UPLOAD, 1); |
63 curl_easy_setopt(handle, CURLOPT_UPLOAD, 1); |
61 curl_easy_setopt(handle, CURLOPT_READFUNCTION, ucx_buffer_read); |
64 curl_easy_setopt(handle, CURLOPT_READFUNCTION, ucx_buffer_read); |
62 curl_easy_setopt(handle, CURLOPT_READDATA, request); |
65 curl_easy_setopt(handle, CURLOPT_READDATA, request); |
63 curl_easy_setopt(handle, CURLOPT_INFILESIZE, request->size); |
66 curl_easy_setopt(handle, CURLOPT_INFILESIZE, request->size); |
64 |
67 |
65 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, ucx_buffer_write); |
68 curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, ucx_buffer_write); |
66 curl_easy_setopt(handle, CURLOPT_WRITEDATA, response); |
69 curl_easy_setopt(handle, CURLOPT_WRITEDATA, response); |
|
70 UcxMap *respheaders = ucx_map_new(32); |
|
71 util_capture_header(handle, respheaders); |
67 |
72 |
68 for(int i=0;i<=maxredirect;i++) { |
73 for(int i=0;i<=maxredirect;i++) { |
69 char *url = NULL; |
74 char *url = NULL; |
70 curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url); |
75 curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url); |
71 if(url) { |
76 if(url) { |
72 size_t ulen = strlen(url); |
77 size_t ulen = strlen(url); |
73 if(ulen > 0) { |
78 if(ulen > 0) { |
74 if(url[ulen-1] == '/') { |
79 if (depth == 1) { |
75 headers = curl_slist_append(headers, "Depth: 1"); |
80 headers = curl_slist_append(headers, "Depth: 1"); |
76 } else { |
81 } else { |
77 headers = curl_slist_append(headers, "Depth: 0"); |
82 headers = curl_slist_append(headers, "Depth: 0"); |
78 } |
83 } |
79 } else { |
84 } else { |
90 response->size = response->pos = 0; |
95 response->size = response->pos = 0; |
91 ret = curl_easy_perform(handle); |
96 ret = curl_easy_perform(handle); |
92 curl_slist_free_all(headers); |
97 curl_slist_free_all(headers); |
93 headers = NULL; |
98 headers = NULL; |
94 |
99 |
95 // continue work with URL we get from the server! |
100 /* |
|
101 * Handle three cases: |
|
102 * 1. We get a Location header (it's a redirect) |
|
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 |
|
106 * 3. Other cases |
|
107 * => the server handled our request and we can stop requesting |
|
108 */ |
96 char *location = NULL; |
109 char *location = NULL; |
|
110 char *msdavexterror; |
97 curl_easy_getinfo(handle, CURLINFO_REDIRECT_URL, &location); |
111 curl_easy_getinfo(handle, CURLINFO_REDIRECT_URL, &location); |
|
112 msdavexterror = ucx_map_cstr_get(respheaders, "x-msdavext_error"); |
|
113 int iishack = depth == 1 && |
|
114 msdavexterror && !strncmp(msdavexterror, "589831;", 7); |
|
115 |
98 if(location) { |
116 if(location) { |
99 // redirect |
117 // redirect |
100 curl_easy_setopt(handle, CURLOPT_URL, location); |
118 curl_easy_setopt(handle, CURLOPT_URL, location); |
|
119 } else if(iishack) { |
|
120 depth = 0; |
101 } else { |
121 } else { |
102 break; |
122 break; |
103 } |
123 } |
104 } |
124 } |
|
125 |
|
126 ucx_map_free_content(respheaders, free); |
|
127 ucx_map_free(respheaders); |
105 |
128 |
106 // reset followlocation option |
129 // reset followlocation option |
107 curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, follow); |
130 curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, follow); |
108 |
131 |
109 return ret; |
132 return ret; |