libidav/utils.c

changeset 173
947843245525
parent 170
cf054cded046
child 174
e7e56c56d126
equal deleted inserted replaced
171:254326cbc1bc 173:947843245525
284 } 284 }
285 285
286 static size_t util_header_callback(char *buffer, size_t size, 286 static size_t util_header_callback(char *buffer, size_t size,
287 size_t nitems, void *data) { 287 size_t nitems, void *data) {
288 288
289 char *duped; // local variable for string duplicates 289 sstr_t sbuffer = sstrn(buffer, size*nitems);
290 290
291 UcxMap *map = (UcxMap*) data; 291 UcxMap *map = (UcxMap*) data;
292 292
293 // if we get a status line, clear the map and exit 293 // if we get a status line, clear the map and exit
294 if(size*nitems >= 5 && !strncmp("HTTP/", buffer, 5)) { 294 if(sstrprefix(sbuffer, S("HTTP/"))) {
295 ucx_map_free_content(map, free); 295 ucx_map_free_content(map, free);
296 ucx_map_clear(map); 296 ucx_map_clear(map);
297 return size*nitems; 297 return size*nitems;
298 } 298 }
299 299
300 // if we get the terminating CRLF, just exit 300 // if we get the terminating CRLF, just exit
301 if (size*nitems == 2 && !strncmp("\r\n", buffer, 2)) { 301 if(!sstrcmp(sbuffer, S("\r\n"))) {
302 return 2; 302 return 2;
303 } 303 }
304 304
305 305 sstr_t key = sbuffer;
306 // get header key 306 sstr_t value = sstrchr(sbuffer, ':');
307 size_t s = 0; 307
308 do { 308 if(value.length == 0) {
309 s++; 309 return 0; // invalid header line
310 } while(buffer[s] != ':'); 310 }
311 char *value = buffer+s+1; 311
312 312 key.length = value.ptr - key.ptr;
313 // remove trailing spaces 313 value.ptr++; value.length--;
314 while(isspace(buffer[s-1])) { 314
315 s--; 315 key = sstrdup(sstrtrim(key));
316 } 316 value = sstrdup(sstrtrim(value));
317 317
318 // save key as all lower case 318 for(size_t i = 0;i<key.length;i++) {
319 duped = malloc(s); 319 key.ptr[i] = tolower(key.ptr[i]);
320 for(size_t i = 0;i<s;i++) { 320 }
321 duped[i] = tolower(buffer[i]); 321
322 } 322 ucx_map_sstr_put(map, key, value.ptr);
323 UcxKey key = ucx_key(duped, s); 323
324 324 free(key.ptr);
325 // get trimmed header value 325
326 while(isspace(*value)) { 326 return sbuffer.length;
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 } 327 }
349 328
350 void util_capture_header(CURL *handle, UcxMap* map) { 329 void util_capture_header(CURL *handle, UcxMap* map) {
351 if(!map) { 330 if(!map) {
352 // deactivate capturing 331 // deactivate capturing

mercurial