1//========================================================================
2//
3// CurlCachedFile.cc
4//
5// This file is licensed under the GPLv2 or later
6//
7// Copyright 2009 Stefan Thomas <thomas@eload24.com>
8// Copyright 2010, 2011 Hib Eris <hib@hiberis.nl>
9// Copyright 2010, 2019, 2021, 2022 Albert Astals Cid <aacid@kde.org>
10//
11//========================================================================
12
13#include <config.h>
14
15#include "CurlCachedFile.h"
16
17#include "goo/GooString.h"
18
19//------------------------------------------------------------------------
20
21CurlCachedFileLoader::CurlCachedFileLoader(const std::string &urlA) : url(urlA)
22{
23 cachedFile = nullptr;
24 curl = nullptr;
25}
26
27CurlCachedFileLoader::~CurlCachedFileLoader()
28{
29 curl_easy_cleanup(curl);
30}
31
32static size_t noop_cb(char *ptr, size_t size, size_t nmemb, void *ptr2)
33{
34 return size * nmemb;
35}
36
37size_t CurlCachedFileLoader::init(CachedFile *cachedFileA)
38{
39 curl_off_t contentLength = -1;
40 long code = 0;
41 size_t size;
42
43 cachedFile = cachedFileA;
44 curl = curl_easy_init();
45
46 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
47 curl_easy_setopt(curl, CURLOPT_HEADER, 1);
48 curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
49 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &noop_cb);
50 curl_easy_perform(curl);
51 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
52 if (code) {
53 curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &contentLength);
54 size = contentLength;
55 } else {
56 error(category: errInternal, pos: -1, msg: "Failed to get size of '{0:s}'.", url.c_str());
57 size = -1;
58 }
59 curl_easy_reset(curl);
60
61 return size;
62}
63
64static size_t load_cb(const char *ptr, size_t size, size_t nmemb, void *data)
65{
66 CachedFileWriter *writer = (CachedFileWriter *)data;
67 return (writer->write)(ptr, size: size * nmemb);
68}
69
70int CurlCachedFileLoader::load(const std::vector<ByteRange> &ranges, CachedFileWriter *writer)
71{
72 CURLcode r = CURLE_OK;
73 unsigned long long fromByte, toByte;
74 for (const ByteRange &bRange : ranges) {
75
76 fromByte = bRange.offset;
77 toByte = fromByte + bRange.length - 1;
78 const std::unique_ptr<GooString> range = GooString::format(fmt: "{0:ulld}-{1:ulld}", fromByte, toByte);
79
80 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
81 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, load_cb);
82 curl_easy_setopt(curl, CURLOPT_WRITEDATA, writer);
83 curl_easy_setopt(curl, CURLOPT_RANGE, range->c_str());
84 r = curl_easy_perform(curl);
85 curl_easy_reset(curl);
86
87 if (r != CURLE_OK) {
88 break;
89 }
90 }
91 return r;
92}
93
94//------------------------------------------------------------------------
95

source code of poppler/poppler/CurlCachedFile.cc