Skip to content

Commit

Permalink
initial multi cookie attempt
Browse files Browse the repository at this point in the history
  • Loading branch information
peterstone2017 authored and YunchuWang committed Apr 21, 2022
1 parent 990bb95 commit e487530
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 14 deletions.
2 changes: 1 addition & 1 deletion azure/functions/_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def charset(self):

@property
@abc.abstractmethod
def headers(self) -> typing.MutableMapping[str, str]:
def headers(self):
pass

@abc.abstractmethod
Expand Down
18 changes: 8 additions & 10 deletions azure/functions/_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
import collections.abc
import io
import json
import typing
import types
import typing

from . import _abc

from ._thirdparty.werkzeug import datastructures as _wk_datastructures
from ._thirdparty.werkzeug import formparser as _wk_parser
from ._thirdparty.werkzeug import http as _wk_http
from ._thirdparty.werkzeug.datastructures import Headers


class BaseHeaders(collections.abc.Mapping):
Expand Down Expand Up @@ -40,13 +40,8 @@ class HttpRequestHeaders(BaseHeaders):
pass


class HttpResponseHeaders(BaseHeaders, collections.abc.MutableMapping):

def __setitem__(self, key: str, value: str):
self.__http_headers__[key.lower()] = value

def __delitem__(self, key: str):
del self.__http_headers__[key.lower()]
class HttpResponseHeaders(Headers):
pass


class HttpResponse(_abc.HttpResponse):
Expand Down Expand Up @@ -90,7 +85,10 @@ def __init__(self,

if headers is None:
headers = {}
self.__headers = HttpResponseHeaders(headers)

self.__headers = HttpResponseHeaders([])
for k, v in headers.items():
self.__headers.add_header(k, v)

if body is not None:
self.__set_body(body)
Expand Down
16 changes: 14 additions & 2 deletions azure/functions/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@

from azure.functions import _abc as azf_abc
from azure.functions import _http as azf_http

from . import meta

try:
from http.cookies import SimpleCookie
except ImportError:
from Cookie import SimpleCookie # type: ignore


class HttpRequest(azf_http.HttpRequest):
"""An HTTP request object."""
Expand Down Expand Up @@ -79,7 +83,8 @@ def encode(cls, obj: typing.Any, *,

if isinstance(obj, azf_abc.HttpResponse):
status = obj.status_code
headers = dict(obj.headers)
headers = obj.headers

if 'content-type' not in headers:
if obj.mimetype.startswith('text/'):
ct = f'{obj.mimetype}; charset={obj.charset}'
Expand All @@ -93,6 +98,12 @@ def encode(cls, obj: typing.Any, *,
else:
datum_body = meta.Datum(type='bytes', value=b'')

cookies = None
if "Set-Cookie" in headers:
cookies = [SimpleCookie(cookie) for cookie in
headers.get_all('Set-Cookie')]
headers.pop("Set-Cookie")

return meta.Datum(
type='http',
value=dict(
Expand All @@ -101,6 +112,7 @@ def encode(cls, obj: typing.Any, *,
n: meta.Datum(type='string', value=h)
for n, h in headers.items()
},
cookies=cookies,
body=datum_body,
)
)
Expand Down
48 changes: 48 additions & 0 deletions tests/test_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import azure.functions as func
import azure.functions.http as http
from azure.functions._http import HttpResponseHeaders


class TestHTTP(unittest.TestCase):
Expand Down Expand Up @@ -88,6 +89,53 @@ def test_http_output_type(self):
self.assertTrue(check_output_type(func.HttpResponse))
self.assertTrue(check_output_type(str))

def test_http_response_encode_to_datum_no_cookie(self):
resp = func.HttpResponse()
datum = http.HttpResponseConverter.encode(resp, expected_type=None)

self.assertEqual(datum.value["cookies"], None)

def test_http_response_encode_to_datum_with_cookies(self):
headers = HttpResponseHeaders()
headers.add("Set-Cookie",
'foo3=42; Domain=example.com; Expires=Thu, '
'12-Jan-2017 13:55:08 GMT; Path=/; Max-Age=10000000')
headers.add("Set-Cookie",
'foo3=43; Domain=example.com; Expires=Thu, 12-Jan-2018 '
'13:55:09 GMT; Path=/; Max-Age=10000000')
resp = func.HttpResponse(headers=headers)
datum = http.HttpResponseConverter.encode(resp, expected_type=None)

actual_cookies = datum.value['cookies']
self.assertIsNotNone(actual_cookies)
self.assertTrue(isinstance(actual_cookies, list))
self.assertTrue(len(actual_cookies), 2)
self.assertEqual(str(actual_cookies[0]),
"Set-Cookie: foo3=42; Domain=example.com; "
"expires=Thu, 12-Jan-2017 13:55:08 GMT; "
"Max-Age=10000000; Path=/")
self.assertEqual(str(actual_cookies[1]),
"Set-Cookie: foo3=43; Domain=example.com; "
"expires=Thu, 12-Jan-2018 13:55:09 GMT; "
"Max-Age=10000000; Path=/")

self.assertTrue("Set-Cookie" not in resp.headers)

def test_http_response_encode_to_datum_with_cookies_lower_case(self):
headers = HttpResponseHeaders()
headers.add("set-cookie",
'foo3=42; Domain=example.com; Path=/; Max-Age=10000.0')
resp = func.HttpResponse(headers=headers)
datum = http.HttpResponseConverter.encode(resp, expected_type=None)

actual_cookies = datum.value['cookies']
self.assertIsNotNone(actual_cookies)
self.assertTrue(isinstance(actual_cookies, list))
self.assertTrue(len(actual_cookies), 1)
self.assertEqual(str(actual_cookies[0]),
"Set-Cookie: foo3=42; Domain=example.com; "
"Max-Age=10000.0; Path=/")

def test_http_request_should_not_have_implicit_output(self):
self.assertFalse(http.HttpRequestConverter.has_implicit_output())

Expand Down
3 changes: 2 additions & 1 deletion tests/test_http_wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import azure.functions as func
from azure.functions._abc import TraceContext, RetryContext
from azure.functions._http import HttpResponseHeaders
from azure.functions._http_wsgi import (
WsgiRequest,
WsgiResponse,
Expand Down Expand Up @@ -153,7 +154,7 @@ def test_response_no_headers(self):

wsgi_response: WsgiResponse = WsgiResponse.from_app(app, environ)
func_response: func.HttpResponse = wsgi_response.to_func_response()
self.assertEqual(func_response.headers, {})
self.assertEqual(func_response.headers, HttpResponseHeaders([]))

def test_response_with_exception(self):
app = self._generate_wsgi_app(
Expand Down

0 comments on commit e487530

Please sign in to comment.