mercurial/byterange.py
changeset 27504 ce3ae9ccd800
parent 25660 328739ea70c3
child 28883 032c4c2f802a
equal deleted inserted replaced
27503:0f4596622273 27504:ce3ae9ccd800
    15 # This file is part of urlgrabber, a high-level cross-protocol url-grabber
    15 # This file is part of urlgrabber, a high-level cross-protocol url-grabber
    16 # Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko
    16 # Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko
    17 
    17 
    18 # $Id: byterange.py,v 1.9 2005/02/14 21:55:07 mstenner Exp $
    18 # $Id: byterange.py,v 1.9 2005/02/14 21:55:07 mstenner Exp $
    19 
    19 
       
    20 from __future__ import absolute_import
       
    21 
       
    22 import email
       
    23 import ftplib
       
    24 import mimetypes
    20 import os
    25 import os
       
    26 import re
       
    27 import socket
    21 import stat
    28 import stat
    22 import urllib
    29 import urllib
    23 import urllib2
    30 import urllib2
    24 import email.Utils
    31 
       
    32 addclosehook = urllib.addclosehook
       
    33 addinfourl = urllib.addinfourl
       
    34 splitattr = urllib.splitattr
       
    35 splitpasswd = urllib.splitpasswd
       
    36 splitport = urllib.splitport
       
    37 splituser = urllib.splituser
       
    38 unquote = urllib.unquote
    25 
    39 
    26 class RangeError(IOError):
    40 class RangeError(IOError):
    27     """Error raised when an unsatisfiable range is requested."""
    41     """Error raised when an unsatisfiable range is requested."""
    28     pass
    42     pass
    29 
    43 
   194     """FileHandler subclass that adds Range support.
   208     """FileHandler subclass that adds Range support.
   195     This class handles Range headers exactly like an HTTP
   209     This class handles Range headers exactly like an HTTP
   196     server would.
   210     server would.
   197     """
   211     """
   198     def open_local_file(self, req):
   212     def open_local_file(self, req):
   199         import mimetypes
       
   200         import email
       
   201         host = req.get_host()
   213         host = req.get_host()
   202         file = req.get_selector()
   214         file = req.get_selector()
   203         localfile = urllib.url2pathname(file)
   215         localfile = urllib.url2pathname(file)
   204         stats = os.stat(localfile)
   216         stats = os.stat(localfile)
   205         size = stats[stat.ST_SIZE]
   217         size = stats[stat.ST_SIZE]
   231 # Unfortunately, a large amount of base FTP code had to be copied
   243 # Unfortunately, a large amount of base FTP code had to be copied
   232 # from urllib and urllib2 in order to insert the FTP REST command.
   244 # from urllib and urllib2 in order to insert the FTP REST command.
   233 # Code modifications for range support have been commented as
   245 # Code modifications for range support have been commented as
   234 # follows:
   246 # follows:
   235 # -- range support modifications start/end here
   247 # -- range support modifications start/end here
   236 
       
   237 from urllib import splitport, splituser, splitpasswd, splitattr, \
       
   238                    unquote, addclosehook, addinfourl
       
   239 import ftplib
       
   240 import socket
       
   241 import mimetypes
       
   242 import email
       
   243 
   248 
   244 class FTPRangeHandler(urllib2.FTPHandler):
   249 class FTPRangeHandler(urllib2.FTPHandler):
   245     def ftp_open(self, req):
   250     def ftp_open(self, req):
   246         host = req.get_host()
   251         host = req.get_host()
   247         if not host:
   252         if not host:
   404     """
   409     """
   405     global _rangere
   410     global _rangere
   406     if range_header is None:
   411     if range_header is None:
   407         return None
   412         return None
   408     if _rangere is None:
   413     if _rangere is None:
   409         import re
       
   410         _rangere = re.compile(r'^bytes=(\d{1,})-(\d*)')
   414         _rangere = re.compile(r'^bytes=(\d{1,})-(\d*)')
   411     match = _rangere.match(range_header)
   415     match = _rangere.match(range_header)
   412     if match:
   416     if match:
   413         tup = range_tuple_normalize(match.group(1, 2))
   417         tup = range_tuple_normalize(match.group(1, 2))
   414         if tup and tup[1]:
   418         if tup and tup[1]: