mercurial/statichttprepo.py
changeset 7274 95f3694cc5a4
parent 7211 25c0dee16ee0
child 7637 1d54e2f6c0b7
equal deleted inserted replaced
7273:84f807918864 7274:95f3694cc5a4
     6 #
     6 #
     7 # This software may be used and distributed according to the terms
     7 # This software may be used and distributed according to the terms
     8 # of the GNU General Public License, incorporated herein by reference.
     8 # of the GNU General Public License, incorporated herein by reference.
     9 
     9 
    10 from i18n import _
    10 from i18n import _
    11 import changelog, httprangereader
    11 import changelog, byterange, url
    12 import repo, localrepo, manifest, util, store
    12 import repo, localrepo, manifest, util, store
    13 import urllib, urllib2, errno
    13 import urllib, urllib2, errno
    14 
    14 
    15 class rangereader(httprangereader.httprangereader):
    15 class httprangereader(object):
    16     def read(self, size=None):
    16     def __init__(self, url, opener):
       
    17         # we assume opener has HTTPRangeHandler
       
    18         self.url = url
       
    19         self.pos = 0
       
    20         self.opener = opener
       
    21     def seek(self, pos):
       
    22         self.pos = pos
       
    23     def read(self, bytes=None):
       
    24         req = urllib2.Request(self.url)
       
    25         end = ''
       
    26         if bytes:
       
    27             end = self.pos + bytes - 1
       
    28         req.add_header('Range', 'bytes=%d-%s' % (self.pos, end))
       
    29 
    17         try:
    30         try:
    18             return httprangereader.httprangereader.read(self, size)
    31             f = self.opener.open(req)
       
    32             data = f.read()
    19         except urllib2.HTTPError, inst:
    33         except urllib2.HTTPError, inst:
    20             num = inst.code == 404 and errno.ENOENT or None
    34             num = inst.code == 404 and errno.ENOENT or None
    21             raise IOError(num, inst)
    35             raise IOError(num, inst)
    22         except urllib2.URLError, inst:
    36         except urllib2.URLError, inst:
    23             raise IOError(None, inst.reason[1])
    37             raise IOError(None, inst.reason[1])
    24 
    38 
    25 def opener(base):
    39         if bytes:
    26     """return a function that opens files over http"""
    40             data = data[:bytes]
    27     p = base
    41         return data
    28     def o(path, mode="r"):
    42 
    29         f = "/".join((p, urllib.quote(path)))
    43 def build_opener(ui, authinfo):
    30         return rangereader(f)
    44     # urllib cannot handle URLs with embedded user or passwd
    31     return o
    45     urlopener = url.opener(ui, authinfo)
       
    46     urlopener.add_handler(byterange.HTTPRangeHandler())
       
    47 
       
    48     def opener(base):
       
    49         """return a function that opens files over http"""
       
    50         p = base
       
    51         def o(path, mode="r"):
       
    52             f = "/".join((p, urllib.quote(path)))
       
    53             return httprangereader(f, urlopener)
       
    54         return o
       
    55 
       
    56     return opener
    32 
    57 
    33 class statichttprepository(localrepo.localrepository):
    58 class statichttprepository(localrepo.localrepository):
    34     def __init__(self, ui, path):
    59     def __init__(self, ui, path):
    35         self._url = path
    60         self._url = path
    36         self.ui = ui
    61         self.ui = ui
    37 
    62 
    38         self.path = path.rstrip('/') + "/.hg"
    63         self.path, authinfo = url.getauthinfo(path.rstrip('/') + "/.hg")
       
    64 
       
    65         opener = build_opener(ui, authinfo)
    39         self.opener = opener(self.path)
    66         self.opener = opener(self.path)
    40 
    67 
    41         # find requirements
    68         # find requirements
    42         try:
    69         try:
    43             requirements = self.opener("requires").read().splitlines()
    70             requirements = self.opener("requires").read().splitlines()