curl.c (128dc2d1e4cb98ddbe9c0df2e0c914dc00925dac) | curl.c (3494d650273e619606c6cb2c38aa9b8b7bed98e2) |
---|---|
1/* 2 * QEMU Block driver for CURL images 3 * 4 * Copyright (c) 2009 Alexander Graf <agraf@suse.de> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights --- 67 unchanged lines hidden (view full) --- 76} CURLState; 77 78typedef struct BDRVCURLState { 79 CURLM *multi; 80 size_t len; 81 CURLState states[CURL_NUM_STATES]; 82 char *url; 83 size_t readahead_size; | 1/* 2 * QEMU Block driver for CURL images 3 * 4 * Copyright (c) 2009 Alexander Graf <agraf@suse.de> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights --- 67 unchanged lines hidden (view full) --- 76} CURLState; 77 78typedef struct BDRVCURLState { 79 CURLM *multi; 80 size_t len; 81 CURLState states[CURL_NUM_STATES]; 82 char *url; 83 size_t readahead_size; |
84 bool accept_range; |
|
84} BDRVCURLState; 85 86static void curl_clean_state(CURLState *s); 87static void curl_multi_do(void *arg); 88static int curl_aio_flush(void *opaque); 89 90static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action, 91 void *s, void *sp) --- 13 unchanged lines hidden (view full) --- 105 case CURL_POLL_REMOVE: 106 qemu_aio_set_fd_handler(fd, NULL, NULL, NULL, NULL); 107 break; 108 } 109 110 return 0; 111} 112 | 85} BDRVCURLState; 86 87static void curl_clean_state(CURLState *s); 88static void curl_multi_do(void *arg); 89static int curl_aio_flush(void *opaque); 90 91static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action, 92 void *s, void *sp) --- 13 unchanged lines hidden (view full) --- 106 case CURL_POLL_REMOVE: 107 qemu_aio_set_fd_handler(fd, NULL, NULL, NULL, NULL); 108 break; 109 } 110 111 return 0; 112} 113 |
113static size_t curl_size_cb(void *ptr, size_t size, size_t nmemb, void *opaque) | 114static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque) |
114{ | 115{ |
115 CURLState *s = ((CURLState*)opaque); | 116 BDRVCURLState *s = opaque; |
116 size_t realsize = size * nmemb; | 117 size_t realsize = size * nmemb; |
117 size_t fsize; | 118 const char *accept_line = "Accept-Ranges: bytes"; |
118 | 119 |
119 if(sscanf(ptr, "Content-Length: %zd", &fsize) == 1) { 120 s->s->len = fsize; | 120 if (realsize >= strlen(accept_line) 121 && strncmp((char *)ptr, accept_line, strlen(accept_line)) == 0) { 122 s->accept_range = true; |
121 } 122 123 return realsize; 124} 125 126static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque) 127{ 128 CURLState *s = ((CURLState*)opaque); --- 313 unchanged lines hidden (view full) --- 442 DPRINTF("CURL: Opening %s\n", file); 443 s->url = g_strdup(file); 444 state = curl_init_state(s); 445 if (!state) 446 goto out_noclean; 447 448 // Get file size 449 | 123 } 124 125 return realsize; 126} 127 128static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque) 129{ 130 CURLState *s = ((CURLState*)opaque); --- 313 unchanged lines hidden (view full) --- 444 DPRINTF("CURL: Opening %s\n", file); 445 s->url = g_strdup(file); 446 state = curl_init_state(s); 447 if (!state) 448 goto out_noclean; 449 450 // Get file size 451 |
452 s->accept_range = false; |
|
450 curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1); | 453 curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1); |
451 curl_easy_setopt(state->curl, CURLOPT_WRITEFUNCTION, (void *)curl_size_cb); | 454 curl_easy_setopt(state->curl, CURLOPT_HEADERFUNCTION, 455 curl_header_cb); 456 curl_easy_setopt(state->curl, CURLOPT_HEADERDATA, s); |
452 if (curl_easy_perform(state->curl)) 453 goto out; 454 curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d); 455 if (d) 456 s->len = (size_t)d; 457 else if(!s->len) 458 goto out; | 457 if (curl_easy_perform(state->curl)) 458 goto out; 459 curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d); 460 if (d) 461 s->len = (size_t)d; 462 else if(!s->len) 463 goto out; |
464 if ((!strncasecmp(s->url, "http://", strlen("http://")) 465 || !strncasecmp(s->url, "https://", strlen("https://"))) 466 && !s->accept_range) { 467 pstrcpy(state->errmsg, CURL_ERROR_SIZE, 468 "Server does not support 'range' (byte ranges)."); 469 goto out; 470 } |
|
459 DPRINTF("CURL: Size = %zd\n", s->len); 460 461 curl_clean_state(state); 462 curl_easy_cleanup(state->curl); 463 state->curl = NULL; 464 465 // Now we know the file exists and its size, so let's 466 // initialize the multi interface! --- 227 unchanged lines hidden --- | 471 DPRINTF("CURL: Size = %zd\n", s->len); 472 473 curl_clean_state(state); 474 curl_easy_cleanup(state->curl); 475 state->curl = NULL; 476 477 // Now we know the file exists and its size, so let's 478 // initialize the multi interface! --- 227 unchanged lines hidden --- |