Skip to content

Commit 0d6c5f0

Browse files
committed
Make mock accept multiple date formats
1 parent ae9b0b8 commit 0d6c5f0

File tree

1 file changed

+46
-34
lines changed

1 file changed

+46
-34
lines changed

src/mock_vws/_mock_web_query_api.py

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,27 @@ def validate_include_target_data(
277277
return unexpected_target_data_message
278278

279279

280+
def _accepted_date_formats() -> Set[str]:
281+
"""
282+
Return all known accepted date formats.
283+
284+
We expect that more formats than this will be accepted.
285+
These are the accepted ones we know of at the time of writing.
286+
"""
287+
known_accepted_formats = {
288+
'%a, %b %d %H:%M:%S %Y',
289+
'%a %b %d %H:%M:%S %Y',
290+
'%a, %d %b %Y %H:%M:%S',
291+
'%a %d %b %Y %H:%M:%S',
292+
}
293+
294+
known_accepted_formats = known_accepted_formats.union(
295+
set(date_format + ' GMT' for date_format in known_accepted_formats)
296+
)
297+
298+
return known_accepted_formats
299+
300+
280301
@wrapt.decorator
281302
def validate_date_format(
282303
wrapped: Callable[..., str],
@@ -298,35 +319,22 @@ def validate_date_format(
298319
An `UNAUTHORIZED` response if the date is in the wrong format.
299320
"""
300321
request, context = args
301-
302-
# We expect that more formats than this will be accepted.
303-
# These are the accepted ones we know of at the time of writing.
304-
known_accepted_formats = {
305-
'%a, %b %d %H:%M:%S %Y',
306-
'%a %b %d %H:%M:%S %Y',
307-
'%a, %d %b %Y %H:%M:%S',
308-
'%a %d %b %Y %H:%M:%S',
309-
}
310-
311-
formats_with_timezones = set(item + ' GMT' for item in known_accepted_formats)
312-
313-
formats = known_accepted_formats.union(formats_with_timezones)
314-
import pdb; pdb.set_trace()
315-
316-
try:
317-
datetime.datetime.strptime(
318-
request.headers['Date'],
319-
'%a, %d %b %Y %H:%M:%S GMT',
320-
)
321-
except ValueError:
322-
context.status_code = codes.UNAUTHORIZED
323-
context.headers['WWW-Authenticate'] = 'VWS'
324-
text = 'Malformed date header.'
325-
content_type = 'text/plain; charset=ISO-8859-1'
326-
context.headers['Content-Type'] = content_type
327-
return text
328-
329-
return wrapped(*args, **kwargs)
322+
date_header = request.headers['Date']
323+
324+
for date_format in _accepted_date_formats():
325+
try:
326+
datetime.datetime.strptime(date_header, date_format)
327+
except ValueError:
328+
pass
329+
else:
330+
return wrapped(*args, **kwargs)
331+
332+
context.status_code = codes.UNAUTHORIZED
333+
context.headers['WWW-Authenticate'] = 'VWS'
334+
text = 'Malformed date header.'
335+
content_type = 'text/plain; charset=ISO-8859-1'
336+
context.headers['Content-Type'] = content_type
337+
return text
330338

331339

332340
@wrapt.decorator
@@ -350,15 +358,19 @@ def validate_date(
350358
A `FORBIDDEN` response if the date is out of range.
351359
"""
352360
request, context = args
361+
date_header = request.headers['Date']
353362

354-
date_from_header = datetime.datetime.strptime(
355-
request.headers['Date'],
356-
'%a, %d %b %Y %H:%M:%S GMT',
357-
)
363+
for date_format in _accepted_date_formats():
364+
try:
365+
date = datetime.datetime.strptime(date_header, date_format)
366+
except ValueError:
367+
pass
368+
else:
369+
break
358370

359371
gmt = pytz.timezone('GMT')
360372
now = datetime.datetime.now(tz=gmt)
361-
date_from_header = date_from_header.replace(tzinfo=gmt)
373+
date_from_header = date.replace(tzinfo=gmt)
362374
time_difference = now - date_from_header
363375

364376
maximum_time_difference = datetime.timedelta(minutes=65)

0 commit comments

Comments
 (0)