OLD | NEW |
1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
2 # Copyright 2014 Google Inc. All Rights Reserved. | 2 # Copyright 2014 Google Inc. All Rights Reserved. |
3 # | 3 # |
4 # Licensed under the Apache License, Version 2.0 (the "License"); | 4 # Licensed under the Apache License, Version 2.0 (the "License"); |
5 # you may not use this file except in compliance with the License. | 5 # you may not use this file except in compliance with the License. |
6 # You may obtain a copy of the License at | 6 # You may obtain a copy of the License at |
7 # | 7 # |
8 # http://www.apache.org/licenses/LICENSE-2.0 | 8 # http://www.apache.org/licenses/LICENSE-2.0 |
9 # | 9 # |
10 # Unless required by applicable law or agreed to in writing, software | 10 # Unless required by applicable law or agreed to in writing, software |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 httplib2 handles media by storing entire chunks of responses in memory, which | 447 httplib2 handles media by storing entire chunks of responses in memory, which |
448 is undesirable particularly when multiple instances are used during | 448 is undesirable particularly when multiple instances are used during |
449 multi-threaded/multi-process copy. This class copies and then overrides some | 449 multi-threaded/multi-process copy. This class copies and then overrides some |
450 httplib2 functions to use a streaming copy approach that uses small memory | 450 httplib2 functions to use a streaming copy approach that uses small memory |
451 buffers. | 451 buffers. |
452 | 452 |
453 Also disables httplib2 retries (for reasons stated in the HttpWithNoRetries | 453 Also disables httplib2 retries (for reasons stated in the HttpWithNoRetries |
454 class doc). | 454 class doc). |
455 """ | 455 """ |
456 | 456 |
457 def __init__(self, stream=None, *args, **kwds): | 457 def __init__(self, *args, **kwds): |
458 if stream is None: | 458 self._stream = None |
459 raise apitools_exceptions.InvalidUserInputError( | |
460 'Cannot create HttpWithDownloadStream with no stream') | |
461 self._stream = stream | |
462 self._logger = logging.getLogger() | 459 self._logger = logging.getLogger() |
463 super(HttpWithDownloadStream, self).__init__(*args, **kwds) | 460 super(HttpWithDownloadStream, self).__init__(*args, **kwds) |
464 | 461 |
465 @property | 462 @property |
466 def stream(self): | 463 def stream(self): |
467 return self._stream | 464 return self._stream |
468 | 465 |
| 466 @stream.setter |
| 467 def stream(self, value): |
| 468 self._stream = value |
| 469 |
469 def _conn_request(self, conn, request_uri, method, body, headers): # pylint:
disable=too-many-statements | 470 def _conn_request(self, conn, request_uri, method, body, headers): # pylint:
disable=too-many-statements |
470 try: | 471 try: |
471 if hasattr(conn, 'sock') and conn.sock is None: | 472 if hasattr(conn, 'sock') and conn.sock is None: |
472 conn.connect() | 473 conn.connect() |
473 conn.request(method, request_uri, body, headers) | 474 conn.request(method, request_uri, body, headers) |
474 except socket.timeout: | 475 except socket.timeout: |
475 raise | 476 raise |
476 except socket.gaierror: | 477 except socket.gaierror: |
477 conn.close() | 478 conn.close() |
478 raise httplib2.ServerNotFoundError( | 479 raise httplib2.ServerNotFoundError( |
(...skipping 27 matching lines...) Expand all Loading... |
506 else: | 507 else: |
507 if response.status in (httplib.OK, httplib.PARTIAL_CONTENT): | 508 if response.status in (httplib.OK, httplib.PARTIAL_CONTENT): |
508 content_length = None | 509 content_length = None |
509 if hasattr(response, 'msg'): | 510 if hasattr(response, 'msg'): |
510 content_length = response.getheader('content-length') | 511 content_length = response.getheader('content-length') |
511 http_stream = response | 512 http_stream = response |
512 bytes_read = 0 | 513 bytes_read = 0 |
513 while True: | 514 while True: |
514 new_data = http_stream.read(TRANSFER_BUFFER_SIZE) | 515 new_data = http_stream.read(TRANSFER_BUFFER_SIZE) |
515 if new_data: | 516 if new_data: |
| 517 if self.stream is None: |
| 518 raise apitools_exceptions.InvalidUserInputError( |
| 519 'Cannot exercise HttpWithDownloadStream with no stream') |
516 self.stream.write(new_data) | 520 self.stream.write(new_data) |
517 bytes_read += len(new_data) | 521 bytes_read += len(new_data) |
518 else: | 522 else: |
519 break | 523 break |
520 | 524 |
521 if (content_length is not None and | 525 if (content_length is not None and |
522 long(bytes_read) != long(content_length)): | 526 long(bytes_read) != long(content_length)): |
523 # The input stream terminated before we were able to read the | 527 # The input stream terminated before we were able to read the |
524 # entire contents, possibly due to a network condition. Set | 528 # entire contents, possibly due to a network condition. Set |
525 # content-length to indicate how many bytes we actually read. | 529 # content-length to indicate how many bytes we actually read. |
526 self._logger.log( | 530 self._logger.log( |
527 logging.DEBUG, 'Only got %s bytes out of content-length %s ' | 531 logging.DEBUG, 'Only got %s bytes out of content-length %s ' |
528 'for request URI %s. Resetting content-length to match ' | 532 'for request URI %s. Resetting content-length to match ' |
529 'bytes read.', bytes_read, content_length, request_uri) | 533 'bytes read.', bytes_read, content_length, request_uri) |
530 response.msg['content-length'] = str(bytes_read) | 534 response.msg['content-length'] = str(bytes_read) |
531 response = httplib2.Response(response) | 535 response = httplib2.Response(response) |
532 else: | 536 else: |
533 # We fall back to the current httplib2 behavior if we're | 537 # We fall back to the current httplib2 behavior if we're |
534 # not processing bytes (eg it's a redirect). | 538 # not processing bytes (eg it's a redirect). |
535 content = response.read() | 539 content = response.read() |
536 response = httplib2.Response(response) | 540 response = httplib2.Response(response) |
537 # pylint: disable=protected-access | 541 # pylint: disable=protected-access |
538 content = httplib2._decompressContent(response, content) | 542 content = httplib2._decompressContent(response, content) |
539 return (response, content) | 543 return (response, content) |
OLD | NEW |