Mercurial > hg
comparison mercurial/httpclient/__init__.py @ 19038:36733ab7fa05
http2: sane readline
It turns out that it pays off to read more than a byte at a time with
a select in between :)
author | Brendan Cully <brendan@kublai.com> |
---|---|
date | Fri, 01 Feb 2013 15:00:23 -0800 |
parents | 31f32a96e1e3 |
children | fae47ecaa952 |
comparison
equal
deleted
inserted
replaced
19037:1fde25ad9396 | 19038:36733ab7fa05 |
---|---|
123 """Read a single line from the response body. | 123 """Read a single line from the response body. |
124 | 124 |
125 This may block until either a line ending is found or the | 125 This may block until either a line ending is found or the |
126 response is complete. | 126 response is complete. |
127 """ | 127 """ |
128 # TODO: move this into the reader interface where it can be | 128 blocks = [] |
129 # smarter (and probably avoid copies) | 129 while True: |
130 bytes = [] | 130 self._reader.readto('\n', blocks) |
131 while not bytes: | 131 |
132 try: | 132 if blocks and blocks[-1][-1] == '\n' or self.complete(): |
133 bytes = [self._reader.read(1)] | 133 break |
134 except _readers.ReadNotReady: | 134 |
135 self._select() | |
136 while bytes[-1] != '\n' and not self.complete(): | |
137 self._select() | 135 self._select() |
138 bytes.append(self._reader.read(1)) | 136 |
139 if bytes[-1] != '\n': | 137 return ''.join(blocks) |
140 next = self._reader.read(1) | |
141 while next and next != '\n': | |
142 bytes.append(next) | |
143 next = self._reader.read(1) | |
144 bytes.append(next) | |
145 return ''.join(bytes) | |
146 | 138 |
147 def read(self, length=None): | 139 def read(self, length=None): |
148 # if length is None, unbounded read | 140 # if length is None, unbounded read |
149 while (not self.complete() # never select on a finished read | 141 while (not self.complete() # never select on a finished read |
150 and (not length # unbounded, so we wait for complete() | 142 and (not length # unbounded, so we wait for complete() |