libidav/methods.c

changeset 171
254326cbc1bc
parent 170
cf054cded046
child 172
cd9f1e772fd0
equal deleted inserted replaced
170:cf054cded046 171:254326cbc1bc
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() {

mercurial