Show More
@@ -380,22 +380,9 b' class HTTPHandler(KeepAliveHandler, urlr' | |||
|
380 | 380 | |
|
381 | 381 | class HTTPResponse(httplib.HTTPResponse): |
|
382 | 382 | # we need to subclass HTTPResponse in order to |
|
383 | # 1) add readline(), readlines(), and readinto() methods | |
|
384 |
# 2) add |
|
|
385 | # 3) add info() and geturl() methods | |
|
386 | ||
|
387 | # in order to add readline(), read must be modified to deal with a | |
|
388 | # buffer. example: readline must read a buffer and then spit back | |
|
389 | # one line at a time. The only real alternative is to read one | |
|
390 | # BYTE at a time (ick). Once something has been read, it can't be | |
|
391 | # put back (ok, maybe it can, but that's even uglier than this), | |
|
392 | # so if you THEN do a normal read, you must first take stuff from | |
|
393 | # the buffer. | |
|
394 | ||
|
395 | # the read method wraps the original to accommodate buffering, | |
|
396 | # although read() never adds to the buffer. | |
|
397 | # Both readline and readlines have been stolen with almost no | |
|
398 | # modification from socket.py | |
|
383 | # 1) add close_connection() methods | |
|
384 | # 2) add info() and geturl() methods | |
|
385 | # 3) add accounting for read(), readlines() and readinto() | |
|
399 | 386 | |
|
400 | 387 | def __init__(self, sock, debuglevel=0, strict=0, method=None): |
|
401 | 388 | httplib.HTTPResponse.__init__( |
@@ -411,9 +398,6 b' class HTTPResponse(httplib.HTTPResponse)' | |||
|
411 | 398 | self._url = None # (same) |
|
412 | 399 | self._connection = None # (same) |
|
413 | 400 | |
|
414 | _raw_read = httplib.HTTPResponse.read | |
|
415 | _raw_readinto = getattr(httplib.HTTPResponse, 'readinto', None) | |
|
416 | ||
|
417 | 401 | # Python 2.7 has a single close() which closes the socket handle. |
|
418 | 402 | # This method was effectively renamed to _close_conn() in Python 3. But |
|
419 | 403 | # there is also a close(). _close_conn() is called by methods like |
@@ -442,23 +426,7 b' class HTTPResponse(httplib.HTTPResponse)' | |||
|
442 | 426 | return self._url |
|
443 | 427 | |
|
444 | 428 | def read(self, amt=None): |
|
445 | # the _rbuf test is only in this first if for speed. It's not | |
|
446 | # logically necessary | |
|
447 | if self._rbuf and amt is not None: | |
|
448 | L = len(self._rbuf) | |
|
449 | if amt > L: | |
|
450 | amt -= L | |
|
451 | else: | |
|
452 | s = self._rbuf[:amt] | |
|
453 | self._rbuf = self._rbuf[amt:] | |
|
454 | return s | |
|
455 | # Careful! http.client.HTTPResponse.read() on Python 3 is | |
|
456 | # implemented using readinto(), which can duplicate self._rbuf | |
|
457 | # if it's not empty. | |
|
458 | s = self._rbuf | |
|
459 | self._rbuf = b'' | |
|
460 | data = self._raw_read(amt) | |
|
461 | ||
|
429 | data = super().read(amt) | |
|
462 | 430 | self.receivedbytescount += len(data) |
|
463 | 431 | try: |
|
464 | 432 | self._connection.receivedbytescount += len(data) |
@@ -468,137 +436,32 b' class HTTPResponse(httplib.HTTPResponse)' | |||
|
468 | 436 | self._handler.parent.receivedbytescount += len(data) |
|
469 | 437 | except AttributeError: |
|
470 | 438 | pass |
|
471 | ||
|
472 | s += data | |
|
473 | return s | |
|
474 | ||
|
475 | # stolen from Python SVN #68532 to fix issue1088 | |
|
476 | def _read_chunked(self, amt): | |
|
477 | chunk_left = self.chunk_left | |
|
478 | parts = [] | |
|
479 | ||
|
480 | while True: | |
|
481 | if chunk_left is None: | |
|
482 | line = self.fp.readline() | |
|
483 | i = line.find(b';') | |
|
484 | if i >= 0: | |
|
485 | line = line[:i] # strip chunk-extensions | |
|
486 | try: | |
|
487 | chunk_left = int(line, 16) | |
|
488 | except ValueError: | |
|
489 | # close the connection as protocol synchronization is | |
|
490 | # probably lost | |
|
491 | self.close() | |
|
492 | raise httplib.IncompleteRead(b''.join(parts)) | |
|
493 | if chunk_left == 0: | |
|
494 | break | |
|
495 | if amt is None: | |
|
496 | parts.append(self._safe_read(chunk_left)) | |
|
497 | elif amt < chunk_left: | |
|
498 | parts.append(self._safe_read(amt)) | |
|
499 | self.chunk_left = chunk_left - amt | |
|
500 | return b''.join(parts) | |
|
501 | elif amt == chunk_left: | |
|
502 | parts.append(self._safe_read(amt)) | |
|
503 | self._safe_read(2) # toss the CRLF at the end of the chunk | |
|
504 | self.chunk_left = None | |
|
505 | return b''.join(parts) | |
|
506 | else: | |
|
507 | parts.append(self._safe_read(chunk_left)) | |
|
508 | amt -= chunk_left | |
|
509 | ||
|
510 | # we read the whole chunk, get another | |
|
511 | self._safe_read(2) # toss the CRLF at the end of the chunk | |
|
512 | chunk_left = None | |
|
513 | ||
|
514 | # read and discard trailer up to the CRLF terminator | |
|
515 | ### note: we shouldn't have any trailers! | |
|
516 | while True: | |
|
517 | line = self.fp.readline() | |
|
518 | if not line: | |
|
519 | # a vanishingly small number of sites EOF without | |
|
520 | # sending the trailer | |
|
521 | break | |
|
522 | if line == b'\r\n': | |
|
523 | break | |
|
524 | ||
|
525 | # we read everything; close the "file" | |
|
526 | self.close() | |
|
527 | ||
|
528 | return b''.join(parts) | |
|
439 | return data | |
|
529 | 440 | |
|
530 | 441 | def readline(self): |
|
531 | # Fast path for a line is already available in read buffer. | |
|
532 | i = self._rbuf.find(b'\n') | |
|
533 | if i >= 0: | |
|
534 | i += 1 | |
|
535 | line = self._rbuf[:i] | |
|
536 | self._rbuf = self._rbuf[i:] | |
|
537 | return line | |
|
538 | ||
|
539 | # No newline in local buffer. Read until we find one. | |
|
540 | # readinto read via readinto will already return _rbuf | |
|
541 | if self._raw_readinto is None: | |
|
542 | chunks = [self._rbuf] | |
|
543 | else: | |
|
544 | chunks = [] | |
|
545 | i = -1 | |
|
546 | readsize = self._rbufsize | |
|
547 | while True: | |
|
548 | new = self._raw_read(readsize) | |
|
549 | if not new: | |
|
550 | break | |
|
551 | ||
|
552 | self.receivedbytescount += len(new) | |
|
553 | self._connection.receivedbytescount += len(new) | |
|
442 | data = super().readline() | |
|
443 | self.receivedbytescount += len(data) | |
|
554 | 444 |
|
|
555 |
|
|
|
445 | self._connection.receivedbytescount += len(data) | |
|
446 | except AttributeError: | |
|
447 | pass | |
|
448 | try: | |
|
449 | self._handler.parent.receivedbytescount += len(data) | |
|
556 | 450 |
|
|
557 | 451 |
|
|
558 | ||
|
559 | chunks.append(new) | |
|
560 | i = new.find(b'\n') | |
|
561 | if i >= 0: | |
|
562 | break | |
|
563 | ||
|
564 | # We either have exhausted the stream or have a newline in chunks[-1]. | |
|
565 | ||
|
566 | # EOF | |
|
567 | if i == -1: | |
|
568 | self._rbuf = b'' | |
|
569 | return b''.join(chunks) | |
|
570 | ||
|
571 | i += 1 | |
|
572 | self._rbuf = chunks[-1][i:] | |
|
573 | chunks[-1] = chunks[-1][:i] | |
|
574 | return b''.join(chunks) | |
|
452 | return data | |
|
575 | 453 | |
|
576 | 454 | def readinto(self, dest): |
|
577 | if self._raw_readinto is None: | |
|
578 | res = self.read(len(dest)) | |
|
579 | if not res: | |
|
580 | return 0 | |
|
581 | dest[0 : len(res)] = res | |
|
582 | return len(res) | |
|
583 | total = len(dest) | |
|
584 | have = len(self._rbuf) | |
|
585 | if have >= total: | |
|
586 | dest[0:total] = self._rbuf[:total] | |
|
587 | self._rbuf = self._rbuf[total:] | |
|
588 | return total | |
|
589 | mv = memoryview(dest) | |
|
590 | got = self._raw_readinto(mv[have:total]) | |
|
591 | ||
|
455 | got = super().readinto(dest) | |
|
592 | 456 | self.receivedbytescount += got |
|
457 | try: | |
|
593 | 458 | self._connection.receivedbytescount += got |
|
594 | try: | |
|
595 | self._handler.receivedbytescount += got | |
|
596 | 459 | except AttributeError: |
|
597 | 460 | pass |
|
598 | ||
|
599 | dest[0:have] = self._rbuf | |
|
600 | got += len(self._rbuf) | |
|
601 | self._rbuf = b'' | |
|
461 | try: | |
|
462 | self._handler.parent.receivedbytescount += got | |
|
463 | except AttributeError: | |
|
464 | pass | |
|
602 | 465 | return got |
|
603 | 466 | |
|
604 | 467 |
General Comments 0
You need to be logged in to leave comments.
Login now