From cd799ddfcdccf1d3f5ab6c2e2d6acfde9d8b023d Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 18 Oct 2018 04:07:13 -0700 Subject: [PATCH] cookies --- responder/api.py | 13 ++++++++++++- responder/models.py | 25 ++++++++++++++++++------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/responder/api.py b/responder/api.py index ab73130..e4480a0 100644 --- a/responder/api.py +++ b/responder/api.py @@ -162,6 +162,13 @@ class API: if route_object.does_match(path): return route + def _prepare_cookies(self, resp): + if resp.cookies: + header = " ".join([f"{k}={v}" for k, v in resp.cookies.items()]) + header = f"Set-Cookie: {header}" + + resp.headers["Set-Cookie"] = header + async def _dispatch_request(self, req): # Set formats on Request object. req.formats = self.formats @@ -219,9 +226,13 @@ class API: else: self.default_response(req, resp) + self._prepare_cookies(resp) + return resp - def add_route(self, route, endpoint=None, *, default=False, static=False, check_existing=True): + def add_route( + self, route, endpoint=None, *, default=False, static=False, check_existing=True + ): """Add a route to the API. :param route: A string representation of the route. diff --git a/responder/models.py b/responder/models.py index cecc31b..5270a2c 100644 --- a/responder/models.py +++ b/responder/models.py @@ -1,17 +1,19 @@ import io import json import gzip +from http.cookies import SimpleCookie + import chardet import rfc3986 import graphene import yaml from requests.structures import CaseInsensitiveDict +from requests.cookies import RequestsCookieJar from starlette.datastructures import MutableHeaders from starlette.requests import Request as StarletteRequest from starlette.responses import Response as StarletteResponse - from urllib.parse import parse_qs from .status_codes import HTTP_200 @@ -88,12 +90,7 @@ class QueryDict(dict): # TODO: add slots class Request: - __slots__ = [ - "_starlette", - "formats", - "_headers", - "_encoding", - ] + __slots__ = ["_starlette", "formats", "_headers", "_encoding"] def __init__(self, scope, receive): self._starlette = StarletteRequest(scope, receive) @@ -130,6 +127,18 @@ class Request: """The parsed URL of the Request.""" return rfc3986.urlparse(self.full_url) + @property + def cookies(self): + cookies = RequestsCookieJar() + cookie_header = self.headers.get("cookie", "") + + # if cookie_header: + bc = SimpleCookie(cookie_header) + for k, v in bc.items(): + cookies[k] = v + + return cookies + @property def params(self): """A dictionary of the parsed query parameters used for the Request.""" @@ -216,6 +225,7 @@ class Response: "media", "headers", "formats", + "cookies", ] def __init__(self, req, *, formats): @@ -231,6 +241,7 @@ class Response: {} ) #: A Python dictionary of {Key: value}, representing the headers of the response. self.formats = formats + self.cookies = {} # req.cookies @property async def body(self):