Read 'size' bytes from remote.
(self, size)
| 337 | |
| 338 | |
| 339 | def read(self, size): |
| 340 | """Read 'size' bytes from remote.""" |
| 341 | # We need buffered read() to continue working after socket timeouts, |
| 342 | # since we use them during IDLE. Unfortunately, the standard library's |
| 343 | # SocketIO implementation makes this impossible, by setting a permanent |
| 344 | # error condition instead of letting the caller decide how to handle a |
| 345 | # timeout. We therefore implement our own buffered read(). |
| 346 | # https://github.com/python/cpython/issues/51571 |
| 347 | # |
| 348 | # Reading in chunks instead of delegating to a single |
| 349 | # BufferedReader.read() call also means we avoid its preallocation |
| 350 | # of an unreasonably large memory block if a malicious server claims |
| 351 | # it will send a huge literal without actually sending one. |
| 352 | # https://github.com/python/cpython/issues/119511 |
| 353 | |
| 354 | parts = [] |
| 355 | |
| 356 | while size > 0: |
| 357 | |
| 358 | if len(parts) < len(self._readbuf): |
| 359 | buf = self._readbuf[len(parts)] |
| 360 | else: |
| 361 | try: |
| 362 | buf = self.sock.recv(DEFAULT_BUFFER_SIZE) |
| 363 | except ConnectionError: |
| 364 | break |
| 365 | if not buf: |
| 366 | break |
| 367 | self._readbuf.append(buf) |
| 368 | |
| 369 | if len(buf) >= size: |
| 370 | parts.append(buf[:size]) |
| 371 | self._readbuf = [buf[size:]] + self._readbuf[len(parts):] |
| 372 | break |
| 373 | parts.append(buf) |
| 374 | size -= len(buf) |
| 375 | |
| 376 | return b''.join(parts) |
| 377 | |
| 378 | |
| 379 | def readline(self): |