libzypp 17.31.7
networkrequesterror.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8----------------------------------------------------------------------*/
12#include <zypp/base/Gettext.h>
13#include <zypp-curl/auth/CurlAuthData>
14#include <curl/curl.h>
15
16namespace zyppng {
17
19
20constexpr std::string_view CurlNativeErrorCodeDescKey = "nativeErrorCodeDesc";
21constexpr 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
30{
31 return new NetworkRequestErrorPrivate( *this );
32}
33
34NetworkRequestError 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
39NetworkRequestError NetworkRequestErrorPrivate::fromCurlError(NetworkRequest &req, int nativeCode , const std::string &nativeError )
40{
41
42 Url url = req.url();
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:
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:
75 break;
76 case CURLE_LOGIN_DENIED:
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 std::string auth_hint;
93 {
94 long auth_info = CURLAUTH_NONE;
95
96 CURLcode infoRet =
97 curl_easy_getinfo(req.nativeHandle(), CURLINFO_HTTPAUTH_AVAIL, &auth_info);
98
99 if(infoRet == CURLE_OK) {
100 extraInfo.insert( { "authHint", zypp::media::CurlAuthData::auth_type_long2str(auth_info) } );
101 }
102 }
103
104 //if there is already a user:password entry in the settings the auth simply failed
105 //@TODO write a testcase for this
106 if ( !req.transferSettings().userPassword().empty() ) {
108 } else {
110 }
111
112 break;
113 }
114
115 case 502: // bad gateway (bnc #1070851)
116 case 503: // service temporarily unavailable (bnc #462545)
118 err = zypp::str::form( _("Location '%s' is temporarily unaccessible."), url.asString().c_str() );
119 break;
120 case 504: // gateway timeout
122 err = zypp::str::form(_("Timeout exceeded when accessing '%s'."), url.asString().c_str() );
123 break;
124 case 403: {
125 std::string msg403;
126 if ( url.getHost().find(".suse.com") != std::string::npos )
127 msg403 = _("Visit the SUSE Customer Center to check whether your registration is valid and has not expired.");
128 else if (url.asString().find("novell.com") != std::string::npos)
129 msg403 = _("Visit the Novell Customer Center to check whether your registration is valid and has not expired.");
130
132 err = msg403;
133 break;
134 }
135 case 404:
136 case 410:
138 err = zypp::str::form( _("File '%s' not found on medium '%s'"), req.targetFilePath().c_str(), url.asString().c_str() );
139 break;
140
141 default:
143 err = zypp::str::form(_("Download (curl) error for '%s':\n"
144 "Error code: %s\n"), url.asString().c_str(), zypp::str::numstring( httpReturnCode ).c_str() ) ;
145 break;
146 }
147 } else {
149 err = zypp::str::form(_("Download (curl) error for '%s':\n"
150 "Unable to retrieve HTTP response\n"), url.asString().c_str() ) ;
151 }
152 }
153 break;
154 case CURLE_FTP_COULDNT_RETR_FILE:
155#if CURLVERSION_AT_LEAST(7,16,0)
156 case CURLE_REMOTE_FILE_NOT_FOUND:
157#endif
158 case CURLE_FTP_ACCESS_DENIED:
159 case CURLE_TFTP_NOTFOUND:
161 break;
162 case CURLE_BAD_PASSWORD_ENTERED:
163 case CURLE_FTP_USER_PASSWORD_INCORRECT:
165 break;
166 case CURLE_COULDNT_RESOLVE_PROXY:
167 case CURLE_COULDNT_RESOLVE_HOST:
168 case CURLE_COULDNT_CONNECT:
169 case CURLE_FTP_CANT_GET_HOST:
171 break;
172 case CURLE_WRITE_ERROR: {
173 // this error code also handles the cases when a callback returned a error.
175 break;
176 }
177 case CURLE_PARTIAL_FILE:
179 break;
180 case CURLE_OPERATION_TIMEDOUT:
182 break;
183 case CURLE_ABORTED_BY_CALLBACK:
185 break;
186 case CURLE_PEER_FAILED_VERIFICATION:
188 break;
189 default:
191 err = "Curl error " + zypp::str::numstring( nativeCode );
192 break;
193 }
194 }
195
196 if ( err.empty() )
197 err = typeToString( c );
198
199 return NetworkRequestError( *new NetworkRequestErrorPrivate(c, std::move(err), std::move(extraInfo)) );
200}
201
203{
204 const char *nativeErr = curl_multi_strerror( static_cast<CURLMcode>(nativeCode) );
205
206 std::map<std::string, boost::any> extraInfo;
207 extraInfo.insert( { "curlMCode", nativeCode } );
208
209 std::string err;
210 if ( nativeErr == nullptr )
211 err = "The dispatcher returned an unknown error";
212 else
213 err = std::string( nativeErr );
214
215 return NetworkRequestError( *new NetworkRequestErrorPrivate(NetworkRequestError::InternalError, std::move(err), std::move(extraInfo)) );
216}
217
219 : d_ptr( &d )
220{ }
221
223 : d_ptr( new NetworkRequestErrorPrivate( NoError, {}, {} ) )
224{ }
225
227{
228 return d_func()->_errorCode;
229}
230
232{
233 return d_func()->_errorMessage;
234}
235
237{
238 return d_func()->_errorCode != NoError;
239}
240
241const std::map<std::string, boost::any> &NetworkRequestError::extraInfo() const
242{
243 return d_func()->_extraInfo;
244}
245
247{
248 switch ( t ) {
250 return "No error";
252 return "Internal Error";
254 return "The request was cancelled";
256 return "The request exceeded the maximum download size";
258 return "The downloaded data did not result in a valid checksum";
260 return "The peer certificate could not be verified";
262 return "Connection failed";
264 return "Unsupported protocol";
266 return "Bad URL";
268 return "Requested location is temporarily unaccessible.";
270 return "Timeout reached";
272 return "Access to requested URL is forbidden.";
274 return "File not found";
276 return "Authentication required but not provided.";
278 return "Login failed.";
280 return "Server returned an error for the given request.";
282 return "Server did not send all requested ranges.";
284 return "Invalid data from server, multipart was requested but there was no range status code.";
285 }
286 return std::string();
287}
288
290{
291 Z_D();
292
293 auto it = d->_extraInfo.find(CurlNativeErrorDescKey.data());
294 if ( it != d->_extraInfo.end() ) {
295 try {
296 return boost::any_cast<std::string>( it->second );
297 } catch ( const boost::bad_any_cast &) { }
298 }
299
300 it = d->_extraInfo.find(CurlNativeErrorCodeDescKey.data());
301 if ( it != d->_extraInfo.end() ) {
302 try {
303 return boost::any_cast<std::string>( it->second );
304 } catch ( const boost::bad_any_cast &) { }
305 }
306
307 return std::string();
308}
309
310}
const char * c_str() const
String representation.
Definition: Pathname.h:110
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...
std::string userPassword() const
returns the user and password as a user:pass string
static std::string typeToString(NetworkRequestError::Type t)
NetworkRequestErrorPrivate(NetworkRequestError::Type code, std::string &&msg, std::map< std::string, boost::any > &&extraInfo)
static zyppng::NetworkRequestError fromCurlMError(int nativeCode)
NetworkRequestErrorPrivate * clone() const
static zyppng::NetworkRequestError fromCurlError(NetworkRequest &req, int nativeCode, const std::string &nativeError)
static zyppng::NetworkRequestError customError(NetworkRequestError::Type t, std::string &&errorMsg="", std::map< std::string, boost::any > &&extraInfo={})
The NetworkRequestError class Represents a error that occured in.
std::string toString() const
toString Returns a string representation of the error
const std::map< std::string, boost::any > & extraInfo() const
Type type() const
type Returns the type of the error
std::string nativeErrorString() const
bool isError() const
isError Will return true if this is a actual error
const zypp::Pathname & targetFilePath() const
Returns the target filename path.
Definition: request.cc:1354
void * nativeHandle() const
Definition: request.cc:1296
TransferSettings & transferSettings()
Definition: request.cc:1417
const std::string & lastRedirectInfo() const
Definition: request.cc:1291
Definition: Arch.h:352
std::string numstring(char n, int w=0)
Definition: String.h:289
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
constexpr std::string_view CurlNativeErrorDescKey
constexpr std::string_view CurlNativeErrorCodeDescKey
ZYPP_IMPL_PRIVATE(Provide)
#define _(MSG)
Definition: Gettext.h:37