| 
					
				 | 
			
			
				@@ -287,16 +287,6 @@ class FileDownloader(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		multiplier = 1024.0 ** 'bkmgtpezy'.index(matchobj.group(2).lower()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return long(round(number * multiplier)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	@staticmethod 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	def verify_url(url): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		"""Verify a URL is valid and data could be downloaded. Return real data URL.""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		request = urllib2.Request(url, None, std_headers) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		data = urllib2.urlopen(request) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		data.read(1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		url = data.geturl() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		data.close() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return url 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	def add_info_extractor(self, ie): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		"""Add an InfoExtractor object to the end of the list.""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		self._ies.append(ie) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -396,13 +386,6 @@ class FileDownloader(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		"""Process a single dictionary returned by an InfoExtractor.""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		# Do nothing else if in simulate mode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if self.params.get('simulate', False): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			# Verify URL if it's an HTTP one 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if info_dict['url'].startswith('http'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					self.verify_url(info_dict['url'].encode('utf-8')).decode('utf-8') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				except (OSError, IOError, urllib2.URLError, httplib.HTTPException, socket.error), err: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					raise UnavailableVideoError 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			# Forced printings 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if self.params.get('forcetitle', False): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				print info_dict['title'].encode(preferredencoding(), 'xmlcharrefreplace') 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -539,32 +522,43 @@ class FileDownloader(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		count = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		retries = self.params.get('retries', 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		while True: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		while count <= retries: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			# Establish connection 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				data = urllib2.urlopen(request) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			except (urllib2.HTTPError, ), err: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if err.code == 503: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					# Retry in case of HTTP error 503 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					count += 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if count <= retries: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						self.report_retry(count, retries) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if err.code != 416: #  416 is 'Requested range not satisfiable' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if err.code != 503 and err.code != 416: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					# Unexpected HTTP error 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					raise 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				# Unable to resume 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				data = urllib2.urlopen(basic_request) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				content_length = data.info()['Content-Length'] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if content_length is not None and long(content_length) == resume_len: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					# Because the file had already been fully downloaded 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					self.report_file_already_downloaded(filename) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					return True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					# Because the server didn't let us 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					self.report_unable_to_resume() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					open_mode = 'wb' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				elif err.code == 416: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					# Unable to resume (requested range not satisfiable) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						# Open the connection again without the range header 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						data = urllib2.urlopen(basic_request) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						content_length = data.info()['Content-Length'] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					except (urllib2.HTTPError, ), err: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						if err.code != 503: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							raise 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						# Examine the reported length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						if content_length is not None and long(content_length) == resume_len: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							# The file had already been fully downloaded 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							self.report_file_already_downloaded(filename) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							return True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							# The length does not match, we start the download over 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							self.report_unable_to_resume() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							open_mode = 'wb' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+							break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			# Retry 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			count += 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if count <= retries: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				self.report_retry(count, retries) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if count > retries: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			self.trouble(u'ERROR: giving up after %s retries' % retries) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		data_len = data.info().get('Content-length', None) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		data_len_str = self.format_bytes(data_len) 
			 |