]>
git.ipfire.org Git - people/stevee/pakfire.git/blob - python/pakfire/client/transport.py
2 ###############################################################################
4 # Pakfire - The IPFire package management system #
5 # Copyright (C) 2011 Pakfire development team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
29 log
= logging
.getLogger("pakfire.client")
31 from pakfire
.constants
import *
32 from pakfire
.i18n
import _
34 # Set the default socket timeout to 30 seconds.
35 socket
.setdefaulttimeout(30)
41 user_agent
= "pakfire/%s" % PAKFIRE_VERSION
43 def single_request(self
, *args
, **kwargs
):
46 # Tries can be passed to this method.
47 tries
= kwargs
.pop("tries", 100)
52 ret
= xmlrpclib
.Transport
.single_request(self
, *args
, **kwargs
)
54 # Catch errors related to the connection. Just try again.
55 except (socket
.error
, ssl
.SSLError
), e
:
56 log
.warning("Exception: %s: %s" % (e
.__class
__.__name
__, e
))
58 # Presumably, the server closed the connection before sending anything.
59 except httplib
.BadStatusLine
:
60 # Try again immediately.
63 # The XML reponse could not be parsed.
64 except xmlrpclib
.ResponseError
, e
:
65 log
.warning("Exception: %s: %s" % (e
.__class
__.__name
__, e
))
67 except xmlrpclib
.ProtocolError
, e
:
69 # Possibly, the user credentials are invalid.
71 raise XMLRPCForbiddenError(e
)
73 elif e
.errcode
== 404:
74 # Some invalid URL was called.
76 raise XMLRPCNotFoundError(e
)
78 elif e
.errcode
== 500:
79 # This could have various reasons, so we can not
80 # be sure to kill connections here.
81 # But to visualize the issue, we will raise an
82 # exception on the last try.
84 raise XMLRPCInternalServerError(e
)
86 elif e
.errcode
== 503:
87 # Possibly the hub is not running but the SSL proxy
88 # is. Just try again in a short time.
92 # Log all XMLRPC protocol errors.
93 log
.error(_("XMLRPC protocol error:"))
94 log
.error(" %s" % _("URL: %s") % e
.url
)
95 log
.error(" %s" % _(" HTTP headers:"))
96 for header
in e
.headers
.items():
97 log
.error(" %s: %s" % header
)
98 log
.error(" %s" % _("Error code: %s") % e
.errcode
)
99 log
.error(" %s" % _("Error message: %s") % e
.errmsg
)
101 # If an unhandled error code appeared, we raise an
105 except xmlrpclib
.Fault
:
109 # If request was successful, we can break the loop.
112 # If the request was not successful, we wait a little time to try
119 log
.warning(_("Trying again in %(timeout)s second(s). %(tries)s tries left.") \
120 % { "timeout" : timeout
, "tries" : tries
})
124 raise XMLRPCTransportError
, _("Maximum number of tries was reached. Giving up.")
130 class XMLRPCTransport(XMLRPCMixin
, xmlrpclib
.Transport
):
132 Handles the XMLRPC connection over HTTP.
137 class SafeXMLRPCTransport(XMLRPCMixin
, xmlrpclib
.SafeTransport
):
139 Handles the XMLRPC connection over HTTPS.
144 class Connection(xmlrpclib
.ServerProxy
):
146 Class wrapper that automatically chooses the right transport
147 method depending on the given URL.
150 def __init__(self
, url
):
151 # Create transport channel to the server.
152 if url
.startswith("https://"):
153 transport
= SafeXMLRPCTransport()
154 elif url
.startswith("http://"):
155 transport
= XMLRPCTransport()
157 xmlrpclib
.ServerProxy
.__init
__(self
, url
, transport
=transport
,