S3: LastModified-date should always be in English (#7254)
This commit is contained in:
		
							parent
							
								
									a04ef58386
								
							
						
					
					
						commit
						404c1ea9e3
					
				| @ -170,10 +170,36 @@ def iso_8601_datetime_without_milliseconds_s3( | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| RFC1123 = "%a, %d %b %Y %H:%M:%S GMT" | RFC1123 = "%a, %d %b %Y %H:%M:%S GMT" | ||||||
|  | EN_WEEKDAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] | ||||||
|  | EN_MONTHS = [ | ||||||
|  |     "Jan", | ||||||
|  |     "Feb", | ||||||
|  |     "Mar", | ||||||
|  |     "Apr", | ||||||
|  |     "May", | ||||||
|  |     "Jun", | ||||||
|  |     "Jul", | ||||||
|  |     "Aug", | ||||||
|  |     "Sep", | ||||||
|  |     "Oct", | ||||||
|  |     "Nov", | ||||||
|  |     "Dec", | ||||||
|  | ] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def rfc_1123_datetime(src: datetime.datetime) -> str: | def rfc_1123_datetime(src: datetime.datetime) -> str: | ||||||
|     return src.strftime(RFC1123) |     """ | ||||||
|  |     Returns the datetime in the RFC-1123 format | ||||||
|  |     Names of weekdays/months are in English | ||||||
|  |     """ | ||||||
|  |     # strftime uses the current locale to translate values | ||||||
|  |     # So weekday/month values may not be in English | ||||||
|  |     # For our usecase, we need these values to always be in English, otherwise botocore is unable to parse it | ||||||
|  |     # Having a hardcoded list ensures this always works, even if the user does not have an English locale installed | ||||||
|  |     eng_weekday = EN_WEEKDAYS[src.isoweekday() - 1] | ||||||
|  |     eng_month = EN_MONTHS[src.month - 1] | ||||||
|  |     non_locallized_rfc1123 = RFC1123.replace("%a", "{}").replace("%b", "{}") | ||||||
|  |     return src.strftime(non_locallized_rfc1123).format(eng_weekday, eng_month) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def str_to_rfc_1123_datetime(value: str) -> datetime.datetime: | def str_to_rfc_1123_datetime(value: str) -> datetime.datetime: | ||||||
|  | |||||||
| @ -1,3 +1,5 @@ | |||||||
|  | import datetime | ||||||
|  | 
 | ||||||
| import pytest | import pytest | ||||||
| from freezegun import freeze_time | from freezegun import freeze_time | ||||||
| 
 | 
 | ||||||
| @ -5,6 +7,8 @@ from moto.core.utils import ( | |||||||
|     camelcase_to_pascal, |     camelcase_to_pascal, | ||||||
|     camelcase_to_underscores, |     camelcase_to_underscores, | ||||||
|     pascal_to_camelcase, |     pascal_to_camelcase, | ||||||
|  |     rfc_1123_datetime, | ||||||
|  |     str_to_rfc_1123_datetime, | ||||||
|     underscores_to_camelcase, |     underscores_to_camelcase, | ||||||
|     unix_time, |     unix_time, | ||||||
| ) | ) | ||||||
| @ -50,3 +54,10 @@ def test_camelcase_to_pascal(_input: str, expected: str) -> None: | |||||||
| @freeze_time("2015-01-01 12:00:00") | @freeze_time("2015-01-01 12:00:00") | ||||||
| def test_unix_time() -> None:  # type: ignore[misc] | def test_unix_time() -> None:  # type: ignore[misc] | ||||||
|     assert unix_time() == 1420113600.0 |     assert unix_time() == 1420113600.0 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_rfc1123_dates() -> None: | ||||||
|  |     with freeze_time("2012-03-04 05:00:05"): | ||||||
|  |         x = rfc_1123_datetime(datetime.datetime.now()) | ||||||
|  |         assert x == "Sun, 04 Mar 2012 05:00:05 GMT" | ||||||
|  |         assert str_to_rfc_1123_datetime(x) == datetime.datetime.now() | ||||||
|  | |||||||
							
								
								
									
										30
									
								
								tests/test_s3/test_s3_locales.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								tests/test_s3/test_s3_locales.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | from datetime import datetime | ||||||
|  | from unittest import SkipTest | ||||||
|  | 
 | ||||||
|  | import boto3 | ||||||
|  | from freezegun import freeze_time | ||||||
|  | 
 | ||||||
|  | from moto import mock_s3, settings | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @mock_s3 | ||||||
|  | def test_rfc_returns_valid_date_for_every_possible_weekday_and_month(): | ||||||
|  |     if not settings.TEST_DECORATOR_MODE: | ||||||
|  |         raise SkipTest("Freezing time only possible in DecoratorMode") | ||||||
|  |     client = boto3.client("s3", region_name="us-east-1") | ||||||
|  |     client.create_bucket(Bucket="bucket_") | ||||||
|  |     for weekday in range(1, 8): | ||||||
|  |         with freeze_time(f"2023-02-{weekday} 12:00:00"): | ||||||
|  |             client.put_object(Bucket="bucket_", Key="test.txt", Body=b"test") | ||||||
|  |             obj = client.get_object(Bucket="bucket_", Key="test.txt") | ||||||
|  |             assert obj["LastModified"].replace(tzinfo=None) == datetime.now() | ||||||
|  |             # If we get here, the LastModified date will have been successfully parsed | ||||||
|  |             # Regardless of which weekday it is | ||||||
|  | 
 | ||||||
|  |     for month in range(1, 13): | ||||||
|  |         with freeze_time(f"2023-{month}-02 12:00:00"): | ||||||
|  |             client.put_object(Bucket="bucket_", Key="test.txt", Body=b"test") | ||||||
|  |             obj = client.get_object(Bucket="bucket_", Key="test.txt") | ||||||
|  |             assert obj["LastModified"].replace(tzinfo=None) == datetime.now() | ||||||
|  |             # If we get here, the LastModified date will have been successfully parsed | ||||||
|  |             # Regardless of which month it is | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user