libzypp 17.31.8
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 break;
192 }
193 }
194
195 if ( err.empty() )
196 err = typeToString( c );
197
198 err += " Curl error (" + zypp::str::numstring( nativeCode ) + ")";
199
200 return NetworkRequestError( *new NetworkRequestErrorPrivate(c, std::move(err), std::move(extraInfo)) );
201}
202
204{
205 const char *nativeErr = curl_multi_strerror( static_cast<CURLMcode>(nativeCode) );
206
207 std::map<std::string, boost::any> extraInfo;
208 extraInfo.insert( { "curlMCode", nativeCode } );
209
210 std::string err;
211 if ( nativeErr == nullptr )
212 err = "The dispatcher returned an unknown error";
213 else
214 err = std::string( nativeErr );
215
216 return NetworkRequestError( *new NetworkRequestErrorPrivate(NetworkRequestError::InternalError, std::move(err), std::move(extraInfo)) );
217}
218
220 : d_ptr( &d )
221{ }
222
224 : d_ptr( new NetworkRequestErrorPrivate( NoError, {}, {} ) )
225{ }
226
228{
229 return d_func()->_errorCode;
230}
231
233{
234 return d_func()->_errorMessage;
235}
236
238{
239 return d_func()->_errorCode != NoError;
240}
241
242const std::map<std::string, boost::any> &NetworkRequestError::extraInfo() const
243{
244 return d_func()->_extraInfo;
245}
246
248{
249 switch ( t ) {
251 return "No error";
253 return "Internal Error";
255 return "The request was cancelled";
257 return "The request exceeded the maximum download size";
259 return "The downloaded data did not result in a valid checksum";
261 return "The peer certificate could not be verified";
263 return "Connection failed";
265 return "Unsupported protocol";
267 return "Bad URL";
269 return "Requested location is temporarily unaccessible.";
271 return "Timeout reached";
273 return "Access to requested URL is forbidden.";
275 return "File not found";
277 return "Authentication required but not provided.";
279 return "Login failed.";
281 return "Server returned an error for the given request.";
283 return "Server did not send all requested ranges.";
285 return "Invalid data from server, multipart was requested but there was no range status code.";
286 }
287 return std::string();
288}
289
291{
292 Z_D();
293
294 auto it = d->_extraInfo.find(CurlNativeErrorDescKey.data());
295 if ( it != d->_extraInfo.end() ) {
296 try {
297 return boost::any_cast<std::string>( it->second );
298 } catch ( const boost::bad_any_cast &) { }
299 }
300
301 it = d->_extraInfo.find(CurlNativeErrorCodeDescKey.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 return std::string();
309}
310
311}
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