Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions aiohttp_client_cache/backends/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def __init__(
autoclose: bool = False,
cache_control: bool = False,
filter_fn: _FilterFn = lambda r: True,
restore_cookies: bool = True,
**kwargs: Any,
):
"""
Expand All @@ -64,6 +65,8 @@ def __init__(
filter_fn: function that takes a :py:class:`aiohttp.ClientResponse` object and
returns a boolean indicating whether or not that response should be cached. Will be
applied to both new and previously cached responses
restore_cookies: Copy cookies from cached responses (and their redirects) into the
session's cookie jar on a cache hit
"""
self.name = cache_name
self.expire_after = expire_after
Expand All @@ -73,6 +76,7 @@ def __init__(
self.cache_control = cache_control
self.filter_fn = filter_fn
self.autoclose = autoclose
self.restore_cookies = restore_cookies
self._disabled = contextvars.ContextVar('_disabled', default=False)

# Allows multiple redirects or other aliased URLs to point to the same cached response
Expand Down
2 changes: 2 additions & 0 deletions aiohttp_client_cache/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ async def _request(
return set_response_defaults(new_response)

def _restore_cookies(self, response: AnyResponse):
if not getattr(self.cache, 'restore_cookies', True):
return
self.cookie_jar.update_cookies(response.cookies or {}, response.url)
for redirect in response.history:
self.cookie_jar.update_cookies(redirect.cookies or {}, redirect.url)
Expand Down
10 changes: 10 additions & 0 deletions docs/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,16 @@ responses (on read). Example:
>>> cache = SQLiteCache(filter_fn=filter_by_size)
```

### Cookies

By default, cookies from a cached response (and any redirects in its history) are copied into the
session's cookie jar on a cache hit, as if the request had been sent. To keep cached responses from
modifying the active session's cookies, use `restore_cookies=False`:

```python
>>> cache = SQLiteCache(restore_cookies=False)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SQLiteCache is the lower-level storage implementation, not the session cache backend. Its constructor also requires a filename, so the example cannot run as written. Use SQLiteBackend instead:

from aiohttp_client_cache import CachedSession, SQLiteBackend

cache = SQLiteBackend(restore_cookies=False)

async with CachedSession(cache=cache) as session:
    ...

```

### Library Compatibility

This library works by extending `aiohttp.ClientSession`, and there are other libraries out there
Expand Down
21 changes: 21 additions & 0 deletions test/unit/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,27 @@ async def test_session__cookies(mock_request):
assert cookies['test_cookie'].value == 'value'


@patch.object(ClientSession, '_request', return_value=FakeCachedResponse)
async def test_session__cookies_not_restored(mock_request):
cache = MagicMock(spec=CacheBackend)
cache.restore_cookies = False
redirect = MagicMock(
url=URL('https://redirect.com'), cookies=SimpleCookie({'redirect_cookie': 'value'})
)
response = AsyncMock(
is_expired=False,
url=URL('https://test.com'),
cookies=SimpleCookie({'test_cookie': 'value'}),
history=[redirect],
)
cache.request.return_value = response

async with CachedSession(cache=cache) as session:
session.cookie_jar.clear()
await session.get('http://test.url')
assert len(session.cookie_jar) == 0


@patch.object(ClientSession, '_request', return_value=FakeCachedResponse)
async def test_session__redirect_cookies(mock_request):
cache = MagicMock(spec=CacheBackend)
Expand Down
Loading