)]}'
{"swift/common/middleware/encrypter.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"098e1fad0ccec574cfd4a3805ca524b8bbda405c","unresolved":false,"context_lines":[{"line_number":90,"context_line":"            _dump_crypto_meta(crypto_meta)"},{"line_number":91,"context_line":"        # the proxy controller will call back for footer metadata after"},{"line_number":92,"context_line":"        # body has been sent"},{"line_number":93,"context_line":"        req.environ[\u0027swift.update.footers\u0027] \u003d self.footers_callback"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def footers_callback(self, footers):"},{"line_number":96,"context_line":"        for key in self.footers_to_add:"}],"source_content_type":"text/x-python","patch_set":26,"id":"9a061dce_c62770b4","line":93,"updated":"2016-04-06 17:32:11.000000000","message":"should wrap any existing callback we find in the environ so that it also gets called back","commit_id":"89bee5c677ee85977d34f894cdccef155d9f1cca"}],"swift/proxy/controllers/obj.py":[{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":1027,"context_line":""},{"line_number":1028,"context_line":"                for putter in putters:"},{"line_number":1029,"context_line":"                    if footers:"},{"line_number":1030,"context_line":"                        etag \u003d putter.chunk_hasher.hexdigest()"},{"line_number":1031,"context_line":"                        crypto_md \u003d determine_crypto_md("},{"line_number":1032,"context_line":"                            req, footers, etag)"},{"line_number":1033,"context_line":"                        # TODO - remove log when things are more stable"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_a67be928","line":1030,"updated":"2016-02-09 10:41:34.000000000","message":"Why are we calculating it here and not using the etag in footers which encrypter calculates and appends to footer? As I see it, we don\u0027t use the etag in footers at all. Am I missing something?","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":1027,"context_line":""},{"line_number":1028,"context_line":"                for putter in putters:"},{"line_number":1029,"context_line":"                    if footers:"},{"line_number":1030,"context_line":"                        etag \u003d putter.chunk_hasher.hexdigest()"},{"line_number":1031,"context_line":"                        crypto_md \u003d determine_crypto_md("},{"line_number":1032,"context_line":"                            req, footers, etag)"},{"line_number":1033,"context_line":"                        # TODO - remove log when things are more stable"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_cacf17b2","line":1030,"in_reply_to":"5a5ae5dd_a67be928","updated":"2016-02-14 05:39:13.000000000","message":"the footer etags are for the container, and for the etag to use when compared to user input - like on if match.  In other words, we use the etag of the plaintext for when the client needs to see the value, or when we compare against user input.  \n\nThis etag is the one that is the hash of the ciphertext. It will be compared to what is calculated on the backend against the encrypted data stored to ensure data integrity.","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":1038,"context_line":""},{"line_number":1039,"context_line":"                for putter in putters:"},{"line_number":1040,"context_line":"                    putter.wait()"},{"line_number":1041,"context_line":"                putters \u003d [p for p in putters if not p.failed]"},{"line_number":1042,"context_line":"        except ChunkReadTimeout as err:"},{"line_number":1043,"context_line":"            self.app.logger.warning("},{"line_number":1044,"context_line":"                _(\u0027ERROR Client read timeout (%ss)\u0027), err.seconds)"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_3c2b9235","line":1041,"updated":"2016-02-09 10:41:34.000000000","message":"this putters filter needed is not needed here since you\u0027re not using it anywhere to check connections as earlier code: https://github.com/openstack/swift/blob/feature/crypto/swift/proxy/controllers/obj.py#L971\n\nBut why are we not checking _check_min_conns this here? I think that check needs to be there.","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":1038,"context_line":""},{"line_number":1039,"context_line":"                for putter in putters:"},{"line_number":1040,"context_line":"                    putter.wait()"},{"line_number":1041,"context_line":"                putters \u003d [p for p in putters if not p.failed]"},{"line_number":1042,"context_line":"        except ChunkReadTimeout as err:"},{"line_number":1043,"context_line":"            self.app.logger.warning("},{"line_number":1044,"context_line":"                _(\u0027ERROR Client read timeout (%ss)\u0027), err.seconds)"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_4a95c73e","line":1041,"in_reply_to":"5a5ae5dd_3c2b9235","updated":"2016-02-14 05:39:13.000000000","message":"Done","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":1073,"context_line":"        \"\"\""},{"line_number":1074,"context_line":"        Store an object using \u0027putters\u0027."},{"line_number":1075,"context_line":"        \"\"\""},{"line_number":1076,"context_line":"        policy_index \u003d int(req.headers.get(\u0027X-Backend-Storage-Policy-Index\u0027))"},{"line_number":1077,"context_line":"        policy \u003d POLICIES.get_by_index(policy_index)"},{"line_number":1078,"context_line":""},{"line_number":1079,"context_line":"        min_conns \u003d policy.quorum"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_502ea6fb","line":1076,"updated":"2016-02-09 10:41:34.000000000","message":"This conversion is done by \u0027get_by_index\u0027 in below line. So this int is not necessary.","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":1073,"context_line":"        \"\"\""},{"line_number":1074,"context_line":"        Store an object using \u0027putters\u0027."},{"line_number":1075,"context_line":"        \"\"\""},{"line_number":1076,"context_line":"        policy_index \u003d int(req.headers.get(\u0027X-Backend-Storage-Policy-Index\u0027))"},{"line_number":1077,"context_line":"        policy \u003d POLICIES.get_by_index(policy_index)"},{"line_number":1078,"context_line":""},{"line_number":1079,"context_line":"        min_conns \u003d policy.quorum"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_4a7ca720","line":1076,"in_reply_to":"5a5ae5dd_502ea6fb","updated":"2016-02-14 05:39:13.000000000","message":"Done","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":1086,"context_line":"            # meet all the correct conditions set in the request"},{"line_number":1087,"context_line":"            self._check_failure_put_connections(putters, req, min_conns)"},{"line_number":1088,"context_line":""},{"line_number":1089,"context_line":"            self._transfer_data(req, data_source, putters, nodes, policy)"},{"line_number":1090,"context_line":""},{"line_number":1091,"context_line":"            putters \u003d [p for p in putters if not p.failed]"},{"line_number":1092,"context_line":"            statuses, reasons, bodies, etags \u003d \\"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_887601d7","line":1089,"updated":"2016-02-09 10:41:34.000000000","message":"\u0027policy\u0027 variable is not used in _transfer_data above. can be removed here and in above method.","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":1086,"context_line":"            # meet all the correct conditions set in the request"},{"line_number":1087,"context_line":"            self._check_failure_put_connections(putters, req, min_conns)"},{"line_number":1088,"context_line":""},{"line_number":1089,"context_line":"            self._transfer_data(req, data_source, putters, nodes, policy)"},{"line_number":1090,"context_line":""},{"line_number":1091,"context_line":"            putters \u003d [p for p in putters if not p.failed]"},{"line_number":1092,"context_line":"            statuses, reasons, bodies, etags \u003d \\"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_8aad0f8b","line":1089,"in_reply_to":"5a5ae5dd_887601d7","updated":"2016-02-14 05:39:13.000000000","message":"Done","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":1088,"context_line":""},{"line_number":1089,"context_line":"            self._transfer_data(req, data_source, putters, nodes, policy)"},{"line_number":1090,"context_line":""},{"line_number":1091,"context_line":"            putters \u003d [p for p in putters if not p.failed]"},{"line_number":1092,"context_line":"            statuses, reasons, bodies, etags \u003d \\"},{"line_number":1093,"context_line":"                self._get_put_responses(req, putters, len(nodes))"},{"line_number":1094,"context_line":"        except HTTPException as resp:"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_bccd4288","line":1091,"updated":"2016-02-09 10:41:34.000000000","message":"you\u0027re already making this p.failed check in _get_put_responses, this is not required here.","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":1088,"context_line":""},{"line_number":1089,"context_line":"            self._transfer_data(req, data_source, putters, nodes, policy)"},{"line_number":1090,"context_line":""},{"line_number":1091,"context_line":"            putters \u003d [p for p in putters if not p.failed]"},{"line_number":1092,"context_line":"            statuses, reasons, bodies, etags \u003d \\"},{"line_number":1093,"context_line":"                self._get_put_responses(req, putters, len(nodes))"},{"line_number":1094,"context_line":"        except HTTPException as resp:"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_2ac7a346","line":1091,"in_reply_to":"5a5ae5dd_bccd4288","updated":"2016-02-14 05:39:13.000000000","message":"I looked at removing this.  The thing is, this imitates what is currently done in EC _store_object.  And there is one line that operates on putters in _get_put_responses before the filter is made - GreenAsyncPile(len(putters)).  Maybe that is only an approximate sizing, and not the exact number. I will have to look into that.\n\nI could remove the filter in _get_put_responses, but then there is one call to it now that does not do the filtering before the call, so the _get_put_responses probably needs it too.  \n\nIf this change is correct, then it should also be correct for EC.  I will want to investigate more before removing this.  I did add a comment \"# sanity check\" in _get_put_responses when it filters.","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":1090,"context_line":""},{"line_number":1091,"context_line":"            putters \u003d [p for p in putters if not p.failed]"},{"line_number":1092,"context_line":"            statuses, reasons, bodies, etags \u003d \\"},{"line_number":1093,"context_line":"                self._get_put_responses(req, putters, len(nodes))"},{"line_number":1094,"context_line":"        except HTTPException as resp:"},{"line_number":1095,"context_line":"            return resp"},{"line_number":1096,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_682b8595","line":1093,"updated":"2016-02-09 10:41:34.000000000","message":"comments for code, still apply here. (eg: \"#transfer data\", \"#get responses\")","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":1090,"context_line":""},{"line_number":1091,"context_line":"            putters \u003d [p for p in putters if not p.failed]"},{"line_number":1092,"context_line":"            statuses, reasons, bodies, etags \u003d \\"},{"line_number":1093,"context_line":"                self._get_put_responses(req, putters, len(nodes))"},{"line_number":1094,"context_line":"        except HTTPException as resp:"},{"line_number":1095,"context_line":"            return resp"},{"line_number":1096,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_0a0c5f93","line":1093,"in_reply_to":"5a5ae5dd_682b8595","updated":"2016-02-14 05:39:13.000000000","message":"yes, there are a few occurrences of the putters filter before the _get_put_responses call.  Again, one includes the current call from EC.  Is this what you meant here?","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":1810,"context_line":""},{"line_number":1811,"context_line":"        conn.node \u003d node"},{"line_number":1812,"context_line":"        conn.resp \u003d None"},{"line_number":1813,"context_line":"        if is_success(resp.status) or resp.status \u003d\u003d HTTP_CONFLICT:"},{"line_number":1814,"context_line":"            conn.resp \u003d resp"},{"line_number":1815,"context_line":"        elif (headers.get(\u0027If-None-Match\u0027, None) is not None and"},{"line_number":1816,"context_line":"              resp.status \u003d\u003d HTTP_PRECONDITION_FAILED):"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_5e05500e","line":1813,"updated":"2016-02-09 10:41:34.000000000","message":"HTTP_UNPROCESSABLE_ENTITY is missing, which earlier the code would check in Replication PUT.\nhttps://github.com/openstack/swift/blob/master/swift/proxy/controllers/obj.py#L905","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":1810,"context_line":""},{"line_number":1811,"context_line":"        conn.node \u003d node"},{"line_number":1812,"context_line":"        conn.resp \u003d None"},{"line_number":1813,"context_line":"        if is_success(resp.status) or resp.status \u003d\u003d HTTP_CONFLICT:"},{"line_number":1814,"context_line":"            conn.resp \u003d resp"},{"line_number":1815,"context_line":"        elif (headers.get(\u0027If-None-Match\u0027, None) is not None and"},{"line_number":1816,"context_line":"              resp.status \u003d\u003d HTTP_PRECONDITION_FAILED):"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_ea5e5b75","line":1813,"in_reply_to":"5a5ae5dd_5e05500e","updated":"2016-02-14 05:39:13.000000000","message":"This is copying what is done for the ECPutter.  I will need to ask if the HTTP_UNPROCESSABLE_ENTITY should be added to both connect methods for putters.  It may be a difference in using a putter, or it could be an oversight in EC as well.","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":1839,"context_line":"    def __init__(self, conn, node, resp, path, connect_duration,"},{"line_number":1840,"context_line":"                 chunked, logger, mime_boundary, footer_callback):"},{"line_number":1841,"context_line":"        BasePutter.__init__(self, conn, node, resp, path, connect_duration,"},{"line_number":1842,"context_line":"                            chunked, logger)"},{"line_number":1843,"context_line":"        # Note: you probably want to call Putter.connect() instead of"},{"line_number":1844,"context_line":"        # instantiating one of these directly."},{"line_number":1845,"context_line":"        self.mime_boundary \u003d mime_boundary"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_bf6774e9","line":1842,"updated":"2016-02-09 10:41:34.000000000","message":"why not use Super? Same for other putter instantiations.","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":1839,"context_line":"    def __init__(self, conn, node, resp, path, connect_duration,"},{"line_number":1840,"context_line":"                 chunked, logger, mime_boundary, footer_callback):"},{"line_number":1841,"context_line":"        BasePutter.__init__(self, conn, node, resp, path, connect_duration,"},{"line_number":1842,"context_line":"                            chunked, logger)"},{"line_number":1843,"context_line":"        # Note: you probably want to call Putter.connect() instead of"},{"line_number":1844,"context_line":"        # instantiating one of these directly."},{"line_number":1845,"context_line":"        self.mime_boundary \u003d mime_boundary"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_4a0ca742","line":1842,"in_reply_to":"5a5ae5dd_bf6774e9","updated":"2016-02-14 05:39:13.000000000","message":"Done","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":2240,"context_line":"    ct \u003d req.headers["},{"line_number":2241,"context_line":"        \u0027X-Backend-Container-Update-Override-Content-Type\u0027] \\"},{"line_number":2242,"context_line":"        if \u0027X-Backend-Container-Update-Override-Content-Type\u0027 \\"},{"line_number":2243,"context_line":"           in req.headers else None"},{"line_number":2244,"context_line":"    cont_etag \u003d footers["},{"line_number":2245,"context_line":"        \u0027X-Backend-Container-Update-Override-Etag\u0027] \\"},{"line_number":2246,"context_line":"        if \u0027X-Backend-Container-Update-Override-Etag\u0027 \\"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_4d3da88d","line":2243,"updated":"2016-02-09 10:41:34.000000000","message":"why not ct \u003d req.headers.get[\u0027X-Backend-Container-Update-Override-Content-Type\u0027, None]?","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":2240,"context_line":"    ct \u003d req.headers["},{"line_number":2241,"context_line":"        \u0027X-Backend-Container-Update-Override-Content-Type\u0027] \\"},{"line_number":2242,"context_line":"        if \u0027X-Backend-Container-Update-Override-Content-Type\u0027 \\"},{"line_number":2243,"context_line":"           in req.headers else None"},{"line_number":2244,"context_line":"    cont_etag \u003d footers["},{"line_number":2245,"context_line":"        \u0027X-Backend-Container-Update-Override-Etag\u0027] \\"},{"line_number":2246,"context_line":"        if \u0027X-Backend-Container-Update-Override-Etag\u0027 \\"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_b503180d","line":2243,"in_reply_to":"5a5ae5dd_4d3da88d","updated":"2016-02-14 05:39:13.000000000","message":"Done","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":2244,"context_line":"    cont_etag \u003d footers["},{"line_number":2245,"context_line":"        \u0027X-Backend-Container-Update-Override-Etag\u0027] \\"},{"line_number":2246,"context_line":"        if \u0027X-Backend-Container-Update-Override-Etag\u0027 \\"},{"line_number":2247,"context_line":"           in footers else None"},{"line_number":2248,"context_line":"    etag_crypto_meta \u003d footers["},{"line_number":2249,"context_line":"        \u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027] \\"},{"line_number":2250,"context_line":"        if \u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027 \\"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_8d4f2033","line":2247,"updated":"2016-02-09 10:41:34.000000000","message":"ditto. footers.get","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":2244,"context_line":"    cont_etag \u003d footers["},{"line_number":2245,"context_line":"        \u0027X-Backend-Container-Update-Override-Etag\u0027] \\"},{"line_number":2246,"context_line":"        if \u0027X-Backend-Container-Update-Override-Etag\u0027 \\"},{"line_number":2247,"context_line":"           in footers else None"},{"line_number":2248,"context_line":"    etag_crypto_meta \u003d footers["},{"line_number":2249,"context_line":"        \u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027] \\"},{"line_number":2250,"context_line":"        if \u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027 \\"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_1509242d","line":2247,"in_reply_to":"5a5ae5dd_8d4f2033","updated":"2016-02-14 05:39:13.000000000","message":"Done","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":2248,"context_line":"    etag_crypto_meta \u003d footers["},{"line_number":2249,"context_line":"        \u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027] \\"},{"line_number":2250,"context_line":"        if \u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027 \\"},{"line_number":2251,"context_line":"           in footers else None"},{"line_number":2252,"context_line":"    crypto_etag \u003d footers["},{"line_number":2253,"context_line":"        \u0027X-Object-Sysmeta-Crypto-Etag\u0027] \\"},{"line_number":2254,"context_line":"        if \u0027X-Object-Sysmeta-Crypto-Etag\u0027 \\"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_ed56d4cc","line":2251,"updated":"2016-02-09 10:41:34.000000000","message":"ditto","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":2248,"context_line":"    etag_crypto_meta \u003d footers["},{"line_number":2249,"context_line":"        \u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027] \\"},{"line_number":2250,"context_line":"        if \u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027 \\"},{"line_number":2251,"context_line":"           in footers else None"},{"line_number":2252,"context_line":"    crypto_etag \u003d footers["},{"line_number":2253,"context_line":"        \u0027X-Object-Sysmeta-Crypto-Etag\u0027] \\"},{"line_number":2254,"context_line":"        if \u0027X-Object-Sysmeta-Crypto-Etag\u0027 \\"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_f50da038","line":2251,"in_reply_to":"5a5ae5dd_ed56d4cc","updated":"2016-02-14 05:39:13.000000000","message":"Done","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":2252,"context_line":"    crypto_etag \u003d footers["},{"line_number":2253,"context_line":"        \u0027X-Object-Sysmeta-Crypto-Etag\u0027] \\"},{"line_number":2254,"context_line":"        if \u0027X-Object-Sysmeta-Crypto-Etag\u0027 \\"},{"line_number":2255,"context_line":"           in footers else None"},{"line_number":2256,"context_line":"    ec_etag \u003d None"},{"line_number":2257,"context_line":"    if trail_md:"},{"line_number":2258,"context_line":"        ec_etag \u003d trail_md[\u0027X-Object-Sysmeta-EC-Etag\u0027] \\"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_ed0d74e8","line":2255,"updated":"2016-02-09 10:41:34.000000000","message":"ditto","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":2252,"context_line":"    crypto_etag \u003d footers["},{"line_number":2253,"context_line":"        \u0027X-Object-Sysmeta-Crypto-Etag\u0027] \\"},{"line_number":2254,"context_line":"        if \u0027X-Object-Sysmeta-Crypto-Etag\u0027 \\"},{"line_number":2255,"context_line":"           in footers else None"},{"line_number":2256,"context_line":"    ec_etag \u003d None"},{"line_number":2257,"context_line":"    if trail_md:"},{"line_number":2258,"context_line":"        ec_etag \u003d trail_md[\u0027X-Object-Sysmeta-EC-Etag\u0027] \\"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_5513ac5c","line":2255,"in_reply_to":"5a5ae5dd_ed0d74e8","updated":"2016-02-14 05:39:13.000000000","message":"Done","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":2256,"context_line":"    ec_etag \u003d None"},{"line_number":2257,"context_line":"    if trail_md:"},{"line_number":2258,"context_line":"        ec_etag \u003d trail_md[\u0027X-Object-Sysmeta-EC-Etag\u0027] \\"},{"line_number":2259,"context_line":"            if \u0027X-Object-Sysmeta-EC-Etag\u0027 in trail_md else None"},{"line_number":2260,"context_line":""},{"line_number":2261,"context_line":"    crypto_md \u003d trailing_metadata_crypto("},{"line_number":2262,"context_line":"        cont_etag\u003dcont_etag,"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_6d02e4b5","line":2259,"updated":"2016-02-09 10:41:34.000000000","message":"ditto","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":2256,"context_line":"    ec_etag \u003d None"},{"line_number":2257,"context_line":"    if trail_md:"},{"line_number":2258,"context_line":"        ec_etag \u003d trail_md[\u0027X-Object-Sysmeta-EC-Etag\u0027] \\"},{"line_number":2259,"context_line":"            if \u0027X-Object-Sysmeta-EC-Etag\u0027 in trail_md else None"},{"line_number":2260,"context_line":""},{"line_number":2261,"context_line":"    crypto_md \u003d trailing_metadata_crypto("},{"line_number":2262,"context_line":"        cont_etag\u003dcont_etag,"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_3510a84e","line":2259,"in_reply_to":"5a5ae5dd_6d02e4b5","updated":"2016-02-14 05:39:13.000000000","message":"Done","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"435c7f3cf96ad147971877b29e2c1955945bba13","unresolved":false,"context_lines":[{"line_number":2258,"context_line":"        ec_etag \u003d trail_md[\u0027X-Object-Sysmeta-EC-Etag\u0027] \\"},{"line_number":2259,"context_line":"            if \u0027X-Object-Sysmeta-EC-Etag\u0027 in trail_md else None"},{"line_number":2260,"context_line":""},{"line_number":2261,"context_line":"    crypto_md \u003d trailing_metadata_crypto("},{"line_number":2262,"context_line":"        cont_etag\u003dcont_etag,"},{"line_number":2263,"context_line":"        cont_content_type\u003dct,"},{"line_number":2264,"context_line":"        etag\u003detag,"}],"source_content_type":"text/x-python","patch_set":14,"id":"5a5ae5dd_0d849008","line":2261,"updated":"2016-02-09 10:41:34.000000000","message":"with the above changes, maybe you could club determine_crypto_md with trailing_metadata_crypto","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"46c570453dd152aad917bf4c6d3d976928f4148a","unresolved":false,"context_lines":[{"line_number":2258,"context_line":"        ec_etag \u003d trail_md[\u0027X-Object-Sysmeta-EC-Etag\u0027] \\"},{"line_number":2259,"context_line":"            if \u0027X-Object-Sysmeta-EC-Etag\u0027 in trail_md else None"},{"line_number":2260,"context_line":""},{"line_number":2261,"context_line":"    crypto_md \u003d trailing_metadata_crypto("},{"line_number":2262,"context_line":"        cont_etag\u003dcont_etag,"},{"line_number":2263,"context_line":"        cont_content_type\u003dct,"},{"line_number":2264,"context_line":"        etag\u003detag,"}],"source_content_type":"text/x-python","patch_set":14,"id":"dae33548_8aaa2f18","line":2261,"in_reply_to":"5a5ae5dd_0d849008","updated":"2016-02-14 05:39:13.000000000","message":"I like keeping it similar to trailing_metadata_ec for now.  I expect somebody (maybe me later) might come up with a better way to define that trailing_metadata dict so its generic.","commit_id":"278cd7d1d541e2db440936d70db0d4473b32506e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"91bdb9b33e7611c0bc45389236a45f640b85e05a","unresolved":false,"context_lines":[{"line_number":1911,"context_line":"        return self.footer_callback"},{"line_number":1912,"context_line":""},{"line_number":1913,"context_line":""},{"line_number":1914,"context_line":"class CryptoPutter(MIMEPutter):"},{"line_number":1915,"context_line":"    \"\"\""},{"line_number":1916,"context_line":"    Putter used with encryption"},{"line_number":1917,"context_line":"    Uses Mime, but not 2-phase.  Uses different footers than EC."}],"source_content_type":"text/x-python","patch_set":19,"id":"ba0121b8_3998b277","line":1914,"updated":"2016-04-01 18:16:37.000000000","message":"Should be possible to make this and ECPutter be the same thing","commit_id":"1820aa4fcad06aeb74e36a6567f9101e31e3c10d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"91bdb9b33e7611c0bc45389236a45f640b85e05a","unresolved":false,"context_lines":[{"line_number":2454,"context_line":"        # in the specific case of replication vs. EC, it doesn\u0027t)."},{"line_number":2455,"context_line":"        if \u0027Content-Length\u0027 in headers:"},{"line_number":2456,"context_line":"            if int(headers[\u0027Content-Length\u0027]) \u003d\u003d 0:"},{"line_number":2457,"context_line":"                headers[\u0027Expect\u0027] \u003d \u0027100-continue\u0027"},{"line_number":2458,"context_line":""},{"line_number":2459,"context_line":"        headers.pop(\u0027Content-Length\u0027, None)"},{"line_number":2460,"context_line":"        headers.pop(\u0027Etag\u0027, None)"}],"source_content_type":"text/x-python","patch_set":19,"id":"ba0121b8_39fb927a","line":2457,"updated":"2016-04-01 18:16:37.000000000","message":"Don\u0027t think this is needed - it happens in the ECPutter connect method","commit_id":"1820aa4fcad06aeb74e36a6567f9101e31e3c10d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"91bdb9b33e7611c0bc45389236a45f640b85e05a","unresolved":false,"context_lines":[{"line_number":2482,"context_line":"                    node, _(\u0027Object\u0027),"},{"line_number":2483,"context_line":"                    _(\u0027Expect: 100-continue on %s\u0027) % path)"},{"line_number":2484,"context_line":""},{"line_number":2485,"context_line":"    def chunk_transformer(self, policy, nstreams):"},{"line_number":2486,"context_line":"        segment_size \u003d policy.ec_segment_size"},{"line_number":2487,"context_line":""},{"line_number":2488,"context_line":"        buf \u003d collections.deque()"}],"source_content_type":"text/x-python","patch_set":19,"id":"ba0121b8_59700640","line":2485,"updated":"2016-04-01 18:16:37.000000000","message":"Not sure why this got made a class method, it doesn\u0027t need to be and just complicates the review.","commit_id":"1820aa4fcad06aeb74e36a6567f9101e31e3c10d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":1025,"context_line":"        policy_index \u003d req.headers.get(\u0027X-Backend-Storage-Policy-Index\u0027)"},{"line_number":1026,"context_line":"        policy \u003d POLICIES.get_by_index(policy_index)"},{"line_number":1027,"context_line":"        if not nodes:"},{"line_number":1028,"context_line":"            return HTTPNotFound()"},{"line_number":1029,"context_line":""},{"line_number":1030,"context_line":"        # RFC2616:8.2.3 disallows 100-continue without a body"},{"line_number":1031,"context_line":"        if (req.content_length \u003e 0) or req.is_chunked:"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_52f3a80a","side":"PARENT","line":1028,"updated":"2016-04-04 18:38:27.000000000","message":"why did the test for zero nodes get deleted?","commit_id":"a4645cf27c77b120db2bcf5724245ab1d18c49e5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"            return resp"},{"line_number":1051,"context_line":"        finally:"},{"line_number":1052,"context_line":"            for conn in conns:"},{"line_number":1053,"context_line":"                conn.close()"},{"line_number":1054,"context_line":""},{"line_number":1055,"context_line":"        if len(etags) \u003e 1:"},{"line_number":1056,"context_line":"            self.app.logger.error("}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_f28c7c37","side":"PARENT","line":1053,"updated":"2016-04-04 18:38:27.000000000","message":"where did the closes get moved to?","commit_id":"a4645cf27c77b120db2bcf5724245ab1d18c49e5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":381,"context_line":"            if response:"},{"line_number":382,"context_line":"                _handle_response(putter, response)"},{"line_number":383,"context_line":"                if min_responses and \\"},{"line_number":384,"context_line":"                        self._have_adequate_successes(statuses, min_responses):"},{"line_number":385,"context_line":"                    break"},{"line_number":386,"context_line":"                elif not min_responses and \\"},{"line_number":387,"context_line":"                        self.have_quorum(statuses, num_nodes):"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_2a09622d","line":384,"updated":"2016-04-04 18:38:27.000000000","message":"_have_adequate_successes is not defined for the Repl case which means we\u0027re relying on min_responses \u003e 0 to avoid the code blowing up.","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"07ea33e56c1cde060ddec0bfa9f31663e09e5a59","unresolved":false,"context_lines":[{"line_number":381,"context_line":"            if response:"},{"line_number":382,"context_line":"                _handle_response(putter, response)"},{"line_number":383,"context_line":"                if min_responses and \\"},{"line_number":384,"context_line":"                        self._have_adequate_successes(statuses, min_responses):"},{"line_number":385,"context_line":"                    break"},{"line_number":386,"context_line":"                elif not min_responses and \\"},{"line_number":387,"context_line":"                        self.have_quorum(statuses, num_nodes):"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_423c6893","line":384,"in_reply_to":"9a061dce_2a09622d","updated":"2016-04-04 19:33:04.000000000","message":"yes, great point! completely missed that. I noticed you already changed a lot of this method in the latest patchset, so I will review it again...","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":390,"context_line":"                # if self._have_adequate_successes(statuses, min_responses):"},{"line_number":391,"context_line":"                #     break"},{"line_number":392,"context_line":"            elif putter:"},{"line_number":393,"context_line":"                # TODO - not sure why EC/crypto didn\u0027t need this condition"},{"line_number":394,"context_line":"                putter.failed \u003d True"},{"line_number":395,"context_line":""},{"line_number":396,"context_line":"        # give any pending requests *some* chance to finish"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_2cd69dc5","line":393,"updated":"2016-04-04 18:38:27.000000000","message":"with repl, get_conn_response might return None, None i.e. the conn could be None, with the EC putter pattern, get_conn_response always returns conn which is in fact a putter.","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"07ea33e56c1cde060ddec0bfa9f31663e09e5a59","unresolved":false,"context_lines":[{"line_number":390,"context_line":"                # if self._have_adequate_successes(statuses, min_responses):"},{"line_number":391,"context_line":"                #     break"},{"line_number":392,"context_line":"            elif putter:"},{"line_number":393,"context_line":"                # TODO - not sure why EC/crypto didn\u0027t need this condition"},{"line_number":394,"context_line":"                putter.failed \u003d True"},{"line_number":395,"context_line":""},{"line_number":396,"context_line":"        # give any pending requests *some* chance to finish"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_22c97479","line":393,"in_reply_to":"9a061dce_2cd69dc5","updated":"2016-04-04 19:33:04.000000000","message":"got it!","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":406,"context_line":"                    statuses.append(HTTP_SERVICE_UNAVAILABLE)"},{"line_number":407,"context_line":"                    reasons.append(\u0027\u0027)"},{"line_number":408,"context_line":"                    bodies.append(\u0027\u0027)"},{"line_number":409,"context_line":"            else:"},{"line_number":410,"context_line":"                # intermediate response phase - set return value to true only"},{"line_number":411,"context_line":"                # if there are responses having same value of *any* status"},{"line_number":412,"context_line":"                # except 5xx"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_96c41d41","line":409,"updated":"2016-04-04 18:38:27.000000000","message":"I think this could just be moved out to the calling site - need_quorum is only True for once call site.","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":1007,"context_line":"                chunk \u003d yield [chunk] * nstreams"},{"line_number":1008,"context_line":"            # Be nice to the person sending us the empty-string to indicate"},{"line_number":1009,"context_line":"            # end-of-message; otherwise, they get a StopIteration"},{"line_number":1010,"context_line":"            chunk \u003d yield [chunk] * nstreams"},{"line_number":1011,"context_line":""},{"line_number":1012,"context_line":"        bytes_transferred \u003d 0"},{"line_number":1013,"context_line":"        chunk_transform \u003d chunk_transformer(len(nodes))"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_f5e7413e","line":1010,"updated":"2016-04-04 18:38:27.000000000","message":"not sure why this is needed - it seems to take a chunk and return a llist of chunks. In the EC case this would have transformed each chunk into a destination backend-specific fragment, but for replica all backends get the same chunk content.","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":1014,"context_line":"        chunk_transform.send(None)"},{"line_number":1015,"context_line":""},{"line_number":1016,"context_line":"        def send_chunk(chunk):"},{"line_number":1017,"context_line":"            backend_chunks \u003d chunk_transform.send(chunk)"},{"line_number":1018,"context_line":"            if backend_chunks is None:"},{"line_number":1019,"context_line":"                # If there\u0027s not enough bytes buffered for erasure-encoding"},{"line_number":1020,"context_line":"                # or whatever we\u0027re doing, the transform will give us None."}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_88106c50","line":1017,"updated":"2016-04-04 18:38:27.000000000","message":"no need for the chunk_transform - we just need to send the chunk to every putter","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":1023,"context_line":"            for putter in list(putters):"},{"line_number":1024,"context_line":"                backend_chunk \u003d backend_chunks[chunk_index[putter]]"},{"line_number":1025,"context_line":"                if not putter.failed:"},{"line_number":1026,"context_line":"                    putter.chunk_hasher.update(backend_chunk)"},{"line_number":1027,"context_line":"                    putter.send_chunk(backend_chunk)"},{"line_number":1028,"context_line":"                else:"},{"line_number":1029,"context_line":"                    putters.remove(putter)"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_284de072","line":1026,"updated":"2016-04-04 18:38:27.000000000","message":"don\u0027t think we need to re-calculate the hash in replication case since we are not changing it *here*","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":1037,"context_line":""},{"line_number":1038,"context_line":"                # build our chunk index dict to place handoffs in the"},{"line_number":1039,"context_line":"                # same part nodes index as the primaries they are covering"},{"line_number":1040,"context_line":"                chunk_index \u003d self._determine_chunk_destinations(putters)"},{"line_number":1041,"context_line":""},{"line_number":1042,"context_line":"                for putter in putters:"},{"line_number":1043,"context_line":"                    putter.spawn_sender_greenthread("}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_0879fc93","line":1040,"updated":"2016-04-04 18:38:27.000000000","message":"not needed, same chunk goes to all backends","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":1063,"context_line":"                    self.app.logger.increment(\u0027client_disconnects\u0027)"},{"line_number":1064,"context_line":"                    raise HTTPClientDisconnect(request\u003dreq)"},{"line_number":1065,"context_line":""},{"line_number":1066,"context_line":"                    # TODO - Is the etag check necessary here like EC?"},{"line_number":1067,"context_line":""},{"line_number":1068,"context_line":"                # TODO - Why was this needed? It makes things break"},{"line_number":1069,"context_line":"                # send_chunk(\u0027\u0027)  # flush out any buffered data"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_48e2d404","line":1066,"updated":"2016-04-04 18:38:27.000000000","message":"no - in EC case the etag per backend/fragment is only known once the content has been streamed through the EC coder, so has to be compared with what the backend thinks it received. For replication case, the content has not changed as it passed through the proxy so backend value should match anything the client sent.\n\n(With crypto, the encrypter does a check that the backend etag matches the hash of the ciphertext - at least, it should!)","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":1123,"context_line":"        Store an object using \u0027putters\u0027."},{"line_number":1124,"context_line":"        \"\"\""},{"line_number":1125,"context_line":"        policy \u003d POLICIES.get_by_index("},{"line_number":1126,"context_line":"            req.headers.get(\u0027X-Backend-Storage-Policy-Index\u0027))"},{"line_number":1127,"context_line":""},{"line_number":1128,"context_line":"        min_conns \u003d policy.quorum"},{"line_number":1129,"context_line":"        putters \u003d self._get_put_connections("}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_f23bdc9a","line":1126,"updated":"2016-04-04 18:38:27.000000000","message":"this change doesn\u0027t save any lines and probably best avoided in a patch that\u0027s already large ;)","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":1125,"context_line":"        policy \u003d POLICIES.get_by_index("},{"line_number":1126,"context_line":"            req.headers.get(\u0027X-Backend-Storage-Policy-Index\u0027))"},{"line_number":1127,"context_line":""},{"line_number":1128,"context_line":"        min_conns \u003d policy.quorum"},{"line_number":1129,"context_line":"        putters \u003d self._get_put_connections("},{"line_number":1130,"context_line":"            req, nodes, partition, outgoing_headers,"},{"line_number":1131,"context_line":"            policy)"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_92e70012","line":1128,"updated":"2016-04-04 18:38:27.000000000","message":"the existing repl code path uses quorum_size(len(nodes)) - I can see that policy.quorum may be more intuitive but I wonder if we should just leave that alone in this patch?","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":2655,"context_line":"                    status_type, req.path))"},{"line_number":2656,"context_line":"        return (conn, resp)"},{"line_number":2657,"context_line":""},{"line_number":2658,"context_line":"    def _get_put_responses2(self, req, putters, num_nodes, final_phase,"},{"line_number":2659,"context_line":"                            min_responses, need_quorum\u003dTrue):"},{"line_number":2660,"context_line":"        \"\"\""},{"line_number":2661,"context_line":"        Collect erasure coded object responses."}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_7673494e","line":2658,"updated":"2016-04-04 18:38:27.000000000","message":"this can be deleted I guess? nice combination with the Repl method.","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"07ea33e56c1cde060ddec0bfa9f31663e09e5a59","unresolved":false,"context_lines":[{"line_number":2655,"context_line":"                    status_type, req.path))"},{"line_number":2656,"context_line":"        return (conn, resp)"},{"line_number":2657,"context_line":""},{"line_number":2658,"context_line":"    def _get_put_responses2(self, req, putters, num_nodes, final_phase,"},{"line_number":2659,"context_line":"                            min_responses, need_quorum\u003dTrue):"},{"line_number":2660,"context_line":"        \"\"\""},{"line_number":2661,"context_line":"        Collect erasure coded object responses."}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_c2acf8ef","line":2658,"in_reply_to":"9a061dce_7673494e","updated":"2016-04-04 19:33:04.000000000","message":"oops. forgot it behind, thanks for the cleanup","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"51fb946fddfeec0a9b8d2f89b7da597b0f09ad95","unresolved":false,"context_lines":[{"line_number":708,"context_line":"                                  {\u0027conns\u0027: len(conns), \u0027nodes\u0027: min_conns})"},{"line_number":709,"context_line":"            raise HTTPServiceUnavailable(request\u003dreq)"},{"line_number":710,"context_line":""},{"line_number":711,"context_line":"    def _get_footers(self, req):"},{"line_number":712,"context_line":"        footers \u003d {}"},{"line_number":713,"context_line":"        footer_callback \u003d req.environ.get("},{"line_number":714,"context_line":"            \u0027swift.update.footers\u0027, lambda _footers: None)"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_7939f5a3","line":711,"updated":"2016-04-06 13:54:30.000000000","message":"I noticed a TODO in the encrypter about removing the callback. Is that still the plan?\n\nhttps://github.com/openstack/swift/blob/feature/crypto/swift/common/middleware/encrypter.py#L91","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e036c9866f64cf1ad9205134791580bbc434d10b","unresolved":false,"context_lines":[{"line_number":708,"context_line":"                                  {\u0027conns\u0027: len(conns), \u0027nodes\u0027: min_conns})"},{"line_number":709,"context_line":"            raise HTTPServiceUnavailable(request\u003dreq)"},{"line_number":710,"context_line":""},{"line_number":711,"context_line":"    def _get_footers(self, req):"},{"line_number":712,"context_line":"        footers \u003d {}"},{"line_number":713,"context_line":"        footer_callback \u003d req.environ.get("},{"line_number":714,"context_line":"            \u0027swift.update.footers\u0027, lambda _footers: None)"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_880f5187","line":711,"in_reply_to":"9a061dce_7939f5a3","updated":"2016-04-06 17:22:32.000000000","message":"Nope we need it. What we have done here is to implement the same callback from the proxy controller as we had used with the FakeFooters middleware.\n\ngood spot, I\u0027ll remove the comment.","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3eca319851f8aa24c09aa521ecbe8438efcb3bde","unresolved":false,"context_lines":[{"line_number":708,"context_line":"                                  {\u0027conns\u0027: len(conns), \u0027nodes\u0027: min_conns})"},{"line_number":709,"context_line":"            raise HTTPServiceUnavailable(request\u003dreq)"},{"line_number":710,"context_line":""},{"line_number":711,"context_line":"    def _get_footers(self, req):"},{"line_number":712,"context_line":"        footers \u003d {}"},{"line_number":713,"context_line":"        footer_callback \u003d req.environ.get("},{"line_number":714,"context_line":"            \u0027swift.update.footers\u0027, lambda _footers: None)"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_f63987d8","line":711,"in_reply_to":"9a061dce_7939f5a3","updated":"2016-04-06 16:06:14.000000000","message":"no, the TODO is wrong. just needs to be removed.  since this review wasn\u0027t touching that file, the comment is removed in another patch that mahati worked on.","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"1391e024cd2b3d591ada3244042ad7dcc871db22","unresolved":false,"context_lines":[{"line_number":713,"context_line":"        footer_callback \u003d req.environ.get("},{"line_number":714,"context_line":"            \u0027swift.update.footers\u0027, lambda _footers: None)"},{"line_number":715,"context_line":"        footer_callback(footers)"},{"line_number":716,"context_line":"        # TODO - remove log when things are more stable"},{"line_number":717,"context_line":"        self.app.logger.debug(\u0027Footers are %s\u0027 % footers)"},{"line_number":718,"context_line":"        return footers"},{"line_number":719,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_f3270210","line":716,"updated":"2016-04-06 03:27:41.000000000","message":"remove comment or both comment and the logging.","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e036c9866f64cf1ad9205134791580bbc434d10b","unresolved":false,"context_lines":[{"line_number":713,"context_line":"        footer_callback \u003d req.environ.get("},{"line_number":714,"context_line":"            \u0027swift.update.footers\u0027, lambda _footers: None)"},{"line_number":715,"context_line":"        footer_callback(footers)"},{"line_number":716,"context_line":"        # TODO - remove log when things are more stable"},{"line_number":717,"context_line":"        self.app.logger.debug(\u0027Footers are %s\u0027 % footers)"},{"line_number":718,"context_line":"        return footers"},{"line_number":719,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_b35606cc","line":716,"in_reply_to":"9a061dce_f3270210","updated":"2016-04-06 17:22:32.000000000","message":"Done","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"1391e024cd2b3d591ada3244042ad7dcc871db22","unresolved":false,"context_lines":[{"line_number":1020,"context_line":"                    raise HTTPClientDisconnect(request\u003dreq)"},{"line_number":1021,"context_line":""},{"line_number":1022,"context_line":"                # TODO - Why was this needed? It makes things break"},{"line_number":1023,"context_line":"                # send_chunk(\u0027\u0027)  # flush out any buffered data"},{"line_number":1024,"context_line":""},{"line_number":1025,"context_line":"                for putter in putters:"},{"line_number":1026,"context_line":"                    # send any footers set by middleware"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_53998e1e","line":1023,"updated":"2016-04-06 03:27:41.000000000","message":"things are pretty different now than how things were when this had been patterned after EC flow.  Maybe there is nothing to look into here.  remove TODO if you agree.","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e036c9866f64cf1ad9205134791580bbc434d10b","unresolved":false,"context_lines":[{"line_number":1020,"context_line":"                    raise HTTPClientDisconnect(request\u003dreq)"},{"line_number":1021,"context_line":""},{"line_number":1022,"context_line":"                # TODO - Why was this needed? It makes things break"},{"line_number":1023,"context_line":"                # send_chunk(\u0027\u0027)  # flush out any buffered data"},{"line_number":1024,"context_line":""},{"line_number":1025,"context_line":"                for putter in putters:"},{"line_number":1026,"context_line":"                    # send any footers set by middleware"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_6c8f682a","line":1023,"in_reply_to":"9a061dce_53998e1e","updated":"2016-04-06 17:22:32.000000000","message":"OK I am satisfied this is not required. In the EC controller, the send_chunk method may buffer part of a chunk and not actually send it to the putter queue when there is not enough chunk data to form an EC fragment. So the final send_chunk(\u0027\u0027) triggers send_chunk (or the chunk transformer) to flush out any remaining data to the putter queue.\n\nWith a replicated obj controller there is no such buffering so every send_chunk ends up putting the chunk onto the putter queues.","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"1391e024cd2b3d591ada3244042ad7dcc871db22","unresolved":false,"context_lines":[{"line_number":1025,"context_line":"                for putter in putters:"},{"line_number":1026,"context_line":"                    # send any footers set by middleware"},{"line_number":1027,"context_line":"                    trail_md \u003d self._get_footers(req)"},{"line_number":1028,"context_line":"                    # TODO - remove log when things are more stable"},{"line_number":1029,"context_line":"                    self.app.logger.debug(\u0027trail_md is %s\u0027 % trail_md)"},{"line_number":1030,"context_line":"                    putter.end_of_object_data(footer_metadata\u003dtrail_md)"},{"line_number":1031,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_53c06ee0","line":1028,"updated":"2016-04-06 03:27:41.000000000","message":"same here - remove TODO or both TODO and the logging","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e036c9866f64cf1ad9205134791580bbc434d10b","unresolved":false,"context_lines":[{"line_number":1025,"context_line":"                for putter in putters:"},{"line_number":1026,"context_line":"                    # send any footers set by middleware"},{"line_number":1027,"context_line":"                    trail_md \u003d self._get_footers(req)"},{"line_number":1028,"context_line":"                    # TODO - remove log when things are more stable"},{"line_number":1029,"context_line":"                    self.app.logger.debug(\u0027trail_md is %s\u0027 % trail_md)"},{"line_number":1030,"context_line":"                    putter.end_of_object_data(footer_metadata\u003dtrail_md)"},{"line_number":1031,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_732e2e44","line":1028,"in_reply_to":"9a061dce_53c06ee0","updated":"2016-04-06 17:22:32.000000000","message":"Done","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"51fb946fddfeec0a9b8d2f89b7da597b0f09ad95","unresolved":false,"context_lines":[{"line_number":1767,"context_line":"        self.conn.close()"},{"line_number":1768,"context_line":""},{"line_number":1769,"context_line":"    @classmethod"},{"line_number":1770,"context_line":"    def _make_connection(cls, node, part, req, headers, conn_timeout,"},{"line_number":1771,"context_line":"                         node_timeout):"},{"line_number":1772,"context_line":"        start_time \u003d time.time()"},{"line_number":1773,"context_line":"        with ConnectionTimeout(conn_timeout):"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_f9b18548","line":1770,"updated":"2016-04-06 13:54:30.000000000","message":"I\u0027d suggest removing this method and just moving the code into connect()","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e036c9866f64cf1ad9205134791580bbc434d10b","unresolved":false,"context_lines":[{"line_number":1767,"context_line":"        self.conn.close()"},{"line_number":1768,"context_line":""},{"line_number":1769,"context_line":"    @classmethod"},{"line_number":1770,"context_line":"    def _make_connection(cls, node, part, req, headers, conn_timeout,"},{"line_number":1771,"context_line":"                         node_timeout):"},{"line_number":1772,"context_line":"        start_time \u003d time.time()"},{"line_number":1773,"context_line":"        with ConnectionTimeout(conn_timeout):"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_b333a661","line":1770,"in_reply_to":"9a061dce_f9b18548","updated":"2016-04-06 17:22:32.000000000","message":"This method is called from both the Putter.connect and MIMEPutter.connect methods so I split it out like this to avoid duplication.\n\nI first looked at having this code in Putter.connect and having MIMEPutter.connect() call the superclass Putter.connect, but because they are class methods the return value ends up being Putter in both cases. So I ended up with this approach.","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"30cda7a273fa3d36919a3cf2670919ad5c8bff32","unresolved":false,"context_lines":[{"line_number":1767,"context_line":"        self.conn.close()"},{"line_number":1768,"context_line":""},{"line_number":1769,"context_line":"    @classmethod"},{"line_number":1770,"context_line":"    def _make_connection(cls, node, part, req, headers, conn_timeout,"},{"line_number":1771,"context_line":"                         node_timeout):"},{"line_number":1772,"context_line":"        start_time \u003d time.time()"},{"line_number":1773,"context_line":"        with ConnectionTimeout(conn_timeout):"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_a52ebb40","line":1770,"in_reply_to":"9a061dce_f9b18548","updated":"2016-04-06 15:28:28.000000000","message":"please disregard this as it is being called from MIMEPutter connect method too","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"1391e024cd2b3d591ada3244042ad7dcc871db22","unresolved":false,"context_lines":[{"line_number":2376,"context_line":"                    trail_md.update(self._get_footers(req))"},{"line_number":2377,"context_line":"                    # but Etag must always be hash of what we sent"},{"line_number":2378,"context_line":"                    trail_md[\u0027Etag\u0027] \u003d \\"},{"line_number":2379,"context_line":"                        putter.chunk_hasher.hexdigest()"},{"line_number":2380,"context_line":"                    # TODO - remove log when things are more stable"},{"line_number":2381,"context_line":"                    self.app.logger.debug(\u0027trail_md is %s\u0027 % trail_md)"},{"line_number":2382,"context_line":"                    putter.end_of_object_data(footer_metadata\u003dtrail_md)"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_56997c1e","line":2379,"updated":"2016-04-06 03:27:41.000000000","message":"In the older version, there was the following\n\nif ec_etag:\n    crypto_md.update({\u0027X-Object-Sysmeta-EC-Etag\u0027: crypto_etag})\n\nThis is because this etag is used for if-match.  It needs to be the crypto_etag in the case of EC.  This is the encrypted plaintext - not the ciphertext.\n\nThis probably needs to be asserted somewhere in the unit tests.","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"48ce5060959c6cb2354b8fe9750ac92b43b1bfac","unresolved":false,"context_lines":[{"line_number":2376,"context_line":"                    trail_md.update(self._get_footers(req))"},{"line_number":2377,"context_line":"                    # but Etag must always be hash of what we sent"},{"line_number":2378,"context_line":"                    trail_md[\u0027Etag\u0027] \u003d \\"},{"line_number":2379,"context_line":"                        putter.chunk_hasher.hexdigest()"},{"line_number":2380,"context_line":"                    # TODO - remove log when things are more stable"},{"line_number":2381,"context_line":"                    self.app.logger.debug(\u0027trail_md is %s\u0027 % trail_md)"},{"line_number":2382,"context_line":"                    putter.end_of_object_data(footer_metadata\u003dtrail_md)"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_dd2d7747","line":2379,"in_reply_to":"9a061dce_424515b1","updated":"2016-04-06 19:30:47.000000000","message":"This EC-Etag had been mentioned in the if-match review.  Line https://github.com/openstack/swift/blob/master/swift/proxy/controllers/obj.py#L2005 was referred to, and the question was asked would this not override the X-Backend-Etag-Is-At set by our middleware.","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e036c9866f64cf1ad9205134791580bbc434d10b","unresolved":false,"context_lines":[{"line_number":2376,"context_line":"                    trail_md.update(self._get_footers(req))"},{"line_number":2377,"context_line":"                    # but Etag must always be hash of what we sent"},{"line_number":2378,"context_line":"                    trail_md[\u0027Etag\u0027] \u003d \\"},{"line_number":2379,"context_line":"                        putter.chunk_hasher.hexdigest()"},{"line_number":2380,"context_line":"                    # TODO - remove log when things are more stable"},{"line_number":2381,"context_line":"                    self.app.logger.debug(\u0027trail_md is %s\u0027 % trail_md)"},{"line_number":2382,"context_line":"                    putter.end_of_object_data(footer_metadata\u003dtrail_md)"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_424515b1","line":2379,"in_reply_to":"9a061dce_56997c1e","updated":"2016-04-06 17:22:32.000000000","message":"We should not be over-writing an EC piece of metadata with crypto metadata. EC uses this sysmeta-ec-etag to group fragment responses during EC get. That would probably still work so long as the value is consistent across all fragments but there may be other code paths (and definitely humans) that expect sysmeta-ec-etag to be the hash of the data prior to Erasure coding.\n\nThe way to do if-match is to use X-Backend-Etag-Is-At to redirect the etag comparison in object server. See swift.proxy.controllers.obj.ECObjectController#_get_or_head_response for an example how this is done. So we\u0027d have (in a follow on patch for conditional GETs):\n\n  req.headers.setdefault(\"X-Backend-Etag-Is-At\",\n                               \"X-Object-Sysmeta-Crypto-Etag\")","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"51fb946fddfeec0a9b8d2f89b7da597b0f09ad95","unresolved":false,"context_lines":[{"line_number":2376,"context_line":"                    trail_md.update(self._get_footers(req))"},{"line_number":2377,"context_line":"                    # but Etag must always be hash of what we sent"},{"line_number":2378,"context_line":"                    trail_md[\u0027Etag\u0027] \u003d \\"},{"line_number":2379,"context_line":"                        putter.chunk_hasher.hexdigest()"},{"line_number":2380,"context_line":"                    # TODO - remove log when things are more stable"},{"line_number":2381,"context_line":"                    self.app.logger.debug(\u0027trail_md is %s\u0027 % trail_md)"},{"line_number":2382,"context_line":"                    putter.end_of_object_data(footer_metadata\u003dtrail_md)"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_b9338d61","line":2379,"in_reply_to":"9a061dce_56997c1e","updated":"2016-04-06 13:54:30.000000000","message":"can this be added in the get_footer callback?","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"3eca319851f8aa24c09aa521ecbe8438efcb3bde","unresolved":false,"context_lines":[{"line_number":2376,"context_line":"                    trail_md.update(self._get_footers(req))"},{"line_number":2377,"context_line":"                    # but Etag must always be hash of what we sent"},{"line_number":2378,"context_line":"                    trail_md[\u0027Etag\u0027] \u003d \\"},{"line_number":2379,"context_line":"                        putter.chunk_hasher.hexdigest()"},{"line_number":2380,"context_line":"                    # TODO - remove log when things are more stable"},{"line_number":2381,"context_line":"                    self.app.logger.debug(\u0027trail_md is %s\u0027 % trail_md)"},{"line_number":2382,"context_line":"                    putter.end_of_object_data(footer_metadata\u003dtrail_md)"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_b6442f1b","line":2379,"in_reply_to":"9a061dce_b9338d61","updated":"2016-04-06 16:06:14.000000000","message":"the only thing is you probably dont want it there unless you are running with EC - i guess you could add that check into the cyrpto mw","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"b905fb4dd9a4cd1e4b871970ebfd7e45bea9e7d5","unresolved":false,"context_lines":[{"line_number":2376,"context_line":"                    trail_md.update(self._get_footers(req))"},{"line_number":2377,"context_line":"                    # but Etag must always be hash of what we sent"},{"line_number":2378,"context_line":"                    trail_md[\u0027Etag\u0027] \u003d \\"},{"line_number":2379,"context_line":"                        putter.chunk_hasher.hexdigest()"},{"line_number":2380,"context_line":"                    # TODO - remove log when things are more stable"},{"line_number":2381,"context_line":"                    self.app.logger.debug(\u0027trail_md is %s\u0027 % trail_md)"},{"line_number":2382,"context_line":"                    putter.end_of_object_data(footer_metadata\u003dtrail_md)"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_ccdf8a38","line":2379,"in_reply_to":"9a061dce_dd2d7747","updated":"2016-04-06 20:21:46.000000000","message":"setdefault() would only sets X-Backend-Etag-Is-At if it is not already set.","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"1391e024cd2b3d591ada3244042ad7dcc871db22","unresolved":false,"context_lines":[{"line_number":2377,"context_line":"                    # but Etag must always be hash of what we sent"},{"line_number":2378,"context_line":"                    trail_md[\u0027Etag\u0027] \u003d \\"},{"line_number":2379,"context_line":"                        putter.chunk_hasher.hexdigest()"},{"line_number":2380,"context_line":"                    # TODO - remove log when things are more stable"},{"line_number":2381,"context_line":"                    self.app.logger.debug(\u0027trail_md is %s\u0027 % trail_md)"},{"line_number":2382,"context_line":"                    putter.end_of_object_data(footer_metadata\u003dtrail_md)"},{"line_number":2383,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_36ca086e","line":2380,"updated":"2016-04-06 03:27:41.000000000","message":"again - remove comment or log and comment","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e036c9866f64cf1ad9205134791580bbc434d10b","unresolved":false,"context_lines":[{"line_number":2377,"context_line":"                    # but Etag must always be hash of what we sent"},{"line_number":2378,"context_line":"                    trail_md[\u0027Etag\u0027] \u003d \\"},{"line_number":2379,"context_line":"                        putter.chunk_hasher.hexdigest()"},{"line_number":2380,"context_line":"                    # TODO - remove log when things are more stable"},{"line_number":2381,"context_line":"                    self.app.logger.debug(\u0027trail_md is %s\u0027 % trail_md)"},{"line_number":2382,"context_line":"                    putter.end_of_object_data(footer_metadata\u003dtrail_md)"},{"line_number":2383,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_421cf5c0","line":2380,"in_reply_to":"9a061dce_36ca086e","updated":"2016-04-06 17:22:32.000000000","message":"Done","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"03007825fb622f87da606c0d48e38213e21a57a8","unresolved":false,"context_lines":[{"line_number":910,"context_line":"                    conn.node \u003d node"},{"line_number":911,"context_line":"                    return conn"},{"line_number":912,"context_line":"                elif resp.status \u003d\u003d HTTP_INSUFFICIENT_STORAGE:"},{"line_number":913,"context_line":"                    self.app.error_limit(node, _(\u0027ERROR Insufficient Storage\u0027))"},{"line_number":914,"context_line":"                elif is_server_error(resp.status):"},{"line_number":915,"context_line":"                    self.app.error_occurred("},{"line_number":916,"context_line":"                        node,"}],"source_content_type":"text/x-python","patch_set":26,"id":"9a061dce_accdfb32","side":"PARENT","line":913,"range":{"start_line":913,"start_character":20,"end_line":913,"end_character":79},"updated":"2016-04-06 20:57:11.000000000","message":"ok, so this is now handled in _connect_put_node","commit_id":"a4645cf27c77b120db2bcf5724245ab1d18c49e5"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"03007825fb622f87da606c0d48e38213e21a57a8","unresolved":false,"context_lines":[{"line_number":1785,"context_line":""},{"line_number":1786,"context_line":"        # make sure this isn\u0027t there"},{"line_number":1787,"context_line":"        headers.pop(\u0027Content-Length\u0027)"},{"line_number":1788,"context_line":"        headers[\u0027X-Backend-Obj-Content-Length\u0027] \u003d expected_frag_archive_size"},{"line_number":1789,"context_line":""},{"line_number":1790,"context_line":"        headers[\u0027X-Backend-Obj-Multipart-Mime-Boundary\u0027] \u003d mime_boundary"},{"line_number":1791,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"9a061dce_72ed7ab6","side":"PARENT","line":1788,"updated":"2016-04-06 20:57:11.000000000","message":"moved to _make_putter","commit_id":"a4645cf27c77b120db2bcf5724245ab1d18c49e5"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"03007825fb622f87da606c0d48e38213e21a57a8","unresolved":false,"context_lines":[{"line_number":1646,"context_line":"        self.connect_duration \u003d connect_duration"},{"line_number":1647,"context_line":"        # for handoff nodes node_index is None"},{"line_number":1648,"context_line":"        self.node_index \u003d node.get(\u0027index\u0027)"},{"line_number":1649,"context_line":"        self.chunk_hasher \u003d md5()"},{"line_number":1650,"context_line":""},{"line_number":1651,"context_line":"        self.failed \u003d False"},{"line_number":1652,"context_line":"        self.queue \u003d None"}],"source_content_type":"text/x-python","patch_set":26,"id":"9a061dce_1797d03a","line":1649,"updated":"2016-04-06 20:57:11.000000000","message":"wondering if this could be moved to MIMEPutter.","commit_id":"89bee5c677ee85977d34f894cdccef155d9f1cca"}],"test/unit/proxy/controllers/test_obj.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":2495,"context_line":""},{"line_number":2496,"context_line":"@patch_policies()"},{"line_number":2497,"context_line":"class TestCryptoReplObjController(BaseObjectControllerMixin,"},{"line_number":2498,"context_line":"                                  unittest.TestCase):"},{"line_number":2499,"context_line":""},{"line_number":2500,"context_line":"    container_info \u003d {"},{"line_number":2501,"context_line":"        \u0027read_acl\u0027: None,"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_39940b36","line":2498,"updated":"2016-04-04 18:38:27.000000000","message":"extending BaseObjectControllerMixin causes ALL the inherited test methods to be repeated. Better to add the new tests to the existing concrete test classes.","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":2507,"context_line":""},{"line_number":2508,"context_line":"    controller_cls \u003d obj.ReplicatedObjectController"},{"line_number":2509,"context_line":""},{"line_number":2510,"context_line":"    def test_PUT_simple_with_footers(self):"},{"line_number":2511,"context_line":"        env \u003d {\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027,"},{"line_number":2512,"context_line":"               \u0027swift.update.footers\u0027: self.footers_callback}"},{"line_number":2513,"context_line":"        req \u003d swift.common.swob.Request.blank(\u0027/v1/a/c/o\u0027, method\u003d\u0027PUT\u0027,"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_d9ca2f4f","line":2510,"updated":"2016-04-04 18:38:27.000000000","message":"does this add anything beyond test_PUT_with_body_and_footers? just wondering if we can simplify down to the one test.","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ab8f90d6065238601a894a9b653ff32ca668890","unresolved":false,"context_lines":[{"line_number":2535,"context_line":""},{"line_number":2536,"context_line":"        with set_http_connect(*codes, expect_headers\u003dexpect_headers):"},{"line_number":2537,"context_line":"            resp \u003d req.get_response(self.app)"},{"line_number":2538,"context_line":"        self.assertEqual(resp.status_int, 503)"},{"line_number":2539,"context_line":""},{"line_number":2540,"context_line":"    def test_PUT_with_body_and_footers(self):"},{"line_number":2541,"context_line":"        env \u003d {\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027,"}],"source_content_type":"text/x-python","patch_set":22,"id":"9a061dce_f9aa936f","line":2538,"updated":"2016-04-04 18:38:27.000000000","message":"what does this check beyond existing tests?","commit_id":"744d23f71a8bba6afe98f8f29aa9d3dcd5e72d36"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"1391e024cd2b3d591ada3244042ad7dcc871db22","unresolved":false,"context_lines":[{"line_number":105,"context_line":"    # TODO - change when cont_etag is encrypted"},{"line_number":106,"context_line":"    cont_etag \u003d \u002720242af0cd21dd7195a10483eb7472c9\u0027"},{"line_number":107,"context_line":"    crypto_etag \u003d \u002720242af0cd21dd7195a10483eb7472c9\u0027"},{"line_number":108,"context_line":"    # cont_ct \u003d \u002782136b4240d6ce4ea7d03e51469a393b\u0027"},{"line_number":109,"context_line":"    etag_crypto_meta \u003d \\"},{"line_number":110,"context_line":"        \u0027{\"cipher\": \"AES_CTR_256\", \"iv\": \"sD+PSw/DfqYwpsVGSo0GEw\u003d\u003d\"}\u0027"},{"line_number":111,"context_line":"    etag \u003d md5(body).hexdigest()"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_36acc833","line":108,"updated":"2016-04-06 03:27:41.000000000","message":"remove the commented-out line","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e036c9866f64cf1ad9205134791580bbc434d10b","unresolved":false,"context_lines":[{"line_number":105,"context_line":"    # TODO - change when cont_etag is encrypted"},{"line_number":106,"context_line":"    cont_etag \u003d \u002720242af0cd21dd7195a10483eb7472c9\u0027"},{"line_number":107,"context_line":"    crypto_etag \u003d \u002720242af0cd21dd7195a10483eb7472c9\u0027"},{"line_number":108,"context_line":"    # cont_ct \u003d \u002782136b4240d6ce4ea7d03e51469a393b\u0027"},{"line_number":109,"context_line":"    etag_crypto_meta \u003d \\"},{"line_number":110,"context_line":"        \u0027{\"cipher\": \"AES_CTR_256\", \"iv\": \"sD+PSw/DfqYwpsVGSo0GEw\u003d\u003d\"}\u0027"},{"line_number":111,"context_line":"    etag \u003d md5(body).hexdigest()"}],"source_content_type":"text/x-python","patch_set":25,"id":"9a061dce_51483dcc","line":108,"in_reply_to":"9a061dce_36acc833","updated":"2016-04-06 17:22:32.000000000","message":"Done","commit_id":"ef85abfae070f7d56f56884b74b2a115a595b490"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"03007825fb622f87da606c0d48e38213e21a57a8","unresolved":false,"context_lines":[{"line_number":560,"context_line":"            resp \u003d req.get_response(self.app)"},{"line_number":561,"context_line":"        self.assertEqual(resp.status_int, 201)"},{"line_number":562,"context_line":""},{"line_number":563,"context_line":"    def test_PUT_simple_with_no_footers(self):"},{"line_number":564,"context_line":"        footers_callback \u003d make_footers_callback(\u0027\u0027)"},{"line_number":565,"context_line":"        env \u003d {\u0027swift.update.footers\u0027: footers_callback}"},{"line_number":566,"context_line":"        req \u003d swift.common.swob.Request.blank(\u0027/v1/a/c/o\u0027, method\u003d\u0027PUT\u0027,"}],"source_content_type":"text/x-python","patch_set":26,"id":"9a061dce_6cb75e3a","line":563,"range":{"start_line":563,"start_character":29,"end_line":563,"end_character":39},"updated":"2016-04-06 20:57:11.000000000","message":"no_footers?","commit_id":"89bee5c677ee85977d34f894cdccef155d9f1cca"}]}
