@@ -512,14 +512,30 @@ class FancyURLopener(URLopener):
512
512
def __init__ (self , * args ):
513
513
apply (URLopener .__init__ , (self ,) + args )
514
514
self .auth_cache = {}
515
+ self .tries = 0
516
+ self .maxtries = 10
515
517
516
518
def http_error_default (self , url , fp , errcode , errmsg , headers ):
517
519
"""Default error handling -- don't raise an exception."""
518
520
return addinfourl (fp , headers , "http:" + url )
519
521
520
522
def http_error_302 (self , url , fp , errcode , errmsg , headers , data = None ):
521
523
"""Error 302 -- relocated (temporarily)."""
522
- # XXX The server can force infinite recursion here!
524
+ self .tries += 1
525
+ if self .maxtries and self .tries >= self .maxtries :
526
+ if hasattr (self , "http_error_500" ):
527
+ meth = self .http_error_500
528
+ else :
529
+ meth = self .http_error_default
530
+ self .tries = 0
531
+ return meth (url , fp , 500 ,
532
+ "Internal Server Error: Redirect Recursion" , headers )
533
+ result = self .redirect_internal (url , fp , errcode , errmsg , headers ,
534
+ data )
535
+ self .tries = 0
536
+ return result
537
+
538
+ def redirect_internal (self , url , fp , errcode , errmsg , headers , data ):
523
539
if headers .has_key ('location' ):
524
540
newurl = headers ['location' ]
525
541
elif headers .has_key ('uri' ):
@@ -555,6 +571,8 @@ def http_error_401(self, url, fp, errcode, errmsg, headers, data=None):
555
571
return getattr (self ,name )(url , realm )
556
572
else :
557
573
return getattr (self ,name )(url , realm , data )
574
+ return URLopener .http_error_default (self , url , fp ,
575
+ errcode , errmsg , headers )
558
576
559
577
def retry_http_basic_auth (self , url , realm , data = None ):
560
578
host , selector = splithost (url )
@@ -689,7 +707,7 @@ def retrfile(self, file, type):
689
707
cmd = 'RETR ' + file
690
708
conn = self .ftp .ntransfercmd (cmd )
691
709
except ftplib .error_perm , reason :
692
- if reason [:3 ] != '550' :
710
+ if str ( reason ) [:3 ] != '550' :
693
711
raise IOError , ('ftp error' , reason ), sys .exc_info ()[2 ]
694
712
if not conn :
695
713
# Set transfer mode to ASCII!
@@ -1036,7 +1054,7 @@ def _fast_quote(s):
1036
1054
for i in range (len (res )):
1037
1055
c = res [i ]
1038
1056
if not _fast_safe .has_key (c ):
1039
- res [i ] = '%%%02x ' % ord (c )
1057
+ res [i ] = '%%%02X ' % ord (c )
1040
1058
return string .join (res , '' )
1041
1059
1042
1060
def quote (s , safe = '/' ):
@@ -1067,7 +1085,7 @@ def quote(s, safe = '/'):
1067
1085
for i in range (len (res )):
1068
1086
c = res [i ]
1069
1087
if c not in safe :
1070
- res [i ] = '%%%02x ' % ord (c )
1088
+ res [i ] = '%%%02X ' % ord (c )
1071
1089
return string .join (res , '' )
1072
1090
1073
1091
def quote_plus (s , safe = '' ):
0 commit comments