This repository was archived by the owner on Mar 6, 2026. It is now read-only.
File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1717import base64
1818import calendar
1919import datetime
20+ from email .message import Message
2021import sys
2122import urllib
2223
@@ -63,6 +64,28 @@ def decorator(method):
6364 return decorator
6465
6566
67+ def parse_content_type (header_value ):
68+ """Parse a 'content-type' header value to get just the plain media-type (without parameters).
69+
70+ This is done using the class Message from email.message as suggested in PEP 594
71+ (because the cgi is now deprecated and will be removed in python 3.13,
72+ see https://peps.python.org/pep-0594/#cgi).
73+
74+ Args:
75+ header_value (str): The value of a 'content-type' header as a string.
76+
77+ Returns:
78+ str: A string with just the lowercase media-type from the parsed 'content-type' header.
79+ If the provided content-type is not parsable, returns 'text/plain',
80+ the default value for textual files.
81+ """
82+ m = Message ()
83+ m ["content-type" ] = header_value
84+ return (
85+ m .get_content_type ()
86+ ) # Despite the name, actually returns just the media-type
87+
88+
6689def utcnow ():
6790 """Returns the current UTC datetime.
6891
Original file line number Diff line number Diff line change @@ -218,7 +218,10 @@ def get(
218218
219219 if response .status == http_client .OK :
220220 content = _helpers .from_bytes (response .data )
221- if response .headers ["content-type" ] == "application/json" :
221+ if (
222+ _helpers .parse_content_type (response .headers ["content-type" ])
223+ == "application/json"
224+ ):
222225 try :
223226 return json .loads (content )
224227 except ValueError as caught_exc :
Original file line number Diff line number Diff line change @@ -176,6 +176,24 @@ def test_get_success_json():
176176 assert result [key ] == value
177177
178178
179+ def test_get_success_json_content_type_charset ():
180+ key , value = "foo" , "bar"
181+
182+ data = json .dumps ({key : value })
183+ request = make_request (
184+ data , headers = {"content-type" : "application/json; charset=UTF-8" }
185+ )
186+
187+ result = _metadata .get (request , PATH )
188+
189+ request .assert_called_once_with (
190+ method = "GET" ,
191+ url = _metadata ._METADATA_ROOT + PATH ,
192+ headers = _metadata ._METADATA_HEADERS ,
193+ )
194+ assert result [key ] == value
195+
196+
179197def test_get_success_retry ():
180198 key , value = "foo" , "bar"
181199
Original file line number Diff line number Diff line change @@ -51,6 +51,32 @@ def func2(): # pragma: NO COVER
5151 _helpers .copy_docstring (SourceClass )(func2 )
5252
5353
54+ def test_parse_content_type_plain ():
55+ assert _helpers .parse_content_type ("text/html" ) == "text/html"
56+ assert _helpers .parse_content_type ("application/xml" ) == "application/xml"
57+ assert _helpers .parse_content_type ("application/json" ) == "application/json"
58+
59+
60+ def test_parse_content_type_with_parameters ():
61+ content_type_html = "text/html; charset=UTF-8"
62+ content_type_xml = "application/xml; charset=UTF-16; version=1.0"
63+ content_type_json = "application/json; charset=UTF-8; indent=2"
64+ assert _helpers .parse_content_type (content_type_html ) == "text/html"
65+ assert _helpers .parse_content_type (content_type_xml ) == "application/xml"
66+ assert _helpers .parse_content_type (content_type_json ) == "application/json"
67+
68+
69+ def test_parse_content_type_missing_or_broken ():
70+ content_type_foo = None
71+ content_type_bar = ""
72+ content_type_baz = "1234"
73+ content_type_qux = " ; charset=UTF-8"
74+ assert _helpers .parse_content_type (content_type_foo ) == "text/plain"
75+ assert _helpers .parse_content_type (content_type_bar ) == "text/plain"
76+ assert _helpers .parse_content_type (content_type_baz ) == "text/plain"
77+ assert _helpers .parse_content_type (content_type_qux ) == "text/plain"
78+
79+
5480def test_utcnow ():
5581 assert isinstance (_helpers .utcnow (), datetime .datetime )
5682
You can’t perform that action at this time.
0 commit comments