diff --git a/requests/utils.py b/requests/utils.py index dfeb77d9..0982ca41 100644 --- a/requests/utils.py +++ b/requests/utils.py @@ -45,7 +45,7 @@ def dict_to_sequence(d): def super_len(o): - total_length = 0 + total_length = None current_position = 0 if hasattr(o, '__len__'): @@ -54,10 +54,6 @@ def super_len(o): elif hasattr(o, 'len'): total_length = o.len - elif hasattr(o, 'getvalue'): - # e.g. BytesIO, cStringIO.StringIO - total_length = len(o.getvalue()) - elif hasattr(o, 'fileno'): try: fileno = o.fileno() @@ -89,6 +85,13 @@ def super_len(o): # let requests chunk it instead. current_position = total_length + if hasattr(o, 'seek') and total_length is None: + # StringIO has a notimplemented fileno + # BytesIO has seek and not fileno + total_length = o.seek(0, 2) + # seek back to current position to support partially read file-like + o.seek(current_position) + return max(0, total_length - current_position)