##// END OF EJS Templates
http: handle push of bundles > 2 GB again (issue3017)...
Mads Kiilerich -
r15152:94b200a1 stable
parent child Browse files
Show More
@@ -22,8 +22,9 b' from mercurial.i18n import _'
22 class httpsendfile(object):
22 class httpsendfile(object):
23 """This is a wrapper around the objects returned by python's "open".
23 """This is a wrapper around the objects returned by python's "open".
24
24
25 Its purpose is to send file-like objects via HTTP and, to do so, it
25 Its purpose is to send file-like objects via HTTP.
26 defines a __len__ attribute to feed the Content-Length header.
26 It do however not define a __len__ attribute because the length
27 might be more than Py_ssize_t can handle.
27 """
28 """
28
29
29 def __init__(self, ui, *args, **kwargs):
30 def __init__(self, ui, *args, **kwargs):
@@ -35,9 +36,9 b' class httpsendfile(object):'
35 self.seek = self._data.seek
36 self.seek = self._data.seek
36 self.close = self._data.close
37 self.close = self._data.close
37 self.write = self._data.write
38 self.write = self._data.write
38 self._len = os.fstat(self._data.fileno()).st_size
39 self.length = os.fstat(self._data.fileno()).st_size
39 self._pos = 0
40 self._pos = 0
40 self._total = self._len / 1024 * 2
41 self._total = self.length / 1024 * 2
41
42
42 def read(self, *args, **kwargs):
43 def read(self, *args, **kwargs):
43 try:
44 try:
@@ -54,9 +55,6 b' class httpsendfile(object):'
54 unit=_('kb'), total=self._total)
55 unit=_('kb'), total=self._total)
55 return ret
56 return ret
56
57
57 def __len__(self):
58 return self._len
59
60 # moved here from url.py to avoid a cycle
58 # moved here from url.py to avoid a cycle
61 def readauthforuri(ui, uri, user):
59 def readauthforuri(ui, uri, user):
62 # Read configuration
60 # Read configuration
@@ -74,9 +74,14 b' class httprepository(wireproto.wirerepos'
74 if cmd == 'pushkey':
74 if cmd == 'pushkey':
75 args['data'] = ''
75 args['data'] = ''
76 data = args.pop('data', None)
76 data = args.pop('data', None)
77 size = 0
78 if util.safehasattr(data, 'length'):
79 size = data.length
80 elif data is not None:
81 size = len(data)
77 headers = args.pop('headers', {})
82 headers = args.pop('headers', {})
78
83
79 if data and self.ui.configbool('ui', 'usehttp2', False):
84 if size and self.ui.configbool('ui', 'usehttp2', False):
80 headers['Expect'] = '100-Continue'
85 headers['Expect'] = '100-Continue'
81 headers['X-HgHttp2'] = '1'
86 headers['X-HgHttp2'] = '1'
82
87
@@ -105,9 +110,6 b' class httprepository(wireproto.wirerepos'
105 cu = "%s%s" % (self._url, qs)
110 cu = "%s%s" % (self._url, qs)
106 req = urllib2.Request(cu, data, headers)
111 req = urllib2.Request(cu, data, headers)
107 if data is not None:
112 if data is not None:
108 # len(data) is broken if data doesn't fit into Py_ssize_t
109 # add the header ourself to avoid OverflowError
110 size = data.__len__()
111 self.ui.debug("sending %s bytes\n" % size)
113 self.ui.debug("sending %s bytes\n" % size)
112 req.add_unredirected_header('Content-Length', '%d' % size)
114 req.add_unredirected_header('Content-Length', '%d' % size)
113 try:
115 try:
@@ -24,6 +24,10 b' import imp, socket, urllib'
24 def sha1(s):
24 def sha1(s):
25 return _fastsha1(s)
25 return _fastsha1(s)
26
26
27 _notset = object()
28 def safehasattr(thing, attr):
29 return getattr(thing, attr, _notset) is not _notset
30
27 def _fastsha1(s):
31 def _fastsha1(s):
28 # This function will import sha1 from hashlib or sha (whichever is
32 # This function will import sha1 from hashlib or sha (whichever is
29 # available) and overwrite itself with it on the first call.
33 # available) and overwrite itself with it on the first call.
General Comments 0
You need to be logged in to leave comments. Login now