E5Network/E5Ftp.py

changeset 2990
583beaf0b4b8
parent 2872
13f12f81cb7b
child 3022
57179e4cdadd
child 3057
10516539f238
equal deleted inserted replaced
2989:7efa8b8b6903 2990:583beaf0b4b8
2 2
3 # Copyright (c) 2012 - 2013 Detlev Offenbach <detlev@die-offenbachs.de> 3 # Copyright (c) 2012 - 2013 Detlev Offenbach <detlev@die-offenbachs.de>
4 # 4 #
5 5
6 """ 6 """
7 Module implementing an extension to the Python FTP class to support FTP proxies. 7 Module implementing an extension to the Python FTP class to support FTP
8 proxies.
8 """ 9 """
9 10
10 import ftplib 11 import ftplib
11 from socket import _GLOBAL_DEFAULT_TIMEOUT 12 from socket import _GLOBAL_DEFAULT_TIMEOUT
12 13
16 Class to signal an error related to proxy configuration. 17 Class to signal an error related to proxy configuration.
17 18
18 The error message starts with a three digit error code followed by a 19 The error message starts with a three digit error code followed by a
19 space and the error string. Supported error codes are: 20 space and the error string. Supported error codes are:
20 <ul> 21 <ul>
21 <li>910: proxy error; the second number gives the category of the proxy error. 22 <li>910: proxy error; the second number gives the category of the proxy
22 The original response from the proxy is appended in the next line.</li> 23 error. The original response from the proxy is appended in the next
23 <li>930: proxy error; the second number gives the category of the proxy error. 24 line.</li>
24 The original response from the proxy is appended in the next line.</li> 25 <li>930: proxy error; the second number gives the category of the proxy
25 <li>940: proxy error; the second number gives the category of the proxy error. 26 error. The original response from the proxy is appended in the next
26 The original response from the proxy is appended in the next line.</li> 27 line.</li>
27 <li>950: proxy error; the second number gives the category of the proxy error. 28 <li>940: proxy error; the second number gives the category of the proxy
28 The original response from the proxy is appended in the next line.</li> 29 error. The original response from the proxy is appended in the next
30 line.</li>
31 <li>950: proxy error; the second number gives the category of the proxy
32 error. The original response from the proxy is appended in the next
33 line.</li>
29 <li>990: proxy usage is enabled but no proxy host given</li> 34 <li>990: proxy usage is enabled but no proxy host given</li>
30 <li>991: proxy usage is enabled but no proxy user given</li> 35 <li>991: proxy usage is enabled but no proxy user given</li>
31 <li>992: proxy usage is enabled but no proxy password given</li> 36 <li>992: proxy usage is enabled but no proxy password given</li>
32 </ul> 37 </ul>
33 """ 38 """
44 Site = 3 # proxy login first, than use SITE command 49 Site = 3 # proxy login first, than use SITE command
45 Open = 4 # proxy login first, than use OPEN command 50 Open = 4 # proxy login first, than use OPEN command
46 UserAtProxyuserAtServer = 5 # one login for both 51 UserAtProxyuserAtServer = 5 # one login for both
47 ProxyuserAtServer = 6 # proxy login with remote host given, than 52 ProxyuserAtServer = 6 # proxy login with remote host given, than
48 # normal remote login 53 # normal remote login
49 AuthResp = 7 # authenticate to proxy with AUTH and RESP commands 54 AuthResp = 7 # authenticate to proxy with AUTH and
55 # RESP commands
50 Bluecoat = 8 # bluecoat proxy 56 Bluecoat = 8 # bluecoat proxy
51 57
52 58
53 class E5Ftp(ftplib.FTP): 59 class E5Ftp(ftplib.FTP):
54 """ 60 """
55 Class implementing an extension to the Python FTP class to support FTP proxies. 61 Class implementing an extension to the Python FTP class to support FTP
62 proxies.
56 """ 63 """
57 def __init__(self, host="", user="", password="", acct="", 64 def __init__(self, host="", user="", password="", acct="",
58 proxyType=E5FtpProxyType.NoProxy, proxyHost="", proxyPort=ftplib.FTP_PORT, 65 proxyType=E5FtpProxyType.NoProxy, proxyHost="",
59 proxyUser="", proxyPassword="", proxyAccount="", 66 proxyPort=ftplib.FTP_PORT, proxyUser="", proxyPassword="",
60 timeout=_GLOBAL_DEFAULT_TIMEOUT): 67 proxyAccount="", timeout=_GLOBAL_DEFAULT_TIMEOUT):
61 """ 68 """
62 Constructor 69 Constructor
63 70
64 @param host name of the FTP host (string) 71 @param host name of the FTP host (string)
65 @param user user name for login to FTP host (string) 72 @param user user name for login to FTP host (string)
94 self.connect(host) 101 self.connect(host)
95 if user: 102 if user:
96 self.login(user, password, acct) 103 self.login(user, password, acct)
97 104
98 def setProxy(self, proxyType=E5FtpProxyType.NoProxy, proxyHost="", 105 def setProxy(self, proxyType=E5FtpProxyType.NoProxy, proxyHost="",
99 proxyPort=ftplib.FTP_PORT, proxyUser="", proxyPassword="", proxyAccount=""): 106 proxyPort=ftplib.FTP_PORT, proxyUser="", proxyPassword="",
107 proxyAccount=""):
100 """ 108 """
101 Public method to set the proxy configuration. 109 Public method to set the proxy configuration.
102 110
103 @param proxyType type of the FTP proxy (integer 0 to 8) 111 @param proxyType type of the FTP proxy (integer 0 to 8)
104 @param proxyHost name of the FTP proxy (string) 112 @param proxyHost name of the FTP proxy (string)
112 self.__proxyPort = proxyPort 120 self.__proxyPort = proxyPort
113 self.__proxyUser = proxyUser 121 self.__proxyUser = proxyUser
114 self.__proxyPassword = proxyPassword 122 self.__proxyPassword = proxyPassword
115 self.__proxyAccount = proxyAccount 123 self.__proxyAccount = proxyAccount
116 124
117 def setProxyAuthentication(self, proxyUser="", proxyPassword="", proxyAccount=""): 125 def setProxyAuthentication(self, proxyUser="", proxyPassword="",
126 proxyAccount=""):
118 """ 127 """
119 Public method to set the proxy authentication info. 128 Public method to set the proxy authentication info.
120 129
121 @param proxyUser user name for login to the proxy (string) 130 @param proxyUser user name for login to the proxy (string)
122 @param proxyPassword password for login to the proxy (string) 131 @param proxyPassword password for login to the proxy (string)
150 if self.__proxyType != E5FtpProxyType.NoProxy: 159 if self.__proxyType != E5FtpProxyType.NoProxy:
151 if not self.__proxyHost: 160 if not self.__proxyHost:
152 raise E5FtpProxyError( 161 raise E5FtpProxyError(
153 "990 Proxy usage requested, but no proxy host given.") 162 "990 Proxy usage requested, but no proxy host given.")
154 163
155 return super().connect(self.__proxyHost, self.__proxyPort, self.__timeout) 164 return super().connect(
165 self.__proxyHost, self.__proxyPort, self.__timeout)
156 else: 166 else:
157 return super().connect(self.__host, self.__port, self.__timeout) 167 return super().connect(self.__host, self.__port, self.__timeout)
158 168
159 def login(self, user="", password="", acct=""): 169 def login(self, user="", password="", acct=""):
160 """ 170 """
161 Public method to login to the FTP server. 171 Public method to login to the FTP server.
162 172
163 This extended method respects the FTP proxy configuration. There are many 173 This extended method respects the FTP proxy configuration. There are
164 different FTP proxy products available. But unfortunately there is no 174 many different FTP proxy products available. But unfortunately there
165 standard for how o traverse a FTP proxy. The lis below shows the sequence 175 is no standard for how o traverse a FTP proxy. The lis below shows
166 of commands used. 176 the sequence of commands used.
167 177
168 <table> 178 <table>
169 <tr><td>user</td><td>Username for remote host</td></tr> 179 <tr><td>user</td><td>Username for remote host</td></tr>
170 <tr><td>pass</td><td>Password for remote host</td></tr> 180 <tr><td>pass</td><td>Password for remote host</td></tr>
171 <tr><td>pruser</td><td>Username for FTP proxy</td></tr> 181 <tr><td>pruser</td><td>Username for FTP proxy</td></tr>
172 <tr><td>prpass</td><td>Password for FTP proxy</td></tr> 182 <tr><td>prpass</td><td>Password for FTP proxy</td></tr>
173 <tr><td>remote.host</td><td>Hostname of the remote FTP server</td></tr> 183 <tr><td>remote.host</td><td>Hostname of the remote FTP server</td>
184 </tr>
174 </table> 185 </table>
175 186
176 <dl> 187 <dl>
177 <dt>E5FtpProxyType.NoProxy:</dt> 188 <dt>E5FtpProxyType.NoProxy:</dt>
178 <dd> 189 <dd>
257 if not self.__proxyUser: 268 if not self.__proxyUser:
258 raise E5FtpProxyError( 269 raise E5FtpProxyError(
259 "991 Proxy usage requested, but no proxy user given") 270 "991 Proxy usage requested, but no proxy user given")
260 if not self.__proxyPassword: 271 if not self.__proxyPassword:
261 raise E5FtpProxyError( 272 raise E5FtpProxyError(
262 "992 Proxy usage requested, but no proxy password given") 273 "992 Proxy usage requested, but no proxy password"
274 " given")
263 275
264 if self.__proxyType in [E5FtpProxyType.NonAuthorizing, 276 if self.__proxyType in [E5FtpProxyType.NonAuthorizing,
265 E5FtpProxyType.AuthResp, E5FtpProxyType.Bluecoat]: 277 E5FtpProxyType.AuthResp, E5FtpProxyType.Bluecoat]:
266 user += "@" + self.__host 278 user += "@" + self.__host
267 if self.__proxyType == E5FtpProxyType.Bluecoat: 279 if self.__proxyType == E5FtpProxyType.Bluecoat:
268 user += " " + self.__proxyUser 280 user += " " + self.__proxyUser
269 acct = self.__proxyPassword 281 acct = self.__proxyPassword
270 elif self.__proxyType == E5FtpProxyType.UserAtProxyuserAtServer: 282 elif self.__proxyType == E5FtpProxyType.UserAtProxyuserAtServer:
271 user = "{0}@{1}@{2}".format(user, self.__proxyUser, self.__host) 283 user = "{0}@{1}@{2}".format(
284 user, self.__proxyUser, self.__host)
272 password = "{0}@{1}".format(password, self.__proxyPassword) 285 password = "{0}@{1}".format(password, self.__proxyPassword)
273 else: 286 else:
274 pruser = self.__proxyUser 287 pruser = self.__proxyUser
275 if self.__proxyType == E5FtpProxyType.UserAtServer: 288 if self.__proxyType == E5FtpProxyType.UserAtServer:
276 user += "@" + self.__host 289 user += "@" + self.__host
282 if presp[0] == "3": 295 if presp[0] == "3":
283 presp = self.sendcmd("PASS " + self.__proxyPassword) 296 presp = self.sendcmd("PASS " + self.__proxyPassword)
284 if presp[0] == "3" and self.__proxyAccount: 297 if presp[0] == "3" and self.__proxyAccount:
285 presp = self.sendcmd("ACCT " + self.__proxyAccount) 298 presp = self.sendcmd("ACCT " + self.__proxyAccount)
286 if presp[0] != "2": 299 if presp[0] != "2":
287 raise E5FtpProxyError("9{0}0 Error authorizing at proxy\n{1}".format( 300 raise E5FtpProxyError(
301 "9{0}0 Error authorizing at proxy\n{1}".format(
288 presp[0], presp)) 302 presp[0], presp))
289 303
290 if self.__proxyType == E5FtpProxyType.Site: 304 if self.__proxyType == E5FtpProxyType.Site:
291 # send SITE command 305 # send SITE command
292 presp = self.sendcmd("SITE " + self.__host) 306 presp = self.sendcmd("SITE " + self.__host)
315 # authorize to the FTP proxy 329 # authorize to the FTP proxy
316 presp = self.sendcmd("AUTH " + self.__proxyUser) 330 presp = self.sendcmd("AUTH " + self.__proxyUser)
317 if presp[0] == "3": 331 if presp[0] == "3":
318 presp = self.sendcmd("RESP " + self.__proxyPassword) 332 presp = self.sendcmd("RESP " + self.__proxyPassword)
319 if presp[0] != "2": 333 if presp[0] != "2":
320 raise E5FtpProxyError("9{0}0 Error authorizing at proxy\n{1}".format( 334 raise E5FtpProxyError(
335 "9{0}0 Error authorizing at proxy\n{1}".format(
321 presp[0], presp)) 336 presp[0], presp))
322 337
323 return resp 338 return resp

eric ide

mercurial