libzypp 17.31.23
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 case CURLE_HTTP2:
191 break;
192 case CURLE_HTTP2_STREAM:
194 break;
195 default:
197 break;
198 }
199 }
200
201 if ( err.empty() )
202 err = typeToString( c );
203
204 err += " Curl error (" + zypp::str::numstring( nativeCode ) + ")";
205
206 return NetworkRequestError( *new NetworkRequestErrorPrivate(c, std::move(err), std::move(extraInfo)) );
207}
208
210{
211 const char *nativeErr = curl_multi_strerror( static_cast<CURLMcode>(nativeCode) );
212
213 std::map<std::string, boost::any> extraInfo;
214 extraInfo.insert( { "curlMCode", nativeCode } );
215
216 std::string err;
217 if ( nativeErr == nullptr )
218 err = "The dispatcher returned an unknown error";
219 else
220 err = std::string( nativeErr );
221
222 return NetworkRequestError( *new NetworkRequestErrorPrivate(NetworkRequestError::InternalError, std::move(err), std::move(extraInfo)) );
223}
224
226 : d_ptr( &d )
227{ }
228
230 : d_ptr( new NetworkRequestErrorPrivate( NoError, {}, {} ) )
231{ }
232
234{
235 return d_func()->_errorCode;
236}
237
239{
240 return d_func()->_errorMessage;
241}
242
244{
245 return d_func()->_errorCode != NoError;
246}
247
248const std::map<std::string, boost::any> &NetworkRequestError::extraInfo() const
249{
250 return d_func()->_extraInfo;
251}
252
254{
255 switch ( t ) {
257 return "No error";
259 return "Internal Error";
261 return "The request was cancelled";
263 return "The request exceeded the maximum download size";
265 return "The downloaded data did not result in a valid checksum";
267 return "The peer certificate could not be verified";
269 return "Connection failed";
271 return "Unsupported protocol";
273 return "Bad URL";
275 return "Requested location is temporarily unaccessible.";
277 return "Timeout reached";
279 return "Access to requested URL is forbidden.";
281 return "File not found";
283 return "Authentication required but not provided.";
285 return "Login failed.";
287 return "Server returned an error for the given request.";
289 return "Server did not send all requested ranges.";
291 return "Invalid data from server, multipart was requested but there was no range status code.";
293 return "Server returned a HTTP/2 error.";
295 return "Server returned a HTTP/2 stream error.";
296 }
297 return std::string();
298}
299
301{
302 Z_D();
303
304 auto it = d->_extraInfo.find(CurlNativeErrorDescKey.data());
305 if ( it != d->_extraInfo.end() ) {
306 try {
307 return boost::any_cast<std::string>( it->second );
308 } catch ( const boost::bad_any_cast &) { }
309 }
310
311 it = d->_extraInfo.find(CurlNativeErrorCodeDescKey.data());
312 if ( it != d->_extraInfo.end() ) {
313 try {
314 return boost::any_cast<std::string>( it->second );
315 } catch ( const boost::bad_any_cast &) { }
316 }
317
318 return std::string();
319}
320
321}
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:1265
void * nativeHandle() const
Definition: request.cc:1207
TransferSettings & transferSettings()
Definition: request.cc:1328
const std::string & lastRedirectInfo() const
Definition: request.cc:1202
Definition: Arch.h:361
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