281 char *ret = strdup(unesc); |
281 char *ret = strdup(unesc); |
282 curl_free(unesc); |
282 curl_free(unesc); |
283 return ret; |
283 return ret; |
284 } |
284 } |
285 |
285 |
|
286 static size_t util_header_callback(char *buffer, size_t size, |
|
287 size_t nitems, void *data) { |
|
288 |
|
289 char *duped; // local variable for string duplicates |
|
290 |
|
291 UcxMap *map = (UcxMap*) data; |
|
292 |
|
293 // if we get a status line, clear the map and exit |
|
294 if(size*nitems >= 5 && !strncmp("HTTP/", buffer, 5)) { |
|
295 ucx_map_free_content(map, free); |
|
296 ucx_map_clear(map); |
|
297 return size*nitems; |
|
298 } |
|
299 |
|
300 // if we get the terminating CRLF, just exit |
|
301 if (size*nitems == 2 && !strncmp("\r\n", buffer, 2)) { |
|
302 return 2; |
|
303 } |
|
304 |
|
305 |
|
306 // get header key |
|
307 size_t s = 0; |
|
308 do { |
|
309 s++; |
|
310 } while(buffer[s] != ':'); |
|
311 char *value = buffer+s+1; |
|
312 |
|
313 // remove trailing spaces |
|
314 while(isspace(buffer[s-1])) { |
|
315 s--; |
|
316 } |
|
317 |
|
318 // save key as all lower case |
|
319 duped = malloc(s); |
|
320 for(size_t i = 0;i<s;i++) { |
|
321 duped[i] = tolower(buffer[i]); |
|
322 } |
|
323 UcxKey key = ucx_key(duped, s); |
|
324 |
|
325 // get trimmed header value |
|
326 while(isspace(*value)) { |
|
327 value++; |
|
328 } |
|
329 s = size*nitems - (value - buffer); |
|
330 while(isspace(value[s-1])) { |
|
331 s--; |
|
332 } |
|
333 |
|
334 // copy header value and append NULL byte (curl does not provide one) |
|
335 duped = malloc(s+1); |
|
336 memcpy(duped, value, s+1); |
|
337 duped[s] = '\0'; |
|
338 |
|
339 char *oldval = ucx_map_get(map, key); |
|
340 if(oldval) { |
|
341 free(oldval); |
|
342 } |
|
343 |
|
344 ucx_map_put(map, key, duped); |
|
345 free(key.data); // ucx_map_put made a copy, so we free this memory |
|
346 |
|
347 return nitems * size; |
|
348 } |
|
349 |
|
350 void util_capture_header(CURL *handle, UcxMap* map) { |
|
351 if(!map) { |
|
352 // deactivate capturing |
|
353 curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, NULL); |
|
354 return; |
|
355 } |
|
356 |
|
357 curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, util_header_callback); |
|
358 curl_easy_setopt(handle, CURLOPT_HEADERDATA, map); |
|
359 } |
|
360 |
286 char* util_resource_name(char *url) { |
361 char* util_resource_name(char *url) { |
287 int si = 0; |
362 int si = 0; |
288 int osi = 0; |
363 int osi = 0; |
289 int i = 0; |
364 int i = 0; |
290 int p = 0; |
365 int p = 0; |