Remove expired cookies
diff --git a/httpie/client.py b/httpie/client.py
index 71a95213c7..65f88e43eb 100644
--- a/httpie/client.py
+++ b/httpie/client.py
@@ -11,14 +11,14 @@
 import requests
 # noinspection PyPackageRequirements
 import urllib3
+from requests.cookies import remove_cookie_by_name
 
 from httpie import __version__
 from httpie.cli.dicts import RequestHeadersDict
 from httpie.plugins.registry import plugin_manager
 from httpie.sessions import get_httpie_session
 from httpie.ssl import AVAILABLE_SSL_VERSION_ARG_MAPPING, HTTPieHTTPSAdapter
-from httpie.utils import repr_dict
-
+from httpie.utils import get_expired_cookies, repr_dict
 
 urllib3.disable_warnings()
 
@@ -82,6 +82,7 @@ def collect_messages(
     if args.compress and prepared_request.body:
         compress_body(prepared_request, always=args.compress > 1)
     response_count = 0
+    expired_cookies = []
     while prepared_request:
         yield prepared_request
         if not args.offline:
@@ -95,6 +96,10 @@ def collect_messages(
                     **send_kwargs_merged,
                     **send_kwargs,
                 )
+                expired_cookies += get_expired_cookies(
+                    headers=response.raw._original_response.msg._headers
+                )
+
             response_count += 1
             if response.next:
                 if args.max_redirects and response_count == args.max_redirects:
@@ -110,6 +115,9 @@ def collect_messages(
     if httpie_session:
         if httpie_session.is_new() or not args.session_read_only:
             httpie_session.cookies = requests_session.cookies
+            httpie_session.remove_cookies(
+                cookie['name'] for cookie in expired_cookies
+            )
             httpie_session.save()
 
 
diff --git a/httpie/sessions.py b/httpie/sessions.py
index 948ce324f5..5750f3de46 100644
--- a/httpie/sessions.py
+++ b/httpie/sessions.py
@@ -5,11 +5,11 @@
 import os
 import re
 from pathlib import Path
-from typing import Optional, Union
+from typing import Iterable, Optional, Union
 from urllib.parse import urlsplit
 
 from requests.auth import AuthBase
-from requests.cookies import RequestsCookieJar, create_cookie
+from requests.cookies import RequestsCookieJar, create_cookie, remove_cookie_by_name
 
 from httpie.cli.dicts import RequestHeadersDict
 from httpie.config import BaseConfigDict, DEFAULT_CONFIG_DIR
@@ -144,3 +144,8 @@ def auth(self) -> Optional[AuthBase]:
     def auth(self, auth: dict):
         assert {'type', 'raw_auth'} == auth.keys()
         self['auth'] = auth
+
+    def remove_cookies(self, names: Iterable[str]):
+        for name in names:
+            if name in self['cookies']:
+                del self['cookies'][name]
diff --git a/httpie/utils.py b/httpie/utils.py
index c5b60216b2..d47f3531c7 100644
--- a/httpie/utils.py
+++ b/httpie/utils.py
@@ -1,8 +1,12 @@
 from __future__ import division
+
 import json
 import mimetypes
+import time
 from collections import OrderedDict
+from http.cookiejar import parse_ns_headers
 from pprint import pformat
+from typing import List, Tuple
 
 import requests.auth
 
@@ -83,3 +87,27 @@ def get_content_type(filename):
         if encoding:
             content_type = '%s; charset=%s' % (mime, encoding)
         return content_type
+
+
+def get_expired_cookies(headers: List[Tuple[str, str]], curr_timestamp: float = None) -> List[dict]:
+    expired_cookies = []
+    cookie_headers = []
+    curr_timestamp = curr_timestamp or time.time()
+
+    for header_name, content in headers:
+        if header_name == 'Set-Cookie':
+            cookie_headers.append(content)
+
+    extracted_cookies = [
+        dict(cookie, name=cookie[0][0])
+        for cookie in parse_ns_headers(cookie_headers)
+    ]
+
+    for cookie in extracted_cookies:
+        if "expires" in cookie and cookie['expires'] <= curr_timestamp:
+            expired_cookies.append({
+                'name': cookie['name'],
+                'path': cookie.get('path', '/')
+            })
+
+    return expired_cookies
diff --git a/tests/test_sessions.py b/tests/test_sessions.py
index 3b7c7ed5f6..b547431036 100644
--- a/tests/test_sessions.py
+++ b/tests/test_sessions.py
@@ -1,14 +1,17 @@
 # coding=utf-8
+import json
 import os
 import shutil
-import sys
+from datetime import datetime
 from tempfile import gettempdir
 
 import pytest
 
+from fixtures import UNICODE
 from httpie.plugins.builtin import HTTPBasicAuth
+from httpie.sessions import Session
+from httpie.utils import get_expired_cookies
 from utils import MockEnvironment, mk_config_dir, http, HTTP_OK
-from fixtures import UNICODE
 
 
 class SessionTestBase:
@@ -186,3 +189,93 @@ def test_download_in_session(self, httpbin):
                  httpbin.url + '/get', env=self.env())
         finally:
             os.chdir(cwd)
+
+
+class TestExpiredCookies:
+
+    @pytest.mark.parametrize(
+        argnames=['initial_cookie', 'expired_cookie'],
+        argvalues=[
+            ({'id': {'value': 123}}, 'id'),
+            ({'id': {'value': 123}}, 'token')
+        ]
+    )
+    def test_removes_expired_cookies_from_session_obj(self, initial_cookie, expired_cookie, httpbin):
+        config_dir = mk_config_dir()
+        session = Session(config_dir)
+        session['cookies'] = initial_cookie
+        session.remove_cookies([expired_cookie])
+        assert expired_cookie not in session.cookies
+
+        shutil.rmtree(config_dir)
+
+    def test_expired_cookies(self, httpbin):
+        orig_session = {
+            'cookies': {
+                'to_expire': {
+                    'value': 'foo'
+                },
+                'to_stay': {
+                    'value': 'foo'
+                },
+            }
+        }
+        config_dir = mk_config_dir()
+        session_path = config_dir / 'test-session.json'
+        session_path.write_text(json.dumps(orig_session))
+
+        r = http(
+            '--session', str(session_path),
+            '--print=H',
+            httpbin.url + '/cookies/delete?to_expire',
+        )
+        assert 'Cookie: to_expire=foo; to_stay=foo' in r
+
+        updated_session = json.loads(session_path.read_text())
+        assert 'to_stay' in updated_session['cookies']
+        assert 'to_expire' not in updated_session['cookies']
+
+        shutil.rmtree(config_dir)
+
+    @pytest.mark.parametrize(
+        argnames=['raw_header', 'timestamp', 'expected'],
+        argvalues=[
+            (
+                [
+                    ('Set-Cookie', 'hello=world; Path=/; Expires=Thu, 01-Jan-1970 00:00:00 GMT; HttpOnly'),
+                    ('Connection', 'keep-alive')
+                ],
+                None,
+                [
+                    {
+                        'name': 'hello',
+                        'path': '/'
+                    }
+                ]
+            ),
+            (
+                [
+                    ('Set-Cookie', 'hello=world; Path=/; Expires=Thu, 01-Jan-1970 00:00:00 GMT; HttpOnly'),
+                    ('Set-Cookie', 'pea=pod; Path=/ab; Expires=Thu, 01-Jan-1970 00:00:00 GMT; HttpOnly'),
+                    ('Connection', 'keep-alive')
+                ],
+                None,
+                [
+                    {'name': 'hello', 'path': '/'},
+                    {'name': 'pea', 'path': '/ab'}
+                ]
+            ),
+            (
+                [
+                    ('Set-Cookie', 'hello=world; Path=/; Expires=Fri, 12 Jun 2020 12:28:55 GMT; HttpOnly'),
+                    ('Connection', 'keep-alive')
+                ],
+                datetime(2020, 6, 11).timestamp(),
+                [
+
+                ]
+            )
+        ]
+    )
+    def test_get_expired_cookies_manages_multiple_cookie_headers(self, raw_header, timestamp, expected):
+        assert get_expired_cookies(raw_header, curr_timestamp=timestamp) == expected

This pull request should fix [#853 ](https://github.com/jakubroztocil/httpie/issues/853) @kbanc @juped