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 ---