Skip to content
Snippets Groups Projects
Verified Commit cb5c7db7 authored by Daniel Hornung's avatar Daniel Hornung
Browse files

FIX: Fixed undefined variable.

parent 937ceb48
No related branches found
No related tags found
2 merge requests!175BUG: Request responses without the "Set-Cookie" header no longer overwrite the...,!164Fix mypy errors
Pipeline #58108 passed
...@@ -83,8 +83,10 @@ class _WrappedHTTPResponse(CaosDBHTTPResponse): ...@@ -83,8 +83,10 @@ class _WrappedHTTPResponse(CaosDBHTTPResponse):
return self.response.status_code return self.response.status_code
def read(self, size: Optional[int] = None): def read(self, size: Optional[int] = None):
# FIXME This function behaves unexpectedly if `size` is larger than in the first run.
if self._stream_consumed is True: if self._stream_consumed is True:
raise RuntimeError("Stream is consumed") raise BufferError("Stream is consumed")
if self._buffer is None: if self._buffer is None:
# the buffer has been drained in the previous call. # the buffer has been drained in the previous call.
...@@ -97,18 +99,15 @@ class _WrappedHTTPResponse(CaosDBHTTPResponse): ...@@ -97,18 +99,15 @@ class _WrappedHTTPResponse(CaosDBHTTPResponse):
return self.response.content return self.response.content
if size is None or size == 0: if size is None or size == 0:
raise RuntimeError( raise BufferError(
"size parameter should not be None if the stream is not consumed yet") "`size` parameter can not be None or zero once reading has started with a non-zero "
"value.")
if len(self._buffer) >= size: if len(self._buffer) >= size:
# still enough bytes in the buffer # still enough bytes in the buffer
# FIXME: `chunk`` is used before definition result = self._buffer[:size]
raise NotImplementedError("chunk is undefined") self._buffer = self._buffer[size:]
return result
# # old code:
# result = chunk[:size]
# self._buffer = chunk[size:]
# return result
if self._generator is None: if self._generator is None:
# first call to this method # first call to this method
...@@ -119,16 +118,16 @@ class _WrappedHTTPResponse(CaosDBHTTPResponse): ...@@ -119,16 +118,16 @@ class _WrappedHTTPResponse(CaosDBHTTPResponse):
try: try:
# read new data into the buffer # read new data into the buffer
chunk = self._buffer + next(self._generator) chunk = self._buffer + next(self._generator)
result = chunk[:size] result = chunk[:size] # FIXME what if `size` is larger than at `iter_content(size)`?
if len(result) == 0: if len(result) == 0:
self._stream_consumed = True self._stream_consumed = True
self._buffer = chunk[size:] self._buffer = chunk[size:]
return result return result
except StopIteration: except StopIteration:
# drain buffer # drain buffer
result = self._buffer last_result = self._buffer
self._buffer = None self._buffer = None
return result return last_result
def getheader(self, name: str, default=None): def getheader(self, name: str, default=None):
return self.response.headers[name] if name in self.response.headers else default return self.response.headers[name] if name in self.response.headers else default
......
...@@ -25,14 +25,18 @@ ...@@ -25,14 +25,18 @@
# pylint: disable=missing-docstring # pylint: disable=missing-docstring
from __future__ import print_function, unicode_literals from __future__ import print_function, unicode_literals
import io
import re import re
from builtins import bytes, str # pylint: disable=redefined-builtin from builtins import bytes, str # pylint: disable=redefined-builtin
import requests
from linkahead import execute_query from linkahead import execute_query
from linkahead.configuration import _reset_config, get_config from linkahead.configuration import _reset_config, get_config
from linkahead.connection.authentication.interface import CredentialsAuthenticator from linkahead.connection.authentication.interface import CredentialsAuthenticator
from linkahead.connection.connection import (CaosDBServerConnection, from linkahead.connection.connection import (CaosDBServerConnection,
_DefaultCaosDBServerConnection, _DefaultCaosDBServerConnection,
_WrappedHTTPResponse,
configure_connection) configure_connection)
from linkahead.connection.mockup import (MockUpResponse, MockUpServerConnection, from linkahead.connection.mockup import (MockUpResponse, MockUpServerConnection,
_request_log_message) _request_log_message)
...@@ -324,3 +328,51 @@ def test_auth_token_connection(): ...@@ -324,3 +328,51 @@ def test_auth_token_connection():
"auth_token authenticator cannot log in " "auth_token authenticator cannot log in "
"again. You must provide a new authentication " "again. You must provide a new authentication "
"token.") "token.")
def test_buffer_read():
"""Test the buffering in _WrappedHTTPResponse.read()"""
class MockResponse(requests.Response):
def __init__(self, content: bytes):
"""A mock response
Parameters
----------
content : bytes
The fake content.
"""
super().__init__()
self._content = content
bio = io.BytesIO(expected)
self.raw = bio
expected = b"This response."
MockResponse(expected)
#############################
# Check for some exceptions #
#############################
resp = _WrappedHTTPResponse(response=MockResponse(expected))
with raises(BufferError) as rte:
resp.read(4)
resp.read()
assert "`size` parameter can not be None" in str(rte.value)
resp = _WrappedHTTPResponse(response=MockResponse(expected))
with raises(BufferError) as rte:
resp.read(4)
resp.read(0)
assert "`size` parameter can not be None" in str(rte.value)
print("---")
resp = _WrappedHTTPResponse(response=MockResponse(expected))
result = (
resp.read(4)
+ resp.read(2)
+ resp.read(2) # This line failed before.
+ resp.read(4) # Reading the rest in two chunks, because of current limitations in read().
+ resp.read(2)
)
assert result == expected
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment