libzypp 17.31.8
request_p.h
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8----------------------------------------------------------------------/
9*
10* This file contains private API, this might break at any time between releases.
11* You have been warned!
12*
13*/
14#ifndef ZYPP_NG_MEDIA_CURL_PRIVATE_REQUEST_P_H_INCLUDED
15#define ZYPP_NG_MEDIA_CURL_PRIVATE_REQUEST_P_H_INCLUDED
16
17#include <zypp-core/zyppng/base/private/base_p.h>
19#include <zypp-media/MediaException>
20#include <zypp-core/zyppng/base/Timer>
21#include <zypp-core/base/Regex.h>
22#include <curl/curl.h>
23#include <array>
24#include <memory>
25#include <zypp-core/Digest.h>
26#include <zypp-core/AutoDispose.h>
27
28#include <boost/optional.hpp>
29#include <variant>
30
31namespace zyppng {
32
33
34
36 {
37 ZYPP_DECLARE_PUBLIC(NetworkRequest)
38 public:
39 enum class ProtocolMode{
40 Default, //< use this mode if no special checks are required in header or write callbacks
41 HTTP //< this mode is used for HTTP and HTTPS downloads
43
45 virtual ~NetworkRequestPrivate();
46
47 bool initialize( std::string &errBuf );
48
49 bool setupHandle ( std::string &errBuf );
50
51 bool assertOutputFile ();
52
58 bool canRecover () const;
59
65 bool prepareToContinue ( std::string &errBuf );
66
70 bool prepareNextRangeBatch( std::string &errBuf );
71
77 bool hasMoreWork() const;
78
83 void aboutToStart ( );
84
90 void dequeueNotify();
91
92 void setResult ( NetworkRequestError &&err );
93 void reset ();
94 void resetActivityTimer ();
95 void onActivityTimeout (Timer &);
98 bool parseContentRangeHeader (const std::string_view &line, size_t &start , size_t &len);
99 bool parseContentTypeMultiRangeHeader ( const std::string_view &line, std::string &boundary );
100
101 std::string errorMessage () const;
102
103
104 std::array<char, CURL_ERROR_SIZE+1> _errorBuf; //provide a buffer for a nicely formatted error for CURL
105
106 template<typename T>
107 void setCurlOption ( CURLoption opt, T data )
108 {
109 auto ret = curl_easy_setopt( _easyHandle, opt, data );
110 if ( ret != 0 ) {
112 }
113 }
114
115 Url _url; //file URL
118 NetworkRequest::Options _options;
119 zypp::ByteCount _expectedFileSize; // the file size as expected by the user code
120 std::vector<NetworkRequest::Range> _requestedRanges;
121
124
125 long _curlDebug = 0L;
126 std::string _lastRedirect;
127 const std::string _currentCookieFile = "/var/lib/YaST2/cookies";
128
129 void *_easyHandle = nullptr; // the easy handle that controlling this request
130 NetworkRequestDispatcher *_dispatcher = nullptr; // the parent downloader owning this request
131
132 //signals
133 Signal< void ( NetworkRequest &req )> _sigStarted;
135 Signal< void ( NetworkRequest &req, off_t dltotal, off_t dlnow, off_t ultotal, off_t ulnow )> _sigProgress;
136 Signal< void ( NetworkRequest &req, const NetworkRequestError &err )> _sigFinished;
137
138 static int curlProgressCallback ( void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow );
139 size_t headerCallback ( char *ptr, size_t size, size_t nmemb );
140 size_t writeCallback ( char *ptr, size_t size, size_t nmemb );
141
142 std::unique_ptr< curl_slist, decltype (&curl_slist_free_all) > _headers;
143
144 // when requesting ranges from the server, we need to make sure not to request
145 // too many at the same time. Instead we batch our requests and reuse the open
146 // connection until we have the full file.
147 // However different server have different maximum nr of ranges, so we start with
148 // a high number and decrease until we find a rangecount that works
149 constexpr static int _rangeAttempt[] = {
150 255,
151 127,
152 63,
153 15,
154 5
155 };
156
157 struct pending_t;
158 struct running_t;
159 struct prepareNextRangeBatch_t;
160
161 struct pending_t {
164 };
165
167 {
168 prepareNextRangeBatch_t( running_t &&prevState );
169 zypp::AutoFILE _outFile; //the file we are writing to
170 off_t _downloaded = 0; //downloaded bytes
171 int _rangeAttemptIdx = 0; // which range attempt index are we currently using
172 };
173
174 struct running_t {
175 running_t( pending_t &&prevState );
176 running_t( prepareNextRangeBatch_t &&prevState );
177
178 Timer::Ptr _activityTimer = Timer::create();
179
181 off_t _currentRange = -1;
182 std::optional<NetworkRequest::Range> _currentSrvRange;
183
188
189 // handle the case when cancel() is called from a slot to the progress signal
190 bool _isInCallback = false;
191
192 // used to handle cancel() when emitting the progress signal, or when we explicitely trigger
193 // a error during callbacks.
194 std::optional<NetworkRequestError> _cachedResult;
195
196 off_t _lastProgressNow = -1; // last value returned from CURL, lets only send signals if we get actual updates
197 off_t _downloaded = 0; //downloaded bytes
198 int _rangeAttemptIdx = 0; // which range attempt index are we currently using
199 zypp::ByteCount _contentLenght; // the content length as reported by the server
200
201 //multirange support for HTTP requests (https://tools.ietf.org/html/rfc7233)
202 std::string _seperatorString;
203 std::vector<char> _rangePrefaceBuffer;
204 };
205
206 struct finished_t {
207 off_t _downloaded = 0; //downloaded bytes
208 zypp::ByteCount _contentLenght = 0; // the content length as reported by the server
209 NetworkRequestError _result; // the overall result of the download
210 };
211
212 std::variant< pending_t, running_t, prepareNextRangeBatch_t, finished_t > _runningMode = pending_t();
213 };
214
215 std::vector<char> peek_data_fd ( FILE *fd, off_t offset, size_t count );
216}
217
218#endif
Store and operate with byte count.
Definition: ByteCount.h:31
Holds transfer setting.
The NetworkRequestError class Represents a error that occured in.
enum zyppng::NetworkRequestPrivate::ProtocolMode _protocolMode
const std::string _currentCookieFile
Definition: request_p.h:127
zypp::Pathname _targetFile
Definition: request_p.h:116
bool parseContentTypeMultiRangeHeader(const std::string_view &line, std::string &boundary)
Definition: request.cc:825
Signal< void(NetworkRequest &req, zypp::ByteCount count)> _sigBytesDownloaded
Definition: request_p.h:134
NetworkRequestDispatcher * _dispatcher
Definition: request_p.h:130
std::vector< NetworkRequest::Range > _requestedRanges
the requested ranges that need to be downloaded
Definition: request_p.h:120
static int curlProgressCallback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
Definition: request.cc:853
std::string errorMessage() const
Definition: request.cc:839
Signal< void(NetworkRequest &req)> _sigStarted
Definition: request_p.h:133
NetworkRequest::FileMode _fMode
Definition: request_p.h:122
std::variant< pending_t, running_t, prepareNextRangeBatch_t, finished_t > _runningMode
Definition: request_p.h:212
bool initialize(std::string &errBuf)
Definition: request.cc:203
void validateRange(NetworkRequest::Range &rng)
Definition: request.cc:793
void onActivityTimeout(Timer &)
Definition: request.cc:762
Signal< void(NetworkRequest &req, off_t dltotal, off_t dlnow, off_t ultotal, off_t ulnow)> _sigProgress
Definition: request_p.h:135
size_t writeCallback(char *ptr, size_t size, size_t nmemb)
Definition: request.cc:967
NetworkRequest::Priority _priority
Definition: request_p.h:123
std::string _lastRedirect
to log/report redirections
Definition: request_p.h:126
NetworkRequest::Options _options
Definition: request_p.h:118
static constexpr int _rangeAttempt[]
Definition: request_p.h:149
bool prepareToContinue(std::string &errBuf)
Definition: request.cc:530
bool prepareNextRangeBatch(std::string &errBuf)
Definition: request.cc:562
size_t headerCallback(char *ptr, size_t size, size_t nmemb)
Definition: request.cc:879
void setResult(NetworkRequestError &&err)
Definition: request.cc:716
std::array< char, CURL_ERROR_SIZE+1 > _errorBuf
Definition: request_p.h:104
bool setupHandle(std::string &errBuf)
Definition: request.cc:215
TransferSettings _settings
Definition: request_p.h:117
void setCurlOption(CURLoption opt, T data)
Definition: request_p.h:107
zypp::ByteCount _expectedFileSize
Definition: request_p.h:119
Signal< void(NetworkRequest &req, const NetworkRequestError &err)> _sigFinished
Definition: request_p.h:136
std::unique_ptr< curl_slist, decltype(&curl_slist_free_all) > _headers
Definition: request_p.h:142
bool checkIfRangeChkSumIsValid(const NetworkRequest::Range &rng)
Definition: request.cc:773
bool parseContentRangeHeader(const std::string_view &line, size_t &start, size_t &len)
Definition: request.cc:808
std::vector< char > peek_data_fd(FILE *fd, off_t offset, size_t count)
Definition: request.cc:135
AutoDispose<FILE*> calling ::fclose
Definition: AutoDispose.h:312
std::optional< NetworkRequestError > _cachedResult
Definition: request_p.h:194
std::vector< char > _rangePrefaceBuffer
Here we buffer.
Definition: request_p.h:203
std::string _seperatorString
The seperator string for multipart responses as defined in RFC 7233 Section 4.1.
Definition: request_p.h:202
std::optional< NetworkRequest::Range > _currentSrvRange
Definition: request_p.h:182
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:428