libidav/methods.c

changeset 170
cf054cded046
parent 166
8911170d5e78
child 171
254326cbc1bc
equal deleted inserted replaced
169:08adb4f87160 170:cf054cded046
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;

mercurial