GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/network/jobinfo.h
Date: 2026-04-26 02:35:59
Exec Total Coverage
Lines: 77 113 68.1%
Branches: 2 10 20.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_NETWORK_JOBINFO_H_
6 #define CVMFS_NETWORK_JOBINFO_H_
7
8 #include <poll.h>
9 #include <pthread.h>
10 #include <stdint.h>
11 #include <unistd.h>
12
13 #include <cstdio>
14 #include <string>
15
16 #include "compression/compression.h"
17 #include "crypto/hash.h"
18 #include "duplex_curl.h" // IWYU pragma: keep
19 #include "network/network_errors.h"
20 #include "network/sink.h"
21 #include "util/pipe.h"
22 #include "util/pointer.h"
23 #include "util/tube.h"
24
25 class InterruptCue;
26
27 namespace download {
28
29 enum DataTubeAction {
30 kActionStop = 0,
31 kActionContinue,
32 kActionDecompress
33 };
34
35 /**
36 * Wrapper for the data tube to transfer data from CallbackCurlData() that is
37 * executed in MainDownload() Thread to Fetch() called by a fuse thread
38 *
39 * TODO(heretherebedragons): do we want to have a pool of those
40 * datatubeelements?
41 */
42 struct DataTubeElement : SingleCopy {
43 char *data;
44 size_t size;
45 DataTubeAction action;
46
47 explicit DataTubeElement(DataTubeAction xact)
48 : data(NULL), size(0), action(xact) { }
49 DataTubeElement(char *mov_data, size_t xsize, DataTubeAction xact)
50 : data(mov_data), size(xsize), action(xact) { }
51
52 ~DataTubeElement() { delete data; }
53 };
54
55 /**
56 * Contains all the information to specify a download job.
57 */
58 class JobInfo {
59 private:
60 static atomic_int64 next_uuid;
61 int64_t id_;
62 /// Pipe used for the return value
63 UniquePtr<Pipe<kPipeDownloadJobsResults> > pipe_job_results;
64 /// Tube (bounded thread-safe queue) to transport data from CURL callback
65 /// to be decompressed in Fetch() instead of MainDownload()
66 UniquePtr<Tube<DataTubeElement> > data_tube_;
67 const std::string *url_;
68 bool compressed_;
69 bool probe_hosts_;
70 bool head_request_;
71 bool follow_redirects_;
72 bool force_nocache_;
73 pid_t pid_;
74 uid_t uid_;
75 gid_t gid_;
76 void *cred_data_; // Per-transfer credential data
77 InterruptCue *interrupt_cue_;
78 cvmfs::Sink *sink_;
79 const shash::Any *expected_hash_;
80 const std::string *path_info_;
81
82 // Allow byte ranges to be specified.
83 off_t range_offset_;
84 off_t range_size_;
85
86 // Internal state
87 CURL *curl_handle_;
88 curl_slist *headers_;
89 char *info_header_;
90 char *tracing_header_pid_;
91 char *tracing_header_gid_;
92 char *tracing_header_uid_;
93 z_stream zstream_;
94 shash::ContextPtr hash_context_;
95 std::string proxy_;
96 std::string link_;
97 bool nocache_;
98 Failures error_code_;
99 int http_code_;
100 unsigned char num_used_proxies_;
101 unsigned char num_used_metalinks_;
102 unsigned char num_used_hosts_;
103 unsigned char num_retries_;
104 unsigned backoff_ms_;
105 int current_metalink_chain_index_;
106 int current_host_chain_index_;
107
108 // Don't fail-over proxies on download errors. default = false
109 bool allow_failure_;
110
111 // TODO(heretherebedragons) c++11 allows to delegate constructors (N1986)
112 // Replace Init() with JobInfo() that is called by the other constructors
113 void Init();
114
115 public:
116 /**
117 * Sink version: downloads entire data chunk where URL u points to
118 */
119 JobInfo(const std::string *u, const bool c, const bool ph,
120 const shash::Any *h, cvmfs::Sink *s);
121
122 /**
123 * No sink version: Only downloads header where the URL u points to
124 */
125 JobInfo(const std::string *u, const bool ph);
126
127 4765 ~JobInfo() {
128 4765 pipe_job_results.Destroy();
129 4765 data_tube_.Destroy();
130 4765 }
131
132 static bool EscapeUrlChar(unsigned char input, char output[3]);
133
134 void CreatePipeJobResults() {
135 pipe_job_results = new Pipe<kPipeDownloadJobsResults>();
136 }
137
138 bool IsValidPipeJobResults() { return pipe_job_results.IsValid(); }
139
140 void CreateDataTube() {
141 // TODO(heretherebedragons) change to weighted queue
142 data_tube_ = new Tube<DataTubeElement>(500);
143 }
144
145 bool IsValidDataTube() { return data_tube_.IsValid(); }
146
147 /**
148 * Tells whether the error is because of a non-existing file. Should only
149 * be called if error_code is not kFailOk
150 */
151 bool IsFileNotFound();
152
153 1274 pid_t *GetPidPtr() { return &pid_; }
154 1274 uid_t *GetUidPtr() { return &uid_; }
155 1274 gid_t *GetGidPtr() { return &gid_; }
156 1274 InterruptCue **GetInterruptCuePtr() { return &interrupt_cue_; }
157 9806 z_stream *GetZstreamPtr() { return &zstream_; }
158 Failures *GetErrorCodePtr() { return &error_code_; }
159 void **GetCredDataPtr() { return &cred_data_; }
160 curl_slist **GetHeadersPtr() { return &headers_; }
161 CURL **GetCurlHandle() { return &curl_handle_; }
162 9804 shash::ContextPtr *GetHashContextPtr() { return &hash_context_; }
163 Pipe<kPipeDownloadJobsResults> *GetPipeJobResultPtr() {
164 return pipe_job_results.weak_ref();
165 }
166 Tube<DataTubeElement> *GetDataTubePtr() { return data_tube_.weak_ref(); }
167
168 15424 const std::string *url() const { return url_; }
169 16650 bool compressed() const { return compressed_; }
170 5478 bool probe_hosts() const { return probe_hosts_; }
171 4984 bool head_request() const { return head_request_; }
172 132 bool follow_redirects() const { return follow_redirects_; }
173 4984 bool force_nocache() const { return force_nocache_; }
174 pid_t pid() const { return pid_; }
175 uid_t uid() const { return uid_; }
176 gid_t gid() const { return gid_; }
177 5116 void *cred_data() const { return cred_data_; }
178 344 InterruptCue *interrupt_cue() const { return interrupt_cue_; }
179 78528 cvmfs::Sink *sink() const { return sink_; }
180 33002 const shash::Any *expected_hash() const { return expected_hash_; }
181 const std::string *path_info() const { return path_info_; }
182
183 4984 off_t range_offset() const { return range_offset_; }
184 off_t range_size() const { return range_size_; }
185
186 20510 CURL *curl_handle() const { return curl_handle_; }
187 15114 curl_slist *headers() const { return headers_; }
188 4984 char *info_header() const { return info_header_; }
189 char *tracing_header_pid() const { return tracing_header_pid_; }
190 char *tracing_header_gid() const { return tracing_header_gid_; }
191 char *tracing_header_uid() const { return tracing_header_uid_; }
192 z_stream zstream() const { return zstream_; }
193 16334 shash::ContextPtr hash_context() const { return hash_context_; }
194 11022 std::string proxy() const { return proxy_; }
195 std::string link() const { return link_; }
196 5934 bool nocache() const { return nocache_; }
197 20700 Failures error_code() const { return error_code_; }
198 688 int http_code() const { return http_code_; }
199 132 unsigned char num_used_proxies() const { return num_used_proxies_; }
200 unsigned char num_used_metalinks() const { return num_used_metalinks_; }
201 5416 unsigned char num_used_hosts() const { return num_used_hosts_; }
202 5268 unsigned char num_retries() const { return num_retries_; }
203 371 unsigned backoff_ms() const { return backoff_ms_; }
204 5240 int current_metalink_chain_index() const {
205 5240 return current_metalink_chain_index_;
206 }
207 88 int current_host_chain_index() const { return current_host_chain_index_; }
208
209 bool allow_failure() const { return allow_failure_; }
210 19153 int64_t id() const { return id_; }
211
212 std::string GetInfoHeaderContents(const std::string &templ);
213 1274 void SetUrl(const std::string *url) { url_ = url; }
214 2237 void SetCompressed(bool compressed) { compressed_ = compressed; }
215 963 void SetProbeHosts(bool probe_hosts) { probe_hosts_ = probe_hosts; }
216 void SetHeadRequest(bool head_request) { head_request_ = head_request; }
217 4984 void SetFollowRedirects(bool follow_redirects) {
218 4984 follow_redirects_ = follow_redirects;
219 4984 }
220 64 void SetForceNocache(bool force_nocache) { force_nocache_ = force_nocache; }
221 void SetCredData(void *cred_data) { cred_data_ = cred_data; }
222 44 void SetInterruptCue(InterruptCue *interrupt_cue) {
223 44 interrupt_cue_ = interrupt_cue;
224 44 }
225 1274 void SetSink(cvmfs::Sink *sink) { sink_ = sink; }
226 1274 void SetExpectedHash(const shash::Any *expected_hash) {
227 1274 expected_hash_ = expected_hash;
228 1274 }
229 1388 void SetPathInfo(const std::string *path_info) { path_info_ = path_info; }
230
231 1388 void SetRangeOffset(off_t range_offset) { range_offset_ = range_offset; }
232 1388 void SetRangeSize(off_t range_size) { range_size_ = range_size; }
233
234 4984 void SetCurlHandle(CURL *curl_handle) { curl_handle_ = curl_handle; }
235 9968 void SetHeaders(curl_slist *headers) { headers_ = headers; }
236 4984 void SetInfoHeader(char *info_header) { info_header_ = info_header; }
237 void SetTracingHeaderPid(char *tracing_header_pid) {
238 tracing_header_pid_ = tracing_header_pid;
239 };
240 void SetTracingHeaderGid(char *tracing_header_gid) {
241 tracing_header_gid_ = tracing_header_gid;
242 };
243 void SetTracingHeaderUid(char *tracing_header_uid) {
244 tracing_header_uid_ = tracing_header_uid;
245 };
246 void SetZstream(z_stream zstream) { zstream_ = zstream; }
247 void SetHashContext(shash::ContextPtr hash_context) {
248 hash_context_ = hash_context;
249 }
250 5116 void SetProxy(const std::string &proxy) { proxy_ = proxy; }
251 4984 void SetLink(const std::string &link) { link_ = link; }
252 5026 void SetNocache(bool nocache) { nocache_ = nocache; }
253 10310 void SetErrorCode(Failures error_code) { error_code_ = error_code; }
254 5512 void SetHttpCode(int http_code) { http_code_ = http_code; }
255 5028 void SetNumUsedProxies(unsigned char num_used_proxies) {
256 5028 num_used_proxies_ = num_used_proxies;
257 5028 }
258 4984 void SetNumUsedMetalinks(unsigned char num_used_metalinks) {
259 4984 num_used_metalinks_ = num_used_metalinks;
260 4984 }
261 5072 void SetNumUsedHosts(unsigned char num_used_hosts) {
262 5072 num_used_hosts_ = num_used_hosts;
263 5072 }
264 5066 void SetNumRetries(unsigned char num_retries) { num_retries_ = num_retries; }
265 5066 void SetBackoffMs(unsigned backoff_ms) { backoff_ms_ = backoff_ms; }
266 void SetCurrentMetalinkChainIndex(int current_metalink_chain_index) {
267 current_metalink_chain_index_ = current_metalink_chain_index;
268 }
269 2925 void SetCurrentHostChainIndex(int current_host_chain_index) {
270 2925 current_host_chain_index_ = current_host_chain_index;
271 2925 }
272
273 void SetAllowFailure(bool allow_failure) { allow_failure_ = allow_failure; }
274
275 // needed for fetch.h ThreadLocalStorage
276
2/4
✓ Branch 2 taken 963 times.
✗ Branch 3 not taken.
✓ Branch 8 taken 963 times.
✗ Branch 9 not taken.
963 JobInfo() { Init(); }
277 }; // JobInfo
278
279 } // namespace download
280
281 #endif // CVMFS_NETWORK_JOBINFO_H_
282