)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"be39c58244f60d4cfcc3e329886ee4e73493c0b0","unresolved":true,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":"Limitations:"},{"line_number":20,"context_line":"- Only one CORS rule per bucket (AWS supports multiple ones)"},{"line_number":21,"context_line":"- AllowedMethod must be \"*\""},{"line_number":22,"context_line":"- AllowedHeader must be \"*\" or omitted"},{"line_number":23,"context_line":"- Complex wildcard patterns in AllowedOrigin not supported"},{"line_number":24,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"ae98c77a_d8f5a9e8","line":21,"updated":"2026-03-12 18:05:56.000000000","message":"We should update the commit message here.","commit_id":"807d6a4d6f2ce358c94f4bf65cfb0d6dc1dd92ec"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"8d1714e4ba2946ef90913626153b150b2f7cedab","unresolved":false,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":"Limitations:"},{"line_number":20,"context_line":"- Only one CORS rule per bucket (AWS supports multiple ones)"},{"line_number":21,"context_line":"- AllowedMethod must be \"*\""},{"line_number":22,"context_line":"- AllowedHeader must be \"*\" or omitted"},{"line_number":23,"context_line":"- Complex wildcard patterns in AllowedOrigin not supported"},{"line_number":24,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"48756b24_4b28b579","line":21,"in_reply_to":"ae98c77a_d8f5a9e8","updated":"2026-03-13 11:34:27.000000000","message":"Done","commit_id":"807d6a4d6f2ce358c94f4bf65cfb0d6dc1dd92ec"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"be39c58244f60d4cfcc3e329886ee4e73493c0b0","unresolved":true,"context_lines":[{"line_number":20,"context_line":"- Only one CORS rule per bucket (AWS supports multiple ones)"},{"line_number":21,"context_line":"- AllowedMethod must be \"*\""},{"line_number":22,"context_line":"- AllowedHeader must be \"*\" or omitted"},{"line_number":23,"context_line":"- Complex wildcard patterns in AllowedOrigin not supported"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"These limitations align with Swift\u0027s container-level CORS"},{"line_number":26,"context_line":"implementation."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"b644d5bd_84cb5b0e","line":23,"updated":"2026-03-12 18:05:56.000000000","message":"We\u0027ll still write them down, right? So if we enhance Swift to support them, they\u0027ll start just working.","commit_id":"807d6a4d6f2ce358c94f4bf65cfb0d6dc1dd92ec"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"8d1714e4ba2946ef90913626153b150b2f7cedab","unresolved":true,"context_lines":[{"line_number":20,"context_line":"- Only one CORS rule per bucket (AWS supports multiple ones)"},{"line_number":21,"context_line":"- AllowedMethod must be \"*\""},{"line_number":22,"context_line":"- AllowedHeader must be \"*\" or omitted"},{"line_number":23,"context_line":"- Complex wildcard patterns in AllowedOrigin not supported"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"These limitations align with Swift\u0027s container-level CORS"},{"line_number":26,"context_line":"implementation."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"8575905f_db7baa42","line":23,"in_reply_to":"b644d5bd_84cb5b0e","updated":"2026-03-13 11:34:27.000000000","message":"No, we explicitly return an error to not break the expectancy of the user. See cors.py:155","commit_id":"807d6a4d6f2ce358c94f4bf65cfb0d6dc1dd92ec"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"be39c58244f60d4cfcc3e329886ee4e73493c0b0","unresolved":true,"context_lines":[{"line_number":25,"context_line":"These limitations align with Swift\u0027s container-level CORS"},{"line_number":26,"context_line":"implementation."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"Change-Id: I7411f219890b6571fd8c71ed04bb9ee9ab031d79"},{"line_number":29,"context_line":"Signed-off-by: Bastien Wermeille \u003cbastien.wermeille@proton.me\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"ecd3bf6b_abe82b31","line":28,"updated":"2026-03-12 18:05:56.000000000","message":"If we add a\n\n\u003e Closes-Bug: #1905104\n\nit\u0027ll not only tie this back to what we\u0027re fixing, but (should) also automatically close the bug when this merges.","commit_id":"807d6a4d6f2ce358c94f4bf65cfb0d6dc1dd92ec"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"8d1714e4ba2946ef90913626153b150b2f7cedab","unresolved":false,"context_lines":[{"line_number":25,"context_line":"These limitations align with Swift\u0027s container-level CORS"},{"line_number":26,"context_line":"implementation."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"Change-Id: I7411f219890b6571fd8c71ed04bb9ee9ab031d79"},{"line_number":29,"context_line":"Signed-off-by: Bastien Wermeille \u003cbastien.wermeille@proton.me\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"6bf5821e_f7348020","line":28,"in_reply_to":"ecd3bf6b_abe82b31","updated":"2026-03-13 11:34:27.000000000","message":"Acknowledged","commit_id":"807d6a4d6f2ce358c94f4bf65cfb0d6dc1dd92ec"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"e77e5d2285c35ae3f522d9c929af0debc9bf5ef1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"9daf4555_20a488ea","updated":"2026-02-17 23:16:55.000000000","message":"Hello,\nI am not familiar at all with gerrit, I hope this will work...\nHere is a proposal as a first step cors support in the s3 api. The idea was to have the same level of cors support for the s3 api as for the swift api.\n\nHappy to work on this and try to move forward if you think this is a good idea.\n\nThis review target those issues:\n- https://bugs.launchpad.net/swift/+bug/1905104\n- https://bugs.launchpad.net/swift/+bug/2077629","commit_id":"a77d97aa5dca9c8b1c3b5dc29d9fe6ac78185989"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"c3ee280970bdb1c9bc9742c0a1193b4bfd5b3334","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":8,"id":"94610406_8c28c4cb","updated":"2026-02-23 16:52:00.000000000","message":"Hello,\nI am not familiar at all with gerrit, I hope this will work...\nHere is a proposal as a first step for cors support in the s3 api. The idea was to have the same level of cors support for the s3 api, as for the swift api.\n\nHappy to work on this and try to move forward if you think this is a good idea.\n\nThis review target those issues:\n\n- https://bugs.launchpad.net/swift/+bug/1905104\n- https://bugs.launchpad.net/swift/+bug/2077629\n\nLet me know what you think of this.","commit_id":"14a6a26a7dea77559f4ee16379c70d07d0c35dd8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"14d8a5ba7f596141808aa679a44da9e7393c5d9a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"12f5c829_d0a1ab9d","updated":"2026-03-10 18:21:55.000000000","message":"Great first contribution, especially if you\u0027re not familiar with Gerrit! I\u0027m worried about us not looking at the responses at all during PUT/DELETE, though. I might also try to write some cross-compat tests under `test/s3api/` over the next couple days.","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bc4d04f58b0187f327faaa4ba250ca9e08daf9fd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"44eb4153_ddc35179","in_reply_to":"12f5c829_d0a1ab9d","updated":"2026-03-11 21:15:09.000000000","message":"\u003e I might also try to write some cross-compat tests under test/s3api/ over the next couple days.\n\nhttps://review.opendev.org/c/openstack/swift/+/980160 (though I suppose it\u0027d be *even better* if it also made some object requests with `Origin` headers...)","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"e6699e7169e97d54f1018bd18eb8633b370fc41d","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":9,"id":"c6734375_0e1fc9ad","in_reply_to":"44eb4153_ddc35179","updated":"2026-03-12 12:51:29.000000000","message":"How can I include or run those tests in gerrit ?","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"be39c58244f60d4cfcc3e329886ee4e73493c0b0","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":9,"id":"e9208787_55b73ce1","in_reply_to":"c6734375_0e1fc9ad","updated":"2026-03-12 18:05:56.000000000","message":"You should feel free to add them directly to your patch. Or we could leave them as a follow-up; either way.\n\nThey\u0027ll get run in CI as part of the `swift-tox-func-s3api-compat-tests-tempauth` job (against Swift, not AWS -- AWS testing is currently always manual).","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2c1e0fdd6090e20b9589e2c9672117ce3b3782dc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"410c0d86_80585a5a","updated":"2026-03-17 19:32:25.000000000","message":"Definitely showing promise -- we should make sure it works when `s3_acl` is enabled, though.\n\nI\u0027m also still not so sure about the `s3api.py` changes. FWIW, all the cross-compat tests I\u0027ve been working on pass just fine without any of those changes (though they *do* require that I set `cors_preflight_allow_origin \u003d *` in my proxy-server.conf).","commit_id":"f1544e87c894c608a06f737b195c6348a79b91a1"}],"swift/common/middleware/s3api/controllers/cors.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"14d8a5ba7f596141808aa679a44da9e7393c5d9a","unresolved":true,"context_lines":[{"line_number":161,"context_line":"        # Validate and collect AllowedMethods"},{"line_number":162,"context_line":"        # Swift doesn\u0027t support method-based CORS restrictions,"},{"line_number":163,"context_line":"        # only \"*\" is valid"},{"line_number":164,"context_line":"        for method_elem in rule.findall(\"./AllowedMethod\"):"},{"line_number":165,"context_line":"            if method_elem.text:"},{"line_number":166,"context_line":"                method \u003d method_elem.text.strip()"},{"line_number":167,"context_line":"                if method !\u003d \"*\":"}],"source_content_type":"text/x-python","patch_set":9,"id":"ef7571d4_c8e1a1a7","line":164,"updated":"2026-03-10 18:21:55.000000000","message":"Might be worth allowing an explicit list of GET, HEAD, PUT, POST, and DELETE -- then we\u0027ll be able to round-trip, or copy an existing configuration to a new bucket with something like\n```\naws s3api put-bucket-cors --bucket bucket2 --cors-configuration \"$(\n    aws s3api get-bucket-cors --bucket bucket1)\"\n```","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"be39c58244f60d4cfcc3e329886ee4e73493c0b0","unresolved":false,"context_lines":[{"line_number":161,"context_line":"        # Validate and collect AllowedMethods"},{"line_number":162,"context_line":"        # Swift doesn\u0027t support method-based CORS restrictions,"},{"line_number":163,"context_line":"        # only \"*\" is valid"},{"line_number":164,"context_line":"        for method_elem in rule.findall(\"./AllowedMethod\"):"},{"line_number":165,"context_line":"            if method_elem.text:"},{"line_number":166,"context_line":"                method \u003d method_elem.text.strip()"},{"line_number":167,"context_line":"                if method !\u003d \"*\":"}],"source_content_type":"text/x-python","patch_set":9,"id":"ddbdf994_98df786e","line":164,"in_reply_to":"4d04a4c6_cb177358","updated":"2026-03-12 18:05:56.000000000","message":"Done","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"e6699e7169e97d54f1018bd18eb8633b370fc41d","unresolved":true,"context_lines":[{"line_number":161,"context_line":"        # Validate and collect AllowedMethods"},{"line_number":162,"context_line":"        # Swift doesn\u0027t support method-based CORS restrictions,"},{"line_number":163,"context_line":"        # only \"*\" is valid"},{"line_number":164,"context_line":"        for method_elem in rule.findall(\"./AllowedMethod\"):"},{"line_number":165,"context_line":"            if method_elem.text:"},{"line_number":166,"context_line":"                method \u003d method_elem.text.strip()"},{"line_number":167,"context_line":"                if method !\u003d \"*\":"}],"source_content_type":"text/x-python","patch_set":9,"id":"4d04a4c6_cb177358","line":164,"in_reply_to":"ef7571d4_c8e1a1a7","updated":"2026-03-12 12:51:29.000000000","message":"Yes, good idea, so as `*` are not allowed, I changed to enforce having the full list.","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bc4d04f58b0187f327faaa4ba250ca9e08daf9fd","unresolved":true,"context_lines":[{"line_number":164,"context_line":"        for method_elem in rule.findall(\"./AllowedMethod\"):"},{"line_number":165,"context_line":"            if method_elem.text:"},{"line_number":166,"context_line":"                method \u003d method_elem.text.strip()"},{"line_number":167,"context_line":"                if method !\u003d \"*\":"},{"line_number":168,"context_line":"                    raise S3NotImplemented("},{"line_number":169,"context_line":"                        \"Method-specific CORS rules are not supported. \""},{"line_number":170,"context_line":"                        \"Use AllowedMethod\u003d\u0027*\u0027 to allow all methods.\""}],"source_content_type":"text/x-python","patch_set":9,"id":"41e487cc_ad25dd0e","line":167,"updated":"2026-03-11 21:15:09.000000000","message":"Note that AWS doesn\u0027t like the wildcard here; trying, I get errors like\n```\nbotocore.errorfactory.InvalidRequest: An error occurred (InvalidRequest) when\ncalling the PutBucketCors operation: Found unsupported HTTP method in CORS\nconfig. Unsupported method is *\n```\nI can\u0027t decide whether I like the wildcard or not.","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"e6699e7169e97d54f1018bd18eb8633b370fc41d","unresolved":true,"context_lines":[{"line_number":164,"context_line":"        for method_elem in rule.findall(\"./AllowedMethod\"):"},{"line_number":165,"context_line":"            if method_elem.text:"},{"line_number":166,"context_line":"                method \u003d method_elem.text.strip()"},{"line_number":167,"context_line":"                if method !\u003d \"*\":"},{"line_number":168,"context_line":"                    raise S3NotImplemented("},{"line_number":169,"context_line":"                        \"Method-specific CORS rules are not supported. \""},{"line_number":170,"context_line":"                        \"Use AllowedMethod\u003d\u0027*\u0027 to allow all methods.\""}],"source_content_type":"text/x-python","patch_set":9,"id":"64a49bbb_1e957838","line":167,"in_reply_to":"41e487cc_ad25dd0e","updated":"2026-03-12 12:51:29.000000000","message":"I\u0027ll change it to enforce the full list, it will be clearer and avoid any confusion with the way AWS handles cors.","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"be39c58244f60d4cfcc3e329886ee4e73493c0b0","unresolved":false,"context_lines":[{"line_number":164,"context_line":"        for method_elem in rule.findall(\"./AllowedMethod\"):"},{"line_number":165,"context_line":"            if method_elem.text:"},{"line_number":166,"context_line":"                method \u003d method_elem.text.strip()"},{"line_number":167,"context_line":"                if method !\u003d \"*\":"},{"line_number":168,"context_line":"                    raise S3NotImplemented("},{"line_number":169,"context_line":"                        \"Method-specific CORS rules are not supported. \""},{"line_number":170,"context_line":"                        \"Use AllowedMethod\u003d\u0027*\u0027 to allow all methods.\""}],"source_content_type":"text/x-python","patch_set":9,"id":"b1467650_bb7c2d10","line":167,"in_reply_to":"64a49bbb_1e957838","updated":"2026-03-12 18:05:56.000000000","message":"Done","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"14d8a5ba7f596141808aa679a44da9e7393c5d9a","unresolved":true,"context_lines":[{"line_number":189,"context_line":"                all_expose_headers.append(header_elem.text.strip())"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"        # Get MaxAgeSeconds"},{"line_number":192,"context_line":"        max_age_elem \u003d rule.find(\"./MaxAgeSeconds\")"},{"line_number":193,"context_line":"        if max_age_elem is not None and max_age_elem.text:"},{"line_number":194,"context_line":"            try:"},{"line_number":195,"context_line":"                max_age \u003d int(max_age_elem.text)"}],"source_content_type":"text/x-python","patch_set":9,"id":"f9e988a7_3ae7b96c","line":192,"updated":"2026-03-10 18:21:55.000000000","message":"Note to self: I should see what AWS does when there are multiple...\n\nBut we should get enforcement of zero-or-one with the `\u003coptional\u003e` 👍","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"b8b31aab266117d446d7ce17ecb36519e52de499","unresolved":false,"context_lines":[{"line_number":189,"context_line":"                all_expose_headers.append(header_elem.text.strip())"},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"        # Get MaxAgeSeconds"},{"line_number":192,"context_line":"        max_age_elem \u003d rule.find(\"./MaxAgeSeconds\")"},{"line_number":193,"context_line":"        if max_age_elem is not None and max_age_elem.text:"},{"line_number":194,"context_line":"            try:"},{"line_number":195,"context_line":"                max_age \u003d int(max_age_elem.text)"}],"source_content_type":"text/x-python","patch_set":9,"id":"2946e434_0c5df7f4","line":192,"in_reply_to":"f9e988a7_3ae7b96c","updated":"2026-03-14 10:49:58.000000000","message":"Acknowledged","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"14d8a5ba7f596141808aa679a44da9e7393c5d9a","unresolved":true,"context_lines":[{"line_number":220,"context_line":""},{"line_number":221,"context_line":"        # Update container metadata"},{"line_number":222,"context_line":"        req.headers.update(headers)"},{"line_number":223,"context_line":"        req.get_response(self.app, \"POST\")"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"        return HTTPOk()"},{"line_number":226,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"1d03b6e4_af2a1492","line":223,"updated":"2026-03-10 18:21:55.000000000","message":"What if this request fails? How is the failure communicated back to the client so they can retry?","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"be39c58244f60d4cfcc3e329886ee4e73493c0b0","unresolved":false,"context_lines":[{"line_number":220,"context_line":""},{"line_number":221,"context_line":"        # Update container metadata"},{"line_number":222,"context_line":"        req.headers.update(headers)"},{"line_number":223,"context_line":"        req.get_response(self.app, \"POST\")"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"        return HTTPOk()"},{"line_number":226,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"1001ac63_8a7806fd","line":223,"in_reply_to":"048ee080_dda14cd6","updated":"2026-03-12 18:05:56.000000000","message":"Ah, right! Sorry, forgot about how that works; thanks for the reminder!","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"e6699e7169e97d54f1018bd18eb8633b370fc41d","unresolved":true,"context_lines":[{"line_number":220,"context_line":""},{"line_number":221,"context_line":"        # Update container metadata"},{"line_number":222,"context_line":"        req.headers.update(headers)"},{"line_number":223,"context_line":"        req.get_response(self.app, \"POST\")"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"        return HTTPOk()"},{"line_number":226,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"048ee080_dda14cd6","line":223,"in_reply_to":"1d03b6e4_af2a1492","updated":"2026-03-12 12:51:29.000000000","message":"So if I have traced it correctly, `req.get_response()` delegates to `_get_response()` in `s3request.py:2165`. That method never silently returns an error response. Looking at `s3request.py`:2208-2260:\n\nIt only returns normally if the backend Swift status is in `_swift_success_codes`. So I guess this should be fine as `_get_response` handle any exception and invalid response code.","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"14d8a5ba7f596141808aa679a44da9e7393c5d9a","unresolved":true,"context_lines":[{"line_number":236,"context_line":"        req.headers[\"X-Container-Meta-Access-Control-Expose-Headers\"] \u003d \"\""},{"line_number":237,"context_line":"        req.headers[\"X-Container-Meta-Access-Control-Max-Age\"] \u003d \"\""},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"        req.get_response(self.app, \"POST\")"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        # DELETE Bucket cors returns 204 No Content"},{"line_number":242,"context_line":"        return HTTPOk(status\u003d204)"}],"source_content_type":"text/x-python","patch_set":9,"id":"7ae74573_716bf9f7","line":239,"updated":"2026-03-10 18:21:55.000000000","message":"Ditto here.","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"e6699e7169e97d54f1018bd18eb8633b370fc41d","unresolved":true,"context_lines":[{"line_number":236,"context_line":"        req.headers[\"X-Container-Meta-Access-Control-Expose-Headers\"] \u003d \"\""},{"line_number":237,"context_line":"        req.headers[\"X-Container-Meta-Access-Control-Max-Age\"] \u003d \"\""},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"        req.get_response(self.app, \"POST\")"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        # DELETE Bucket cors returns 204 No Content"},{"line_number":242,"context_line":"        return HTTPOk(status\u003d204)"}],"source_content_type":"text/x-python","patch_set":9,"id":"8e6d41e7_a783d678","line":239,"in_reply_to":"7ae74573_716bf9f7","updated":"2026-03-12 12:51:29.000000000","message":"Same as above","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"be39c58244f60d4cfcc3e329886ee4e73493c0b0","unresolved":false,"context_lines":[{"line_number":236,"context_line":"        req.headers[\"X-Container-Meta-Access-Control-Expose-Headers\"] \u003d \"\""},{"line_number":237,"context_line":"        req.headers[\"X-Container-Meta-Access-Control-Max-Age\"] \u003d \"\""},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"        req.get_response(self.app, \"POST\")"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        # DELETE Bucket cors returns 204 No Content"},{"line_number":242,"context_line":"        return HTTPOk(status\u003d204)"}],"source_content_type":"text/x-python","patch_set":9,"id":"77bbe438_90d28aad","line":239,"in_reply_to":"8e6d41e7_a783d678","updated":"2026-03-12 18:05:56.000000000","message":"Acknowledged","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"be39c58244f60d4cfcc3e329886ee4e73493c0b0","unresolved":true,"context_lines":[{"line_number":171,"context_line":"            raise MalformedXML("},{"line_number":172,"context_line":"                msg\u003d\"AllowedMethod %s is not supported\""},{"line_number":173,"context_line":"                    % \", \".join(sorted(extra))"},{"line_number":174,"context_line":"            )"},{"line_number":175,"context_line":"        missing \u003d required_methods - provided_methods"},{"line_number":176,"context_line":"        if missing:"},{"line_number":177,"context_line":"            raise MalformedXML("}],"source_content_type":"text/x-python","patch_set":11,"id":"f5a5bdae_66fb320a","line":174,"updated":"2026-03-12 18:05:56.000000000","message":"From testing against AWS, I think we want this to be more like\n```\nraise InvalidRequest(\n    \"Found unsupported HTTP method in CORS config. \"\n    \"Unsupported method is \" + \", \".join(sorted(extra))\n)\n```\nor something. (I haven\u0027t yet tested sending *multiple* invalid methods...)","commit_id":"807d6a4d6f2ce358c94f4bf65cfb0d6dc1dd92ec"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"8d1714e4ba2946ef90913626153b150b2f7cedab","unresolved":false,"context_lines":[{"line_number":171,"context_line":"            raise MalformedXML("},{"line_number":172,"context_line":"                msg\u003d\"AllowedMethod %s is not supported\""},{"line_number":173,"context_line":"                    % \", \".join(sorted(extra))"},{"line_number":174,"context_line":"            )"},{"line_number":175,"context_line":"        missing \u003d required_methods - provided_methods"},{"line_number":176,"context_line":"        if missing:"},{"line_number":177,"context_line":"            raise MalformedXML("}],"source_content_type":"text/x-python","patch_set":11,"id":"9700c1c1_bb2fd704","line":174,"in_reply_to":"f5a5bdae_66fb320a","updated":"2026-03-13 11:34:27.000000000","message":"Done","commit_id":"807d6a4d6f2ce358c94f4bf65cfb0d6dc1dd92ec"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2c1e0fdd6090e20b9589e2c9672117ce3b3782dc","unresolved":true,"context_lines":[{"line_number":181,"context_line":""},{"line_number":182,"context_line":"        # Validate and collect AllowedHeaders"},{"line_number":183,"context_line":"        # Swift doesn\u0027t support header-based CORS restrictions,"},{"line_number":184,"context_line":"        # only \"*\" is valid"},{"line_number":185,"context_line":"        for header_elem in rule.findall(\"./AllowedHeader\"):"},{"line_number":186,"context_line":"            if header_elem.text:"},{"line_number":187,"context_line":"                header \u003d header_elem.text.strip()"}],"source_content_type":"text/x-python","patch_set":15,"id":"9bb08f6c_c6e6a860","line":184,"updated":"2026-03-17 19:32:25.000000000","message":"Should we require that clients provide this, similar to how we require that they list all the required methods? And respond with it on GET?","commit_id":"f1544e87c894c608a06f737b195c6348a79b91a1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2c1e0fdd6090e20b9589e2c9672117ce3b3782dc","unresolved":true,"context_lines":[{"line_number":245,"context_line":"        req.headers[\"X-Container-Meta-Access-Control-Expose-Headers\"] \u003d \"\""},{"line_number":246,"context_line":"        req.headers[\"X-Container-Meta-Access-Control-Max-Age\"] \u003d \"\""},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"        req.get_response(self.app, \"POST\")"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":"        # DELETE Bucket cors returns 204 No Content"},{"line_number":251,"context_line":"        return HTTPOk(status\u003d204)"}],"source_content_type":"text/x-python","patch_set":15,"id":"521b41ed_3f32947d","line":248,"updated":"2026-03-17 19:32:25.000000000","message":"This bombs out if `s3_acl` is enabled:\n```\nTraceback (most recent call last):\n  File \"/vagrant/swift/swift/common/middleware/s3api/s3api.py\", line 458, in __call__\n    resp \u003d self.handle_request(req)\n           ^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/vagrant/swift/swift/common/middleware/s3api/s3api.py\", line 502, in handle_request\n    res \u003d handler(req)\n          ^^^^^^^^^^^^\n  File \"/vagrant/swift/swift/common/middleware/s3api/controllers/base.py\", line 40, in wrapped\n    return func(self, req)\n           ^^^^^^^^^^^^^^^\n  File \"/vagrant/swift/swift/common/middleware/s3api/controllers/cors.py\", line 251, in DELETE\n    req.get_response(self.app, \"POST\")\n  File \"/vagrant/swift/swift/common/middleware/s3api/s3request.py\", line 2448, in get_response\n    resp \u003d self.acl_handler.handle_acl(\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/vagrant/swift/swift/common/middleware/s3api/acl_handlers.py\", line 96, in handle_acl\n    return ah._handle_acl(app, method)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/vagrant/swift/swift/common/middleware/s3api/acl_handlers.py\", line 129, in _handle_acl\n    raise Exception(\u0027No permission to be checked exists\u0027)\nException: No permission to be checked exists\n```\nShould just need something like\n```\ndiff --git a/swift/common/middleware/s3api/acl_handlers.py b/swift/common/middleware/s3api/acl_handlers.py\nindex f5b8c587b..71624a48f 100644\n--- a/swift/common/middleware/s3api/acl_handlers.py\n+++ b/swift/common/middleware/s3api/acl_handlers.py\n@@ -477,9 +477,11 @@ ACL_MAP \u003d {\n     # Initiate Multipart Upload\n     (\u0027POST\u0027, \u0027HEAD\u0027, \u0027container\u0027):\n     {\u0027Permission\u0027: \u0027WRITE\u0027},\n-    # Versioning\n+    # Versioning, CORS\n     (\u0027PUT\u0027, \u0027POST\u0027, \u0027container\u0027):\n     {\u0027Permission\u0027: \u0027WRITE\u0027},\n+    (\u0027DELETE\u0027, \u0027POST\u0027, \u0027container\u0027):\n+    {\u0027Permission\u0027: \u0027WRITE\u0027},\n     (\u0027DELETE\u0027, \u0027GET\u0027, \u0027container\u0027):\n     {\u0027Permission\u0027: \u0027WRITE\u0027},\n }\n```\napplied.","commit_id":"f1544e87c894c608a06f737b195c6348a79b91a1"}],"swift/common/middleware/s3api/s3api.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"14d8a5ba7f596141808aa679a44da9e7393c5d9a","unresolved":true,"context_lines":[{"line_number":447,"context_line":"                from swift.proxy.controllers.base import \\"},{"line_number":448,"context_line":"                    get_container_info"},{"line_number":449,"context_line":""},{"line_number":450,"context_line":"                container_info \u003d get_container_info("},{"line_number":451,"context_line":"                    env, self.app, swift_source\u003d\u0027S3\u0027)"},{"line_number":452,"context_line":"                cors_info \u003d container_info.get(\u0027cors\u0027)"},{"line_number":453,"context_line":"                if not cors_info:"}],"source_content_type":"text/x-python","patch_set":9,"id":"3485e0ac_68b44395","line":450,"updated":"2026-03-10 18:21:55.000000000","message":"There\u0027s no Swift version to the path, so shouldn\u0027t always get a pretty empty response? https://github.com/openstack/swift/blob/2.37.0/swift/proxy/controllers/base.py#L451-L454\n\nOr... we\u0027ve got somebody using bucket-in-host addressing, with an object whose key starts with `v1.0/`, and then we\u0027re getting back data for the wrong container, potentially even the wrong account...\n\n*Maybe* we could get some useful response here if the client\u0027s using presigned URLs *and* we switch this to `get_container_info(env, self, swift_source\u003d\u0027S3\u0027)` -- but preflights for `Authorization`-signed requests are necessarily pretty anonymous. We can\u0027t know what account they\u0027re trying to reference.","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"e6699e7169e97d54f1018bd18eb8633b370fc41d","unresolved":true,"context_lines":[{"line_number":447,"context_line":"                from swift.proxy.controllers.base import \\"},{"line_number":448,"context_line":"                    get_container_info"},{"line_number":449,"context_line":""},{"line_number":450,"context_line":"                container_info \u003d get_container_info("},{"line_number":451,"context_line":"                    env, self.app, swift_source\u003d\u0027S3\u0027)"},{"line_number":452,"context_line":"                cors_info \u003d container_info.get(\u0027cors\u0027)"},{"line_number":453,"context_line":"                if not cors_info:"}],"source_content_type":"text/x-python","patch_set":9,"id":"744d8dae_58594550","line":450,"in_reply_to":"3485e0ac_68b44395","updated":"2026-03-12 12:51:29.000000000","message":"Yes, you\u0027re right. I\u0027ll dig on this issue.","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"14d8a5ba7f596141808aa679a44da9e7393c5d9a","unresolved":true,"context_lines":[{"line_number":575,"context_line":"                # Check if origin is allowed"},{"line_number":576,"context_line":"                allowed_origins \u003d [o.strip() for o in allow_origin.split(\u0027 \u0027)"},{"line_number":577,"context_line":"                                   if o.strip()]"},{"line_number":578,"context_line":"                if req_origin in allowed_origins:"},{"line_number":579,"context_line":"                    resp.headers[\u0027Access-Control-Allow-Origin\u0027] \u003d req_origin"},{"line_number":580,"context_line":"                    existing_vary \u003d resp.headers.get(\u0027Vary\u0027)"},{"line_number":581,"context_line":"                    resp.headers[\u0027Vary\u0027] \u003d ("}],"source_content_type":"text/x-python","patch_set":9,"id":"9e12383d_1e8d2b3f","line":578,"updated":"2026-03-10 18:21:55.000000000","message":"OK, so s3api will always behave like [`strict_cors_mode \u003d True`](https://github.com/openstack/swift/blob/2.37.0/etc/proxy-server.conf-sample#L126), which is probably the right call.","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"e6699e7169e97d54f1018bd18eb8633b370fc41d","unresolved":false,"context_lines":[{"line_number":575,"context_line":"                # Check if origin is allowed"},{"line_number":576,"context_line":"                allowed_origins \u003d [o.strip() for o in allow_origin.split(\u0027 \u0027)"},{"line_number":577,"context_line":"                                   if o.strip()]"},{"line_number":578,"context_line":"                if req_origin in allowed_origins:"},{"line_number":579,"context_line":"                    resp.headers[\u0027Access-Control-Allow-Origin\u0027] \u003d req_origin"},{"line_number":580,"context_line":"                    existing_vary \u003d resp.headers.get(\u0027Vary\u0027)"},{"line_number":581,"context_line":"                    resp.headers[\u0027Vary\u0027] \u003d ("}],"source_content_type":"text/x-python","patch_set":9,"id":"abe6595b_9f4e9ffc","line":578,"in_reply_to":"9e12383d_1e8d2b3f","updated":"2026-03-12 12:51:29.000000000","message":"Acknowledged","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"}],"swift/common/middleware/s3api/s3response.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bc4d04f58b0187f327faaa4ba250ca9e08daf9fd","unresolved":true,"context_lines":[{"line_number":690,"context_line":""},{"line_number":691,"context_line":"class NoSuchCORSConfiguration(ErrorResponse):"},{"line_number":692,"context_line":"    _status \u003d \u0027404 Not Found\u0027"},{"line_number":693,"context_line":"    _msg \u003d \u0027The CORS configuration does not exist.\u0027"},{"line_number":694,"context_line":""},{"line_number":695,"context_line":""},{"line_number":696,"context_line":"class NoSuchUpload(ErrorResponse):"}],"source_content_type":"text/x-python","patch_set":9,"id":"fddff920_548c7887","line":693,"range":{"start_line":693,"start_character":49,"end_line":693,"end_character":50},"updated":"2026-03-11 21:15:09.000000000","message":"AWS doesn\u0027t include the period 🙄","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":38841,"name":"Bastien","display_name":"Ph0tonic","email":"bastien.wermeille@proton.me","username":"Ph0tonic"},"change_message_id":"e6699e7169e97d54f1018bd18eb8633b370fc41d","unresolved":false,"context_lines":[{"line_number":690,"context_line":""},{"line_number":691,"context_line":"class NoSuchCORSConfiguration(ErrorResponse):"},{"line_number":692,"context_line":"    _status \u003d \u0027404 Not Found\u0027"},{"line_number":693,"context_line":"    _msg \u003d \u0027The CORS configuration does not exist.\u0027"},{"line_number":694,"context_line":""},{"line_number":695,"context_line":""},{"line_number":696,"context_line":"class NoSuchUpload(ErrorResponse):"}],"source_content_type":"text/x-python","patch_set":9,"id":"00bb3817_e98a598b","line":693,"range":{"start_line":693,"start_character":49,"end_line":693,"end_character":50},"in_reply_to":"fddff920_548c7887","updated":"2026-03-12 12:51:29.000000000","message":"Done","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"}],"swift/common/middleware/s3api/schema/c_or_sconfiguration.rng":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"14d8a5ba7f596141808aa679a44da9e7393c5d9a","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":9,"id":"bdeefd0c_3bc6b437","updated":"2026-03-10 18:21:55.000000000","message":"This file name looks odd -- I was expecting something more like `c_o_r_s_configuration.rng`...\n\nUgh -- looks like a bug in `camel_to_snake`...","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bc4d04f58b0187f327faaa4ba250ca9e08daf9fd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"dbe125d2_9ee07bb7","in_reply_to":"bdeefd0c_3bc6b437","updated":"2026-03-11 21:15:09.000000000","message":"https://review.opendev.org/c/openstack/swift/+/979900 -- now merged.","commit_id":"5b7fbdffd946f88b299478004b280972cf2be219"}]}
