libzypp: zypp-curl/ng/network/networkrequesterror.cc Source File

libzypp 17.38.6

networkrequesterror.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8----------------------------------------------------------------------*/
9#include <zypp-curl/ng/network/private/networkrequesterror_p.h>
10#include <zypp-curl/ng/network/request.h>
11#include <zypp-curl/private/curlhelper_p.h>
12#include <zypp-core/base/Gettext.h>
13#include <zypp-curl/auth/CurlAuthData>
14#include <curl/curl.h>
15
16namespace zyppng {
17
18 ZYPP_IMPL_PRIVATE(NetworkRequestError);
19
20 constexpr std::string_view CurlNativeErrorCodeDescKey = "nativeErrorCodeDesc";
21 constexpr std::string_view CurlNativeErrorDescKey = "nativeErrorDesc";
22
23NetworkRequestErrorPrivate::NetworkRequestErrorPrivate(NetworkRequestError::Type code, std::string &&msg, std::map<std::string, boost::any> &&extraInfo)
24 : _errorCode(code)
25 , _errorMessage( std::move(msg) )
26, _extraInfo( std::move(extraInfo) )
27{ }
28
29 NetworkRequestErrorPrivate *NetworkRequestErrorPrivate::clone() const
30{
31 return new NetworkRequestErrorPrivate( *this );
32}
33
34 NetworkRequestError NetworkRequestErrorPrivate::customError( NetworkRequestError::Type t, std::string &&errorMsg, std::map<std::string, boost::any> &&extraInfo )
35{
36 return NetworkRequestError( *new NetworkRequestErrorPrivate(t, errorMsg.empty() ? typeToString(t) : std::move(errorMsg), std::move(extraInfo)) );
37}
38
39 NetworkRequestError NetworkRequestErrorPrivate::fromCurlError(NetworkRequest &req, int nativeCode , const std::string &nativeError )
40{
41
42 Url url = req.url();
43 NetworkRequestError::Type c = NetworkRequestError::NoError;
44 std::string err;
45 std::map<std::string, boost::any> extraInfo;
46
47 if ( nativeCode != 0 ) {
48
49 const char *nativeErr = curl_easy_strerror( static_cast<CURLcode>(nativeCode) );
50 if ( nativeErr != nullptr )
51 extraInfo.insert( { CurlNativeErrorCodeDescKey.data(), std::string( nativeErr ) } );
52
53 if ( !nativeError.empty() )
54 extraInfo.insert( { CurlNativeErrorDescKey.data(), nativeError } );
55
56 extraInfo.insert( { "requestUrl", url } );
57 extraInfo.insert( { "curlCode", nativeCode } );
58 extraInfo.insert( { "filepath", req.targetFilePath().asString() } );
59 extraInfo.insert( { "lastRedirect", req.lastRedirectInfo() } );
60
61 switch ( nativeCode )
62 {
63 case CURLE_UNSUPPORTED_PROTOCOL:
64 c = NetworkRequestError::UnsupportedProtocol;
65 err = typeToString( c );
66 if ( !req.lastRedirectInfo().empty() )
67 {
68 err += " or redirect (";
69 err += req.lastRedirectInfo();
70 err += ")";
71 }
72 break;
73 case CURLE_URL_MALFORMAT: case CURLE_URL_MALFORMAT_USER:
74 c = NetworkRequestError::MalformedURL;
75 break;
76 case CURLE_LOGIN_DENIED:
77 c = NetworkRequestError::Unauthorized;
78 break;
79 case CURLE_HTTP_RETURNED_ERROR: {
80 long httpReturnCode = 0;
81 CURLcode infoRet = curl_easy_getinfo( req.nativeHandle(),
82 CURLINFO_RESPONSE_CODE,
83 &httpReturnCode );
84
85 if ( infoRet == CURLE_OK ) {
86 extraInfo.insert( { "responseCode", httpReturnCode } );
87
88 std::string msg = "HTTP response: " + zypp::str::numstring( httpReturnCode );
89 switch ( httpReturnCode )
90 {
91 case 401: {
92 long auth_info = CURLAUTH_NONE;
93
94 CURLcode infoRet =
95 curl_easy_getinfo(req.nativeHandle(), CURLINFO_HTTPAUTH_AVAIL, &auth_info);
96
97 if (infoRet == CURLE_OK) {
98 extraInfo.insert( { "authHint", zypp::media::CurlAuthData::auth_type_long2str(auth_info) } );
99 }
100
101 //if there is already a user:password entry in the settings the auth simply failed
102 //@TODO write a testcase for this
103 if ( req.transferSettings().hasCredentials() ) {
104 c = NetworkRequestError::AuthFailed;
105 } else {
106 c = NetworkRequestError::Unauthorized;
107 }
108
109 break;
110 }
111
112 case 502: // bad gateway (bnc #1070851)
113 case 503: // service temporarily unavailable (bnc #462545)
114 c = NetworkRequestError::TemporaryProblem;
115 err = zypp::str::form( _("Location '%s' is temporarily unaccessible."), url.asString().c_str() );
116 break;
117 case 504: // gateway timeout
118 c = NetworkRequestError::Timeout;
119 err = zypp::str::form(_("Timeout exceeded when accessing '%s'."), url.asString().c_str() );
120 break;
121 case 403: {
122 std::string msg403;
123 if ( url.getHost().find(".suse.com") != std::string::npos )
124 msg403 = _("Visit the SUSE Customer Center to check whether your registration is valid and has not expired.");
125 else if (url.asString().find("novell.com") != std::string::npos)
126 msg403 = _("Visit the Novell Customer Center to check whether your registration is valid and has not expired.");
127
128 c = NetworkRequestError::Forbidden;
129 err = msg403;
130 break;
131 }
132 case 404:
133 case 410:
134 c = NetworkRequestError::NotFound;
135 err = zypp::str::form( _("File '%s' not found on medium '%s'"), req.targetFilePath().c_str(), url.asString().c_str() );
136 break;
137
138 default:
139 c = NetworkRequestError::ServerReturnedError;
140 err = zypp::str::form(_("Download (curl) error for '%s':\n"
141 "Error code: %s\n"), url.asString().c_str(), zypp::str::numstring( httpReturnCode ).c_str() ) ;
142 break;
143 }
144 } else {
145 c = NetworkRequestError::ServerReturnedError;
146 err = zypp::str::form(_("Download (curl) error for '%s':\n"
147 "Unable to retrieve HTTP response\n"), url.asString().c_str() ) ;
148 }
149 }
150 break;
151 case CURLE_FTP_COULDNT_RETR_FILE:
152#if CURLVERSION_AT_LEAST(7,16,0)
153 case CURLE_REMOTE_FILE_NOT_FOUND:
154#endif
155 case CURLE_FTP_ACCESS_DENIED:
156 case CURLE_TFTP_NOTFOUND:
157 c = NetworkRequestError::NotFound;
158 break;
159 case CURLE_BAD_PASSWORD_ENTERED:
160 case CURLE_FTP_USER_PASSWORD_INCORRECT:
161 c = NetworkRequestError::AuthFailed;
162 break;
163 case CURLE_COULDNT_RESOLVE_PROXY:
164 case CURLE_COULDNT_RESOLVE_HOST:
165 case CURLE_COULDNT_CONNECT:
166 case CURLE_FTP_CANT_GET_HOST:
167 c = NetworkRequestError::ConnectionFailed;
168 break;
169 case CURLE_WRITE_ERROR: {
170 // this error code also handles the cases when a callback returned a error.
171 c = NetworkRequestError::InternalError;
172 break;
173 }
174 case CURLE_PARTIAL_FILE:
175 c = NetworkRequestError::ServerReturnedError;
176 break;
177 case CURLE_OPERATION_TIMEDOUT:
178 c = NetworkRequestError::Timeout;
179 break;
180 case CURLE_ABORTED_BY_CALLBACK:
181 c = NetworkRequestError::Cancelled;
182 break;
183 case CURLE_PEER_FAILED_VERIFICATION:
184 c = NetworkRequestError::PeerCertificateInvalid;
185 break;
186 case CURLE_HTTP2:
187 c = NetworkRequestError::Http2Error;
188 break;
189 case CURLE_HTTP2_STREAM:
190 c = NetworkRequestError::Http2StreamError;
191 break;
192 default:
193 c = NetworkRequestError::ServerReturnedError;
194 break;
195 }
196 }
197
198 if ( err.empty() )
199 err = typeToString( c );
200
201 err += " Curl error (" + zypp::str::numstring( nativeCode ) + ")";
202
203 return NetworkRequestError( *new NetworkRequestErrorPrivate(c, std::move(err), std::move(extraInfo)) );
204}
205
206 NetworkRequestError NetworkRequestErrorPrivate::fromCurlMError( int nativeCode )
207{
208 const char *nativeErr = curl_multi_strerror( static_cast<CURLMcode>(nativeCode) );
209
210 std::map<std::string, boost::any> extraInfo;
211 extraInfo.insert( { "curlMCode", nativeCode } );
212
213 std::string err;
214 if ( nativeErr == nullptr )
215 err = "The dispatcher returned an unknown error";
216 else
217 err = std::string( nativeErr );
218
219 return NetworkRequestError( *new NetworkRequestErrorPrivate(NetworkRequestError::InternalError, std::move(err), std::move(extraInfo)) );
220}
221
222 NetworkRequestError::NetworkRequestError(zyppng::NetworkRequestErrorPrivate &d )
223 : d_ptr( &d )
224{ }
225
226NetworkRequestError::NetworkRequestError()
227 : d_ptr( new NetworkRequestErrorPrivate( NoError, {}, {} ) )
228{ }
229
230 NetworkRequestError::Type NetworkRequestError::type() const
231{
232 return d_func()->_errorCode;
233}
234
235std::string NetworkRequestError::toString() const
236{
237 return d_func()->_errorMessage;
238}
239
240 bool NetworkRequestError::isError() const
241{
242 return d_func()->_errorCode != NoError;
243}
244
245 const std::map<std::string, boost::any> &NetworkRequestError::extraInfo() const
246{
247 return d_func()->_extraInfo;
248}
249
250std::string NetworkRequestErrorPrivate::typeToString( NetworkRequestError::Type t )
251{
252 switch ( t ) {
253 case NetworkRequestError::NoError:
254 return _("No error");
255 case NetworkRequestError::InternalError:
256 return _("Internal Error");
257 case NetworkRequestError::Cancelled:
258 return _("The request was cancelled");
259 case NetworkRequestError::ExceededMaxLen:
260 return _("The request exceeded the maximum download size");
261 case NetworkRequestError::InvalidChecksum:
262 return _("The downloaded data did not result in a valid checksum");
263 case NetworkRequestError::PeerCertificateInvalid:
264 return _("The peer certificate could not be verified");
265 case NetworkRequestError::ConnectionFailed:
266 return _("Connection failed");
267 case NetworkRequestError::UnsupportedProtocol:
268 return _("Unsupported protocol");
269 case NetworkRequestError::MalformedURL:
270 return _("Bad URL");
271 case NetworkRequestError::TemporaryProblem:
272 return _("Requested location is temporarily unaccessible.");
273 case NetworkRequestError::Timeout:
274 return _("Timeout reached");
275 case NetworkRequestError::Forbidden:
276 return _("Access to requested URL is forbidden.");
277 case NetworkRequestError::NotFound:
278 return _("File not found");
279 case NetworkRequestError::Unauthorized:
280 return _("Authentication required but not provided.");
281 case NetworkRequestError::AuthFailed:
282 return _("Login failed.");
283 case NetworkRequestError::ServerReturnedError:
284 return _("Server returned an error for the given request.");
285 case NetworkRequestError::MissingData:
286 return _("Server did not send all requested ranges.");
287 case NetworkRequestError::RangeFail:
288 return _("Invalid data from server, multipart was requested but there was no range status code.");
289 case NetworkRequestError::Http2Error:
290 return _("Server returned a HTTP/2 error.");
291 case NetworkRequestError::Http2StreamError:
292 return _("Server returned a HTTP/2 stream error.");
293 }
294 return std::string();
295}
296
297std::string NetworkRequestError::nativeErrorString() const
298{
299 Z_D();
300
301 auto it = d->_extraInfo.find(CurlNativeErrorDescKey.data());
302 if ( it != d->_extraInfo.end() ) {
303 try {
304 return boost::any_cast<std::string>( it->second );
305 } catch ( const boost::bad_any_cast &) { }
306 }
307
308 it = d->_extraInfo.find(CurlNativeErrorCodeDescKey.data());
309 if ( it != d->_extraInfo.end() ) {
310 try {
311 return boost::any_cast<std::string>( it->second );
312 } catch ( const boost::bad_any_cast &) { }
313 }
314
315 return std::string();
316}
317
318}
Gettext.h
_
#define _(MSG)
Definition Gettext.h:39
zypp::Url
Url manipulation class.
Definition Url.h:93
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition Pathname.h:113
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition Pathname.h:94
zypp::media::CurlAuthData::auth_type_long2str
static std::string auth_type_long2str(long auth_type)
Converts a long of ORed CURLAUTH_* identifiers into a string of comma separated list of authenticatio...
Definition curlauthdata.cc:104
zypp::media::TransferSettings::hasCredentials
bool hasCredentials() const
has a username, maybe even the password
Definition transfersettings.cc:157
zyppng::NetworkRequestErrorPrivate
Definition networkrequesterror_p.h:23
zyppng::NetworkRequestErrorPrivate::typeToString
static std::string typeToString(NetworkRequestError::Type t)
Definition networkrequesterror.cc:250
zyppng::NetworkRequestErrorPrivate::NetworkRequestErrorPrivate
NetworkRequestErrorPrivate(NetworkRequestError::Type code, std::string &&msg, std::map< std::string, boost::any > &&extraInfo)
Definition networkrequesterror.cc:23
zyppng::NetworkRequestErrorPrivate::fromCurlMError
static zyppng::NetworkRequestError fromCurlMError(int nativeCode)
Definition networkrequesterror.cc:206
zyppng::NetworkRequestErrorPrivate::clone
NetworkRequestErrorPrivate * clone() const
Definition networkrequesterror.cc:29
zyppng::NetworkRequestErrorPrivate::fromCurlError
static zyppng::NetworkRequestError fromCurlError(NetworkRequest &req, int nativeCode, const std::string &nativeError)
Definition networkrequesterror.cc:39
zyppng::NetworkRequestErrorPrivate::customError
static zyppng::NetworkRequestError customError(NetworkRequestError::Type t, std::string &&errorMsg="", std::map< std::string, boost::any > &&extraInfo={})
Definition networkrequesterror.cc:34
zyppng::NetworkRequestErrorPrivate::_extraInfo
std::map< std::string, boost::any > _extraInfo
Definition networkrequesterror_p.h:31
zyppng::NetworkRequestErrorPrivate::_errorMessage
std::string _errorMessage
Definition networkrequesterror_p.h:30
zyppng::NetworkRequestErrorPrivate::_errorCode
NetworkRequestError::Type _errorCode
Definition networkrequesterror_p.h:29
zyppng::NetworkRequestError
The NetworkRequestError class Represents a error that occured in.
Definition networkrequesterror.h:24
zyppng::NetworkRequestError::toString
std::string toString() const
toString Returns a string representation of the error
Definition networkrequesterror.cc:235
zyppng::NetworkRequestError::extraInfo
const std::map< std::string, boost::any > & extraInfo() const
Definition networkrequesterror.cc:245
zyppng::NetworkRequestError::type
Type type() const
type Returns the type of the error
Definition networkrequesterror.cc:230
zyppng::NetworkRequestError::NetworkRequestError
NetworkRequestError()
Definition networkrequesterror.cc:226
zyppng::NetworkRequestError::nativeErrorString
std::string nativeErrorString() const
Definition networkrequesterror.cc:297
zyppng::NetworkRequestError::Type
Type
Definition networkrequesterror.h:26
zyppng::NetworkRequestError::ServerReturnedError
@ ServerReturnedError
Definition networkrequesterror.h:42
zyppng::NetworkRequestError::Forbidden
@ Forbidden
Definition networkrequesterror.h:38
zyppng::NetworkRequestError::PeerCertificateInvalid
@ PeerCertificateInvalid
Definition networkrequesterror.h:30
zyppng::NetworkRequestError::UnsupportedProtocol
@ UnsupportedProtocol
Definition networkrequesterror.h:34
zyppng::NetworkRequestError::InternalError
@ InternalError
Definition networkrequesterror.h:28
zyppng::NetworkRequestError::ExceededMaxLen
@ ExceededMaxLen
Definition networkrequesterror.h:32
zyppng::NetworkRequestError::Unauthorized
@ Unauthorized
Definition networkrequesterror.h:40
zyppng::NetworkRequestError::MalformedURL
@ MalformedURL
Definition networkrequesterror.h:35
zyppng::NetworkRequestError::ConnectionFailed
@ ConnectionFailed
Definition networkrequesterror.h:31
zyppng::NetworkRequestError::RangeFail
@ RangeFail
Definition networkrequesterror.h:44
zyppng::NetworkRequestError::AuthFailed
@ AuthFailed
Definition networkrequesterror.h:41
zyppng::NetworkRequestError::Timeout
@ Timeout
Definition networkrequesterror.h:37
zyppng::NetworkRequestError::Http2Error
@ Http2Error
Definition networkrequesterror.h:45
zyppng::NetworkRequestError::MissingData
@ MissingData
Definition networkrequesterror.h:43
zyppng::NetworkRequestError::NoError
@ NoError
Definition networkrequesterror.h:27
zyppng::NetworkRequestError::NotFound
@ NotFound
Definition networkrequesterror.h:39
zyppng::NetworkRequestError::Cancelled
@ Cancelled
Definition networkrequesterror.h:29
zyppng::NetworkRequestError::Http2StreamError
@ Http2StreamError
Definition networkrequesterror.h:46
zyppng::NetworkRequestError::TemporaryProblem
@ TemporaryProblem
Definition networkrequesterror.h:36
zyppng::NetworkRequestError::InvalidChecksum
@ InvalidChecksum
Definition networkrequesterror.h:33
zyppng::NetworkRequestError::isError
bool isError() const
isError Will return true if this is a actual error
Definition networkrequesterror.cc:240
zyppng::NetworkRequestError::d_ptr
zypp::RWCOW_pointer< NetworkRequestErrorPrivate > d_ptr
Definition networkrequesterror.h:104
zyppng::NetworkRequest
Definition request.h:43
zyppng::NetworkRequest::targetFilePath
const zypp::Pathname & targetFilePath() const
Returns the target filename path.
Definition request.cc:932
zyppng::NetworkRequest::url
Url url() const
Definition request.cc:918
zyppng::NetworkRequest::nativeHandle
void * nativeHandle() const
Definition request.cc:874
zyppng::NetworkRequest::transferSettings
TransferSettings & transferSettings()
Definition request.cc:995
zyppng::NetworkRequest::lastRedirectInfo
const std::string & lastRedirectInfo() const
Definition request.cc:869
curlhelper_p.h
std
Definition ansi.h:855
zypp::str::numstring
std::string numstring(char n, int w=0)
Definition String.h:290
zypp::str::form
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition String.cc:39
zypp::url
Url details namespace.
Definition UrlBase.cc:58
zyppng
Definition MediaNetworkRequestExecutor.h:16
zyppng::CurlNativeErrorDescKey
constexpr std::string_view CurlNativeErrorDescKey
Definition networkrequesterror.cc:21
zyppng::CurlNativeErrorCodeDescKey
constexpr std::string_view CurlNativeErrorCodeDescKey
Definition networkrequesterror.cc:20
networkrequesterror_p.h
request.h
ZYPP_IMPL_PRIVATE
#define ZYPP_IMPL_PRIVATE(Class)
Definition zyppglobal.h:85
Z_D
#define Z_D()
Definition zyppglobal.h:98