)]}'
{"swift/common/request_helpers.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1e6763f8c1459b7a0ece4f7eb0ddcfb5146115a8","unresolved":false,"context_lines":[{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    param req: request object"},{"line_number":91,"context_line":"    \"\"\""},{"line_number":92,"context_line":"    req.content_type_manually_set \u003d True"},{"line_number":93,"context_line":"    detect_content_type \u003d \\"},{"line_number":94,"context_line":"        config_true_value(req.headers.get(\u0027x-detect-content-type\u0027))"},{"line_number":95,"context_line":"    if detect_content_type or not req.headers.get(\u0027content-type\u0027):"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a2fa921_5479e5c6","line":92,"updated":"2015-10-08 21:20:13.000000000","message":"(Context from https://review.openstack.org/#/c/220897/9/swift/common/request_helpers.py )\n\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\t\n\n\tTim Burke\t\tOct 7 11:33 AM\n\nI\u0027m a little worried about dangling this off the req, instead of stuffing it into req.environ. Can the proxy still see it if middleware calls this first? If not, how much does it matter?\n\nSpeaking of multiple calls, can we make this idempotent? It seems like if we call it repeatedly, every call after the first will think the content-type was manually set.\n\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n\n\tMahati Chamarthy\t\t5:49 AM\n\nUpdate_content_type is called once on PUT in obj controller and now in crypto middleware. req.content_type_manually_set is called only for copy: https://github.com/openstack/swift/blob/2.4.0/swift/proxy/controllers/obj.py#L470 (which should also be similar in encrypter when COPY is implemented)\n\nI think proxy wouldn\u0027t have an issue with that.\n\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n\nSo, we call this once in the middleware (which sets req.content_type_manually_set), which eventually passes things down the pipeline (losing whatever was set, since the pipeline doesn\u0027t know about swob Requests, just WSGI environments), ultimately reaching the proxy which calls it again. By now, req.headers[\u0027content-type\u0027] is definitely set, and \u0027x-detect-content-type\u0027 is decidedly not in req.headers, so req.content_type_manually_set *will* be True, and everything else here gets ignored. Which will mean that a PUT-with-X-Copy-From (but no Content-Type) will use whatever mimetypes thinks the destination content-type should be, rather than what the source content-type *is*.\n\nRight? Am I missing something? Or is it just that we\u0027re not worrying about encrypter+COPY yet?","commit_id":"95002ad0159cdf7fc773e9e73afabadd9856f0d2"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"823d1eb93c1e81dbabfbe3e78a3f30c4738c7bc2","unresolved":false,"context_lines":[{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    param req: request object"},{"line_number":91,"context_line":"    \"\"\""},{"line_number":92,"context_line":"    req.content_type_manually_set \u003d True"},{"line_number":93,"context_line":"    detect_content_type \u003d \\"},{"line_number":94,"context_line":"        config_true_value(req.headers.get(\u0027x-detect-content-type\u0027))"},{"line_number":95,"context_line":"    if detect_content_type or not req.headers.get(\u0027content-type\u0027):"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a2fa921_0324635b","line":92,"in_reply_to":"7a2fa921_5479e5c6","updated":"2015-10-09 14:01:06.000000000","message":"You\u0027re right. We *have* to worry about encrypter+COPY now otherwise it\u0027s breaking existing tests :) Thanks for bringing that up! I fixed it now with req.environ","commit_id":"95002ad0159cdf7fc773e9e73afabadd9856f0d2"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fc65366991fb31fec7e16a0387d5116b7827148d","unresolved":false,"context_lines":[{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    param req: request object"},{"line_number":91,"context_line":"    \"\"\""},{"line_number":92,"context_line":"    req.environ[\u0027content_type_manually_set\u0027] \u003d True"},{"line_number":93,"context_line":"    detect_content_type \u003d \\"},{"line_number":94,"context_line":"        config_true_value(req.headers.get(\u0027x-detect-content-type\u0027))"},{"line_number":95,"context_line":"    if detect_content_type or not req.headers.get(\u0027content-type\u0027):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7a2fa921_dbe5eb08","line":92,"updated":"2015-10-09 17:18:13.000000000","message":"I think we still want this to be idempotent. Otherwise, encrypter will call this once and set content-type, then proxy will call this again and always think the content-type was manually set. Maybe just start off the function with\n\n    if \u0027content_type_manually_set\u0027 in req.environ:\n        return\n\n?","commit_id":"d4a735552fb7d80fac5369365acb7bf64bd930a8"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"65c14f6b4f8cd8673f856635fdd53e775ae3089e","unresolved":false,"context_lines":[{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    param req: request object"},{"line_number":91,"context_line":"    \"\"\""},{"line_number":92,"context_line":"    req.environ[\u0027content_type_manually_set\u0027] \u003d True"},{"line_number":93,"context_line":"    detect_content_type \u003d \\"},{"line_number":94,"context_line":"        config_true_value(req.headers.get(\u0027x-detect-content-type\u0027))"},{"line_number":95,"context_line":"    if detect_content_type or not req.headers.get(\u0027content-type\u0027):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7a2fa921_4771e70a","line":92,"in_reply_to":"7a2fa921_dbe5eb08","updated":"2015-10-10 14:00:01.000000000","message":"Done. Makes sense.","commit_id":"d4a735552fb7d80fac5369365acb7bf64bd930a8"}],"swift/proxy/controllers/obj.py":[{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"f1a508c0da7facf2450c48c72df81451714dd54f","unresolved":false,"context_lines":[{"line_number":481,"context_line":"        del sink_req.headers[\u0027X-Copy-From\u0027]"},{"line_number":482,"context_line":"        if \u0027X-Copy-From-Account\u0027 in sink_req.headers:"},{"line_number":483,"context_line":"            del sink_req.headers[\u0027X-Copy-From-Account\u0027]"},{"line_number":484,"context_line":"        if not req.environ[\u0027content_type_manually_set\u0027]:"},{"line_number":485,"context_line":"            sink_req.headers[\u0027Content-Type\u0027] \u003d \\"},{"line_number":486,"context_line":"                source_resp.headers[\u0027Content-Type\u0027]"},{"line_number":487,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"fa80f949_b653b0e1","line":484,"updated":"2015-11-06 00:52:30.000000000","message":"acoles: could you educate me on this change?  I thought maybe it was done on master, but looking at master now, it still uses the req.content_type_manually_set.  It uses req.environ for other items, but not this one.","commit_id":"b515b289717f3a96148fc3936f9a55987090f3a0"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"b9a047c7487e0a33436a0ddf029b807fc438f819","unresolved":false,"context_lines":[{"line_number":481,"context_line":"        del sink_req.headers[\u0027X-Copy-From\u0027]"},{"line_number":482,"context_line":"        if \u0027X-Copy-From-Account\u0027 in sink_req.headers:"},{"line_number":483,"context_line":"            del sink_req.headers[\u0027X-Copy-From-Account\u0027]"},{"line_number":484,"context_line":"        if not req.environ[\u0027content_type_manually_set\u0027]:"},{"line_number":485,"context_line":"            sink_req.headers[\u0027Content-Type\u0027] \u003d \\"},{"line_number":486,"context_line":"                source_resp.headers[\u0027Content-Type\u0027]"},{"line_number":487,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"fa80f949_7edd05df","line":484,"in_reply_to":"fa80f949_45963694","updated":"2015-11-06 14:58:58.000000000","message":"I see.  thank you!","commit_id":"b515b289717f3a96148fc3936f9a55987090f3a0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"29a0cb7ea7f15d229a30af7e8105c1206502bdca","unresolved":false,"context_lines":[{"line_number":481,"context_line":"        del sink_req.headers[\u0027X-Copy-From\u0027]"},{"line_number":482,"context_line":"        if \u0027X-Copy-From-Account\u0027 in sink_req.headers:"},{"line_number":483,"context_line":"            del sink_req.headers[\u0027X-Copy-From-Account\u0027]"},{"line_number":484,"context_line":"        if not req.environ[\u0027content_type_manually_set\u0027]:"},{"line_number":485,"context_line":"            sink_req.headers[\u0027Content-Type\u0027] \u003d \\"},{"line_number":486,"context_line":"                source_resp.headers[\u0027Content-Type\u0027]"},{"line_number":487,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"fa80f949_45963694","line":484,"in_reply_to":"fa80f949_5ceb8578","updated":"2015-11-06 11:47:04.000000000","message":"See comments here https://review.openstack.org/#/c/232572/1/swift/common/request_helpers.py\n\nNot a change that I made, but makes sense.","commit_id":"b515b289717f3a96148fc3936f9a55987090f3a0"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"ed7eaf23aeb3d2112586c2529468255720c04aa7","unresolved":false,"context_lines":[{"line_number":481,"context_line":"        del sink_req.headers[\u0027X-Copy-From\u0027]"},{"line_number":482,"context_line":"        if \u0027X-Copy-From-Account\u0027 in sink_req.headers:"},{"line_number":483,"context_line":"            del sink_req.headers[\u0027X-Copy-From-Account\u0027]"},{"line_number":484,"context_line":"        if not req.environ[\u0027content_type_manually_set\u0027]:"},{"line_number":485,"context_line":"            sink_req.headers[\u0027Content-Type\u0027] \u003d \\"},{"line_number":486,"context_line":"                source_resp.headers[\u0027Content-Type\u0027]"},{"line_number":487,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"fa80f949_5ceb8578","line":484,"in_reply_to":"fa80f949_b653b0e1","updated":"2015-11-06 02:50:26.000000000","message":"Maybe I can try :)\n\nThis is so that it remains persistent when crypto middleware is in place. So that proxy can see if a change is made via crypto. It cannot if it is latched onto req.","commit_id":"b515b289717f3a96148fc3936f9a55987090f3a0"}],"test/unit/common/middleware/test_encrypter.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1e6763f8c1459b7a0ece4f7eb0ddcfb5146115a8","unresolved":false,"context_lines":[{"line_number":377,"context_line":"        # is encrypted. A todo maybe to decrypt it and verify"},{"line_number":378,"context_line":"        headers \u003d {\u0027Content-Length\u0027: 0, \u0027content-type\u0027: \u0027something/wrong\u0027,"},{"line_number":379,"context_line":"                   \u0027X-Detect-Content-Type\u0027: \u0027True\u0027}"},{"line_number":380,"context_line":"        set_http_connect(204, 204, 201, 201, 201)"},{"line_number":381,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, headers\u003dheaders,"},{"line_number":382,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027,"},{"line_number":383,"context_line":"                                     \u0027swift.crypto.fetch_crypto_keys\u0027:"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a2fa921_3150fbd3","line":380,"updated":"2015-10-08 21:20:13.000000000","message":"Other places that we use set_http_connect in proxy/test_server.py use it along with save_globals. Should we do that here?\n\nOr maybe just turn set_http_connect into a context manager itself? Come to think of it, why aren\u0027t we using mock.patch?","commit_id":"95002ad0159cdf7fc773e9e73afabadd9856f0d2"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"823d1eb93c1e81dbabfbe3e78a3f30c4738c7bc2","unresolved":false,"context_lines":[{"line_number":377,"context_line":"        # is encrypted. A todo maybe to decrypt it and verify"},{"line_number":378,"context_line":"        headers \u003d {\u0027Content-Length\u0027: 0, \u0027content-type\u0027: \u0027something/wrong\u0027,"},{"line_number":379,"context_line":"                   \u0027X-Detect-Content-Type\u0027: \u0027True\u0027}"},{"line_number":380,"context_line":"        set_http_connect(204, 204, 201, 201, 201)"},{"line_number":381,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, headers\u003dheaders,"},{"line_number":382,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027,"},{"line_number":383,"context_line":"                                     \u0027swift.crypto.fetch_crypto_keys\u0027:"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a2fa921_03cea362","line":380,"in_reply_to":"7a2fa921_3150fbd3","updated":"2015-10-09 14:01:06.000000000","message":"Yup, looks like we have to use save_globals - it is holding up things otherwise. \n\nNow I\u0027m just importing those things (save_globals and set_http_connect) from test_server.py","commit_id":"95002ad0159cdf7fc773e9e73afabadd9856f0d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e23ff435d914d372961cded12316babb4640861a","unresolved":false,"context_lines":[{"line_number":367,"context_line":"            container_ring\u003dFakeRing())"},{"line_number":368,"context_line":"        self.app \u003d encrypter.Encrypter(self.proxy_app, {})"},{"line_number":369,"context_line":""},{"line_number":370,"context_line":"    def tearDown(self):"},{"line_number":371,"context_line":"        self.proxy_app.account_ring.set_replicas(3)"},{"line_number":372,"context_line":"        self.proxy_app.container_ring.set_replicas(3)"},{"line_number":373,"context_line":"        for policy in POLICIES:"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a2ca52d_c0ce1d83","line":370,"updated":"2015-10-13 18:03:38.000000000","message":"don\u0027t think this is needed - these tests don\u0027t change the rings","commit_id":"f83947730177cc6d7e451b7f47f0c7b2820ac50f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e23ff435d914d372961cded12316babb4640861a","unresolved":false,"context_lines":[{"line_number":375,"context_line":""},{"line_number":376,"context_line":"    def test_PUT_detect_content_type(self):"},{"line_number":377,"context_line":"        # This only tests that even with the detect ct header, content-type"},{"line_number":378,"context_line":"        # is encrypted. A todo maybe to decrypt it and verify"},{"line_number":379,"context_line":"        with test_server.save_globals():"},{"line_number":380,"context_line":"            headers \u003d {\u0027Content-Length\u0027: 0, \u0027content-type\u0027: \u0027something/wrong\u0027,"},{"line_number":381,"context_line":"                       \u0027X-Detect-Content-Type\u0027: \u0027True\u0027}"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a2ca52d_6094e936","line":378,"updated":"2015-10-13 18:03:38.000000000","message":"It would be good to do this now.","commit_id":"f83947730177cc6d7e451b7f47f0c7b2820ac50f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e23ff435d914d372961cded12316babb4640861a","unresolved":false,"context_lines":[{"line_number":385,"context_line":"                                         \u0027swift.crypto.fetch_crypto_keys\u0027:"},{"line_number":386,"context_line":"                                         fetch_crypto_keys})"},{"line_number":387,"context_line":"            req.get_response(self.app)"},{"line_number":388,"context_line":"            enc_ct \u003d req.headers[\u0027content-type\u0027]"},{"line_number":389,"context_line":"            self.assertTrue(enc_ct !\u003d \u0027something/wrong\u0027)"},{"line_number":390,"context_line":"            self.assertTrue(enc_ct !\u003d \u0027application/octet-stream\u0027)"},{"line_number":391,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5a2ca52d_608dc930","line":388,"updated":"2015-10-13 18:03:38.000000000","message":"this req object is not necessarily the same as the req sent to the connection - so this is not actually verifying what gets emitted from the obj controller.","commit_id":"f83947730177cc6d7e451b7f47f0c7b2820ac50f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e23ff435d914d372961cded12316babb4640861a","unresolved":false,"context_lines":[{"line_number":386,"context_line":"                                         fetch_crypto_keys})"},{"line_number":387,"context_line":"            req.get_response(self.app)"},{"line_number":388,"context_line":"            enc_ct \u003d req.headers[\u0027content-type\u0027]"},{"line_number":389,"context_line":"            self.assertTrue(enc_ct !\u003d \u0027something/wrong\u0027)"},{"line_number":390,"context_line":"            self.assertTrue(enc_ct !\u003d \u0027application/octet-stream\u0027)"},{"line_number":391,"context_line":""},{"line_number":392,"context_line":"    def test_PUT_no_content_type(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a2ca52d_40b68ddd","line":389,"updated":"2015-10-13 18:03:38.000000000","message":"it could be None and the test passes - lets just verify the encrypted value :)","commit_id":"f83947730177cc6d7e451b7f47f0c7b2820ac50f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e23ff435d914d372961cded12316babb4640861a","unresolved":false,"context_lines":[{"line_number":387,"context_line":"            req.get_response(self.app)"},{"line_number":388,"context_line":"            enc_ct \u003d req.headers[\u0027content-type\u0027]"},{"line_number":389,"context_line":"            self.assertTrue(enc_ct !\u003d \u0027something/wrong\u0027)"},{"line_number":390,"context_line":"            self.assertTrue(enc_ct !\u003d \u0027application/octet-stream\u0027)"},{"line_number":391,"context_line":""},{"line_number":392,"context_line":"    def test_PUT_no_content_type(self):"},{"line_number":393,"context_line":"        # Tests content-type is guessed and encrypted when none is supplied"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a2ca52d_a0c1a130","line":390,"updated":"2015-10-13 18:03:38.000000000","message":"use self.assertNotEqual (except see the linked patch for actually asserting the encrypted value)","commit_id":"f83947730177cc6d7e451b7f47f0c7b2820ac50f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e23ff435d914d372961cded12316babb4640861a","unresolved":false,"context_lines":[{"line_number":400,"context_line":"                                         fetch_crypto_keys})"},{"line_number":401,"context_line":"            req.get_response(self.app)"},{"line_number":402,"context_line":"            enc_ct \u003d req.headers[\u0027content-type\u0027]"},{"line_number":403,"context_line":"            self.assertTrue(enc_ct !\u003d \u0027application/octet-stream\u0027)"},{"line_number":404,"context_line":""},{"line_number":405,"context_line":""},{"line_number":406,"context_line":"if __name__ \u003d\u003d \u0027__main__\u0027:"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a2ca52d_e0f55983","line":403,"updated":"2015-10-13 18:03:38.000000000","message":"Also test that when crypto is overridden then we haven\u0027t messed up normal behavior.","commit_id":"f83947730177cc6d7e451b7f47f0c7b2820ac50f"}],"test/unit/proxy/test_server.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e23ff435d914d372961cded12316babb4640861a","unresolved":false,"context_lines":[{"line_number":70,"context_line":"from swift.proxy.controllers.base import get_container_memcache_key, \\"},{"line_number":71,"context_line":"    get_account_memcache_key, cors_validation"},{"line_number":72,"context_line":"import swift.proxy.controllers"},{"line_number":73,"context_line":"import swift.proxy.controllers.obj"},{"line_number":74,"context_line":"from swift.common.swob import Request, Response, HTTPUnauthorized, \\"},{"line_number":75,"context_line":"    HTTPException, HeaderKeyDict"},{"line_number":76,"context_line":"from swift.common import storage_policy"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a2ca52d_a04be1af","side":"PARENT","line":73,"updated":"2015-10-13 18:03:38.000000000","message":"what happened here? how could we have an unused import??","commit_id":"e7de096faed751fd84c436009b4cdc1d4171fd0f"}]}
