)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"060ec918e684974404c54ae30f7b40400a6cf4f0","unresolved":true,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"tests: don\u0027t set req.date in s3api unit tests"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"swob.Request does not have a date attribute so stop setting it in unit"},{"line_number":10,"context_line":"tests.  (webob.Request does have a date property which may explain the"},{"line_number":11,"context_line":"historical context of these calls.)"},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"9bdb8e37_0ef38a15","line":9,"updated":"2026-04-09 15:58:17.000000000","message":"sounds right to me!\n\n```\n\u003e\u003e\u003e r \u003d Request.blank(\u0027/\u0027)\n\u003e\u003e\u003e r.date\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nAttributeError: \u0027Request\u0027 object has no attribute \u0027date\u0027\n```","commit_id":"ea7dd2462e8d5dfd59fb74acce20796059c9da0f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"060ec918e684974404c54ae30f7b40400a6cf4f0","unresolved":true,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"swob.Request does not have a date attribute so stop setting it in unit"},{"line_number":10,"context_line":"tests.  (webob.Request does have a date property which may explain the"},{"line_number":11,"context_line":"historical context of these calls.)"},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Change-Id: I32b09b271e88cffd79fb0c856da638fcade46ab8"},{"line_number":14,"context_line":"Signed-off-by: Alistair Coles \u003calistairncoles@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"c8ea6594_28e29633","line":11,"updated":"2026-04-09 15:58:17.000000000","message":"TIL\n\n```\n\u003e\u003e\u003e import webob\n\u003e\u003e\u003e r \u003d webob.Request.blank(\u0027/\u0027)\n\u003e\u003e\u003e r.date\n\u003e\u003e\u003e \n```","commit_id":"ea7dd2462e8d5dfd59fb74acce20796059c9da0f"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"060ec918e684974404c54ae30f7b40400a6cf4f0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"8a04025a_efa9532e","updated":"2026-04-09 15:58:17.000000000","message":"FWIW there\u0027s another test over in test.unit.common.mw.s3api.test_s3api called \"test_canonical_string_v4\" that set\u0027s `HTTP_DATE` to some old time and then pins:\n\n```\n                    patch(\u0027swift.common.middleware.s3api.utils.time.time\u0027,\n                          return_value\u003dfake_time):\n```\n\nI\u0027m not actually sure that I understand this precedence when defining the `self.signing_timestamp`\n\n```\n                    timestamp \u003d mktime(\n                        self.headers.get(\u0027X-Amz-Date\u0027,\n                                         self.headers.get(\u0027Date\u0027)))\n```\n\n... but we eventually decide:\n\n```\n        delta \u003d abs(int(self.signing_timestamp) - int(S3Timestamp.now()))\n        if delta \u003e self.conf.allowable_clock_skew:\n            raise RequestTimeTooSkewed()\n```\n\nso, yeah I\u0027m pretty sure `environ[\u0027HTTP_DATE\u0027]` is NOT required, and we seem to allow *either* just a `Date` header (which I now realize is all that `HTTP_\u003cheader_name\u003e` ever is/was) OR `HTTP_X_AMZ_DATE`\n\n```\n\u003e\u003e\u003e Request.blank(\u0027/\u0027, headers\u003d{\u0027X-Amz-Date\u0027: \u0027Mon, 09 Sep 2011 23:36:00 GMT\u0027}).environ[\u0027HTTP_X_AMZ_DATE\u0027]\n\u0027Mon, 09 Sep 2011 23:36:00 GMT\u0027\n```\n\nremoving `req.date \u003d ` seems reasonable to me - it does nothing and confuses what is actually necessary (i.e. either Date or X-Amz-Date header must be \"recent\" compared to S3Timestamp.now) AND obscures that we already accomplish that properly in all cases (one way or another) elsewhere.\n\nmaster:\n\n```\n$ ag req.date\ntest/unit/common/middleware/s3api/test_multi_delete.py\n694:        req.date \u003d datetime.now()\n730:        req.date \u003d datetime.now()\n\ntest/unit/common/middleware/s3api/test_obj.py\n711:        req.date \u003d datetime.now()\n742:        req.date \u003d datetime.now()\n767:        req.date \u003d datetime.now()\n791:        req.date \u003d datetime.now()\n840:        req.date \u003d datetime.now()\n868:        req.date \u003d datetime.now()\n894:        req.date \u003d datetime.now()\n951:        req.date \u003d datetime.now()\n1379:        req.date \u003d datetime.now()\n```\n\nthis change:\n\n```\n$ ag req.date\n$ \n```\n\nLGTM!","commit_id":"ea7dd2462e8d5dfd59fb74acce20796059c9da0f"}],"test/unit/common/middleware/s3api/test_multi_delete.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"060ec918e684974404c54ae30f7b40400a6cf4f0","unresolved":true,"context_lines":[{"line_number":685,"context_line":"                                \u0027Date\u0027: self.get_date_header(),"},{"line_number":686,"context_line":"                                \u0027Content-MD5\u0027: content_md5},"},{"line_number":687,"context_line":"                            body\u003dbody)"},{"line_number":688,"context_line":"        req.date \u003d datetime.now()"},{"line_number":689,"context_line":"        req.content_type \u003d \u0027text/plain\u0027"},{"line_number":690,"context_line":""},{"line_number":691,"context_line":"        status, headers, body \u003d self.call_s3api(req)"}],"source_content_type":"text/x-python","patch_set":2,"id":"da6ae089_7bb77513","side":"PARENT","line":688,"updated":"2026-04-09 15:58:17.000000000","message":"so is the learning here that mutation of `HTTP_DATE` is just not required?\n\n```\n\u003e\u003e\u003e r.environ\n{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027, \u0027SCRIPT_NAME\u0027: \u0027\u0027, \u0027PATH_INFO\u0027: \u0027/\u0027, \u0027QUERY_STRING\u0027: \u0027\u0027, \u0027SERVER_NAME\u0027: \u0027localhost\u0027, \u0027SERVER_PORT\u0027: \u002780\u0027, \u0027HTTP_HOST\u0027: \u0027localhost:80\u0027, \u0027SERVER_PROTOCOL\u0027: \u0027HTTP/1.0\u0027, \u0027wsgi.version\u0027: (1, 0), \u0027wsgi.url_scheme\u0027: \u0027http\u0027, \u0027wsgi.input\u0027: \u003c_io.BytesIO object at 0x7f8a8ccb7dd0\u003e, \u0027wsgi.errors\u0027: \u003c_io.TextIOWrapper name\u003d\u0027\u003cstderr\u003e\u0027 mode\u003d\u0027w\u0027 encoding\u003d\u0027utf-8\u0027\u003e, \u0027wsgi.multithread\u0027: False, \u0027wsgi.multiprocess\u0027: False, \u0027wsgi.run_once\u0027: False}\n\u003e\u003e\u003e r.date \u003d datetime.now()\n\u003e\u003e\u003e r.environ\n{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027, \u0027SCRIPT_NAME\u0027: \u0027\u0027, \u0027PATH_INFO\u0027: \u0027/\u0027, \u0027QUERY_STRING\u0027: \u0027\u0027, \u0027SERVER_NAME\u0027: \u0027localhost\u0027, \u0027SERVER_PORT\u0027: \u002780\u0027, \u0027HTTP_HOST\u0027: \u0027localhost:80\u0027, \u0027SERVER_PROTOCOL\u0027: \u0027HTTP/1.0\u0027, \u0027wsgi.version\u0027: (1, 0), \u0027wsgi.url_scheme\u0027: \u0027http\u0027, \u0027wsgi.input\u0027: \u003c_io.BytesIO object at 0x7f8a8ccb7dd0\u003e, \u0027wsgi.errors\u0027: \u003c_io.TextIOWrapper name\u003d\u0027\u003cstderr\u003e\u0027 mode\u003d\u0027w\u0027 encoding\u003d\u0027utf-8\u0027\u003e, \u0027wsgi.multithread\u0027: False, \u0027wsgi.multiprocess\u0027: False, \u0027wsgi.run_once\u0027: False, \u0027HTTP_DATE\u0027: \u0027Thu, 09 Apr 2026 15:37:42 GMT\u0027}\n```\n\n^ this is a webob.Request, I guess on a swob.Request we already know this wasn\u0027t doing any magic setter into the environ... so maybe \"it can\u0027t be required\" by definition because \"it didn\u0027t work\"","commit_id":"977b96b89e13e0aff04b98e060c7ca64607efd14"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"060ec918e684974404c54ae30f7b40400a6cf4f0","unresolved":true,"context_lines":[{"line_number":718,"context_line":"        req \u003d Request.blank(\u0027/bucket?delete\u0027,"},{"line_number":719,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027POST\u0027},"},{"line_number":720,"context_line":"                            headers\u003d{\u0027Authorization\u0027: \u0027AWS %s:hmac\u0027 % account,"},{"line_number":721,"context_line":"                                     \u0027Date\u0027: self.get_date_header(),"},{"line_number":722,"context_line":"                                     \u0027Content-MD5\u0027: content_md5},"},{"line_number":723,"context_line":"                            body\u003dbody)"},{"line_number":724,"context_line":"        req.date \u003d datetime.now()"}],"source_content_type":"text/x-python","patch_set":2,"id":"05d9aa9e_b5b84a4d","side":"PARENT","line":721,"updated":"2026-04-09 15:58:17.000000000","message":"oic, I think we\u0027d already found a way to work around `req.date \u003d` does nothing:\n\n    def get_date_header(self, skew\u003d0):\n        # email.utils.formatdate returns utc timestamp in default\n        return email.utils.formatdate(time.time() + skew)\n\n```\n\u003e\u003e\u003e Request.blank(\u0027/\u0027, headers\u003d{\u0027Date\u0027: \u0027Mon, 09 Sep 2011 23:36:00 GMT\u0027}).environ\n{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027, \u0027SCRIPT_NAME\u0027: \u0027\u0027, \u0027QUERY_STRING\u0027: \u0027\u0027, \u0027PATH_INFO\u0027: \u0027/\u0027, \u0027SERVER_NAME\u0027: \u0027localhost\u0027, \u0027SERVER_PORT\u0027: \u002780\u0027, \u0027HTTP_HOST\u0027: \u0027localhost:80\u0027, \u0027SERVER_PROTOCOL\u0027: \u0027HTTP/1.0\u0027, \u0027wsgi.version\u0027: (1, 0), \u0027wsgi.url_scheme\u0027: \u0027http\u0027, \u0027wsgi.errors\u0027: \u003c_io.StringIO object at 0x792a379ce380\u003e, \u0027wsgi.multithread\u0027: False, \u0027wsgi.multiprocess\u0027: False, \u0027wsgi.input\u0027: \u003cswift.common.swob.WsgiBytesIO object at 0x792a39283b00\u003e, \u0027HTTP_DATE\u0027: \u0027Mon, 09 Sep 2011 23:36:00 GMT\u0027}\n```","commit_id":"977b96b89e13e0aff04b98e060c7ca64607efd14"}],"test/unit/common/middleware/s3api/test_obj.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4dd9e6ef173cf6262ee72df5127985a889c2142e","unresolved":true,"context_lines":[{"line_number":703,"context_line":"            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":704,"context_line":"            headers\u003d{\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,"},{"line_number":705,"context_line":"                     \u0027x-amz-storage-class\u0027: \u0027STANDARD\u0027,"},{"line_number":706,"context_line":"                     \u0027Content-MD5\u0027: content_md5},"},{"line_number":707,"context_line":"            body\u003dself.object_body)"},{"line_number":708,"context_line":"        req.content_type \u003d \u0027text/plain\u0027"},{"line_number":709,"context_line":"        status, headers, body \u003d self.call_s3api(req)"}],"source_content_type":"text/x-python","patch_set":1,"id":"d08f8d6a_fc7d4667","line":706,"updated":"2026-01-05 20:20:45.000000000","message":"argh, I didn\u0027t mean to commit this change","commit_id":"673b9fc2871f08d721ff1d18d62f92f8b8f6446f"}]}
