)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"5d58cab4dec1adc7179eaf76c7de58b1b5bcef9e","unresolved":false,"context_lines":[{"line_number":11,"context_line":"requests. The main reasoning for this change is to remove any"},{"line_number":12,"context_line":"dependency that versioning had on copy, which will allow for the COPY"},{"line_number":13,"context_line":"functionality to be moved to middleware and to be to the left of the"},{"line_number":14,"context_line":"versioned writes middleware in the proxy pipeline. In this way,"},{"line_number":15,"context_line":"no COPY request will ever arrive at the versioned writes middleware."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"A side benefit of this change is that it removes a HEAD request from"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"9a68dd71_9e7da91e","line":14,"updated":"2016-01-21 13:42:22.000000000","message":"Is getting rid of the copy hooks the only benefit from this ? Or is there a dependency for this for encryption feature ?","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"570f22e7a7691569a046b81db47c26755c6cca71","unresolved":false,"context_lines":[{"line_number":11,"context_line":"requests. The main reasoning for this change is to remove any"},{"line_number":12,"context_line":"dependency that versioning had on copy, which will allow for the COPY"},{"line_number":13,"context_line":"functionality to be moved to middleware and to be to the left of the"},{"line_number":14,"context_line":"versioned writes middleware in the proxy pipeline. In this way,"},{"line_number":15,"context_line":"no COPY request will ever arrive at the versioned writes middleware."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"A side benefit of this change is that it removes a HEAD request from"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"9a68dd71_d265031e","line":14,"in_reply_to":"9a68dd71_0284f7d1","updated":"2016-02-12 21:50:42.000000000","message":"Janie, correct. that is my understanding as well.","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"8780bf365ca12e8f334a9fe83b0d1526cdb3abe9","unresolved":false,"context_lines":[{"line_number":11,"context_line":"requests. The main reasoning for this change is to remove any"},{"line_number":12,"context_line":"dependency that versioning had on copy, which will allow for the COPY"},{"line_number":13,"context_line":"functionality to be moved to middleware and to be to the left of the"},{"line_number":14,"context_line":"versioned writes middleware in the proxy pipeline. In this way,"},{"line_number":15,"context_line":"no COPY request will ever arrive at the versioned writes middleware."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"A side benefit of this change is that it removes a HEAD request from"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"9a68dd71_0284f7d1","line":14,"in_reply_to":"9a68dd71_9e7da91e","updated":"2016-01-21 15:25:59.000000000","message":"encryption is only dependent on this as it needs COPY as middleware.  There is no hook for encryption at the moment, and creating one may cause some refactoring and a bit of a mess.  So, the root of the dependency on COPY as mw is so that we don\u0027t have a need to write a copy hook.","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"}],"swift/common/middleware/versioned_writes.py":[{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"5d58cab4dec1adc7179eaf76c7de58b1b5bcef9e","unresolved":false,"context_lines":[{"line_number":117,"context_line":""},{"line_number":118,"context_line":"import json"},{"line_number":119,"context_line":"import six"},{"line_number":120,"context_line":"from StringIO import StringIO"},{"line_number":121,"context_line":"from six.moves.urllib.parse import quote, unquote"},{"line_number":122,"context_line":"import time"},{"line_number":123,"context_line":"from swift.common.utils import get_logger, Timestamp, \\"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_3e16fda7","line":120,"range":{"start_line":120,"start_character":0,"end_line":120,"end_character":29},"updated":"2016-01-21 13:42:22.000000000","message":"Prefer using BytesIO from six module","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"570f22e7a7691569a046b81db47c26755c6cca71","unresolved":false,"context_lines":[{"line_number":117,"context_line":""},{"line_number":118,"context_line":"import json"},{"line_number":119,"context_line":"import six"},{"line_number":120,"context_line":"from StringIO import StringIO"},{"line_number":121,"context_line":"from six.moves.urllib.parse import quote, unquote"},{"line_number":122,"context_line":"import time"},{"line_number":123,"context_line":"from swift.common.utils import get_logger, Timestamp, \\"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_787829f9","line":120,"range":{"start_line":120,"start_character":0,"end_line":120,"end_character":29},"in_reply_to":"9a68dd71_3e16fda7","updated":"2016-02-12 21:50:42.000000000","message":"Done","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"2c1789131b5b31efcb7a196c490a40562041f62a","unresolved":false,"context_lines":[{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    def _get_source_object(self, req, path_info):"},{"line_number":189,"context_line":"        # make a GET request to check object versions"},{"line_number":190,"context_line":"        _headers \u003d {\u0027X-Newest\u0027: \u0027True\u0027,"},{"line_number":191,"context_line":"                    \u0027x-auth-token\u0027: req.headers.get(\u0027x-auth-token\u0027)}"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"        # make a pre_auth request in case the user has write access"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a7b0d38_12bd2a68","line":190,"range":{"start_line":190,"start_character":23,"end_line":190,"end_character":29},"updated":"2015-12-24 03:21:39.000000000","message":"Just a question to educate me: Why is the policy_index header needed for a HEAD, but not for a GET?","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5766521495e5226949fd064b49fc57a82d3956bb","unresolved":false,"context_lines":[{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    def _get_source_object(self, req, path_info):"},{"line_number":189,"context_line":"        # make a GET request to check object versions"},{"line_number":190,"context_line":"        _headers \u003d {\u0027X-Newest\u0027: \u0027True\u0027,"},{"line_number":191,"context_line":"                    \u0027x-auth-token\u0027: req.headers.get(\u0027x-auth-token\u0027)}"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"        # make a pre_auth request in case the user has write access"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_cf19e3d8","line":190,"range":{"start_line":190,"start_character":23,"end_line":190,"end_character":29},"in_reply_to":"1a7b0d38_12bd2a68","updated":"2016-01-22 17:00:58.000000000","message":"I am confused by this too - was the policy index ever needed here? does the HEAD method in proxy obj controller not insert it?","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"570f22e7a7691569a046b81db47c26755c6cca71","unresolved":false,"context_lines":[{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    def _get_source_object(self, req, path_info):"},{"line_number":189,"context_line":"        # make a GET request to check object versions"},{"line_number":190,"context_line":"        _headers \u003d {\u0027X-Newest\u0027: \u0027True\u0027,"},{"line_number":191,"context_line":"                    \u0027x-auth-token\u0027: req.headers.get(\u0027x-auth-token\u0027)}"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"        # make a pre_auth request in case the user has write access"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a57f1b5_231501e4","line":190,"range":{"start_line":190,"start_character":23,"end_line":190,"end_character":29},"in_reply_to":"9a68dd71_cf19e3d8","updated":"2016-02-12 21:50:42.000000000","message":"Alistair, I don\u0027t think this was ever needed. the GETorHEAD method in the proxy obj controller will get it from container_info: https://github.com/openstack/swift/blob/master/swift/proxy/controllers/obj.py#L189,L191","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5766521495e5226949fd064b49fc57a82d3956bb","unresolved":false,"context_lines":[{"line_number":192,"context_line":""},{"line_number":193,"context_line":"        # make a pre_auth request in case the user has write access"},{"line_number":194,"context_line":"        # to container, but not READ. This was allowed in previous version"},{"line_number":195,"context_line":"        # (i.e., before middleware) so keeping the same behavior here"},{"line_number":196,"context_line":"        get_req \u003d make_pre_authed_request("},{"line_number":197,"context_line":"            req.environ, path\u003dpath_info,"},{"line_number":198,"context_line":"            headers\u003d_headers, method\u003d\u0027GET\u0027, swift_source\u003d\u0027VW\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_ef2dc7a8","line":195,"updated":"2016-01-22 17:00:58.000000000","message":"was that true in both direction i.e. reading from the target container or the versions container?","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5766521495e5226949fd064b49fc57a82d3956bb","unresolved":false,"context_lines":[{"line_number":202,"context_line":"            # This indicates a transfer-encoding: chunked source object,"},{"line_number":203,"context_line":"            # which currently only happens because there are more than"},{"line_number":204,"context_line":"            # CONTAINER_LISTING_LIMIT segments in a segmented object. In"},{"line_number":205,"context_line":"            # this case, we\u0027re going to refuse to do the server-side copy."},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"            # TODO: Check if above comment is true and"},{"line_number":208,"context_line":"            # content_length can really be None."}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_4fdbb3ec","line":205,"updated":"2016-01-22 17:00:58.000000000","message":"But we don\u0027t want to ever resolve a *LO manifest so this should never happen?","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"570f22e7a7691569a046b81db47c26755c6cca71","unresolved":false,"context_lines":[{"line_number":202,"context_line":"            # This indicates a transfer-encoding: chunked source object,"},{"line_number":203,"context_line":"            # which currently only happens because there are more than"},{"line_number":204,"context_line":"            # CONTAINER_LISTING_LIMIT segments in a segmented object. In"},{"line_number":205,"context_line":"            # this case, we\u0027re going to refuse to do the server-side copy."},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"            # TODO: Check if above comment is true and"},{"line_number":208,"context_line":"            # content_length can really be None."}],"source_content_type":"text/x-python","patch_set":2,"id":"3a57f1b5_03f1e5cc","line":205,"in_reply_to":"9a68dd71_4fdbb3ec","updated":"2016-02-12 21:50:42.000000000","message":"Done","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5766521495e5226949fd064b49fc57a82d3956bb","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        put_req.etag \u003d source_resp.etag"},{"line_number":228,"context_line":"        put_req.headers[\u0027Content-Type\u0027] \u003d source_resp.headers[\u0027Content-Type\u0027]"},{"line_number":229,"context_line":""},{"line_number":230,"context_line":"        copy_headers_into(source_resp, put_req)"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"        # Copy over x-static-large-object for POSTs and manifest copies"},{"line_number":233,"context_line":"        if \u0027X-Static-Large-Object\u0027 in source_resp.headers and \\"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_c59d4967","line":230,"updated":"2016-01-22 17:00:58.000000000","message":"This worries me - i.e. the whitelist approach. There obj server has a list if allowed headers that is longer than the list used for copy_headers:\n            content-disposition,\n            content-encoding,\n            x-delete-at,\n            x-object-manifest,\n            x-static-large-object,\n\nI wonder if a black list approach would be better i.e. remove anything we know should not be copied?\n\nthat would remove the need for special handling of X-Static-Large-Object below too.\n\nI realise that master seems to do the same header copying, but this is a chance to understand if it is correct.","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"47e3f42f78954c5768b8d8ebd9c9dfb0b07d4189","unresolved":false,"context_lines":[{"line_number":229,"context_line":""},{"line_number":230,"context_line":"        copy_headers_into(source_resp, put_req)"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"        # Copy over x-static-large-object for POSTs and manifest copies"},{"line_number":233,"context_line":"        if \u0027X-Static-Large-Object\u0027 in source_resp.headers and \\"},{"line_number":234,"context_line":"                (req.params.get(\u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027 or"},{"line_number":235,"context_line":"                 \u0027swift.post_as_copy\u0027 in req.environ):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_58875bb5","line":232,"updated":"2016-01-21 05:08:13.000000000","message":"the dlo copy hook has logic to preserve the \u0027X-Object-Manifest\u0027 header if present.  Granted, there is an issue now about what should happen with DLO under post-as-copy in patch 252791.  But I was wondering if the \u0027X-Object-Manifest\u0027 header needed to be addressed here as well?\n\nalong those lines, have you tested these changes under fast-post as well?","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5766521495e5226949fd064b49fc57a82d3956bb","unresolved":false,"context_lines":[{"line_number":229,"context_line":""},{"line_number":230,"context_line":"        copy_headers_into(source_resp, put_req)"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"        # Copy over x-static-large-object for POSTs and manifest copies"},{"line_number":233,"context_line":"        if \u0027X-Static-Large-Object\u0027 in source_resp.headers and \\"},{"line_number":234,"context_line":"                (req.params.get(\u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027 or"},{"line_number":235,"context_line":"                 \u0027swift.post_as_copy\u0027 in req.environ):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_6a47c04b","line":232,"in_reply_to":"9a68dd71_58875bb5","updated":"2016-01-22 17:00:58.000000000","message":"We don\u0027t get here for a DLO - see line 252.\n\nWe only get here for a PUT or COPY so I don\u0027t understand the comment referring to POSTs.","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"bf9e872dd626e345eb83d623aedc13446011245d","unresolved":false,"context_lines":[{"line_number":229,"context_line":""},{"line_number":230,"context_line":"        copy_headers_into(source_resp, put_req)"},{"line_number":231,"context_line":""},{"line_number":232,"context_line":"        # Copy over x-static-large-object for POSTs and manifest copies"},{"line_number":233,"context_line":"        if \u0027X-Static-Large-Object\u0027 in source_resp.headers and \\"},{"line_number":234,"context_line":"                (req.params.get(\u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027 or"},{"line_number":235,"context_line":"                 \u0027swift.post_as_copy\u0027 in req.environ):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_bca13448","line":232,"in_reply_to":"9a68dd71_6a47c04b","updated":"2016-01-23 03:58:16.000000000","message":"Oh, right - I hadn\u0027t noticed the dlo manifest was ignored for versioning until later.  As for my comment: it was only referring to the copy_hook and post_as_copy handling that seemed related.  Below, there is a case for slo and swift.post_as_copy.","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5766521495e5226949fd064b49fc57a82d3956bb","unresolved":false,"context_lines":[{"line_number":232,"context_line":"        # Copy over x-static-large-object for POSTs and manifest copies"},{"line_number":233,"context_line":"        if \u0027X-Static-Large-Object\u0027 in source_resp.headers and \\"},{"line_number":234,"context_line":"                (req.params.get(\u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027 or"},{"line_number":235,"context_line":"                 \u0027swift.post_as_copy\u0027 in req.environ):"},{"line_number":236,"context_line":"            put_req.headers[\u0027X-Static-Large-Object\u0027] \u003d \\"},{"line_number":237,"context_line":"                source_resp.headers[\u0027X-Static-Large-Object\u0027]"},{"line_number":238,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_8a97948f","line":235,"updated":"2016-01-22 17:00:58.000000000","message":"swift.post_as_copy is set in the proxy obj controller so would never be set here? The request has not yet reached the obj controller.","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"570f22e7a7691569a046b81db47c26755c6cca71","unresolved":false,"context_lines":[{"line_number":232,"context_line":"        # Copy over x-static-large-object for POSTs and manifest copies"},{"line_number":233,"context_line":"        if \u0027X-Static-Large-Object\u0027 in source_resp.headers and \\"},{"line_number":234,"context_line":"                (req.params.get(\u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027 or"},{"line_number":235,"context_line":"                 \u0027swift.post_as_copy\u0027 in req.environ):"},{"line_number":236,"context_line":"            put_req.headers[\u0027X-Static-Large-Object\u0027] \u003d \\"},{"line_number":237,"context_line":"                source_resp.headers[\u0027X-Static-Large-Object\u0027]"},{"line_number":238,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"3a57f1b5_63945942","line":235,"in_reply_to":"9a68dd71_8a97948f","updated":"2016-02-12 21:50:42.000000000","message":"Done","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5766521495e5226949fd064b49fc57a82d3956bb","unresolved":false,"context_lines":[{"line_number":234,"context_line":"                (req.params.get(\u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027 or"},{"line_number":235,"context_line":"                 \u0027swift.post_as_copy\u0027 in req.environ):"},{"line_number":236,"context_line":"            put_req.headers[\u0027X-Static-Large-Object\u0027] \u003d \\"},{"line_number":237,"context_line":"                source_resp.headers[\u0027X-Static-Large-Object\u0027]"},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"        return put_req.get_response(self.app)"},{"line_number":240,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_cc3331aa","line":237,"updated":"2016-01-22 17:00:58.000000000","message":"I think we just always want to copy this header if it exists - as discussed in IRC, we want to preserve slo manifests","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"570f22e7a7691569a046b81db47c26755c6cca71","unresolved":false,"context_lines":[{"line_number":234,"context_line":"                (req.params.get(\u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027 or"},{"line_number":235,"context_line":"                 \u0027swift.post_as_copy\u0027 in req.environ):"},{"line_number":236,"context_line":"            put_req.headers[\u0027X-Static-Large-Object\u0027] \u003d \\"},{"line_number":237,"context_line":"                source_resp.headers[\u0027X-Static-Large-Object\u0027]"},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"        return put_req.get_response(self.app)"},{"line_number":240,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"3a57f1b5_039fa55f","line":237,"in_reply_to":"9a68dd71_cc3331aa","updated":"2016-02-12 21:50:42.000000000","message":"Done","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5766521495e5226949fd064b49fc57a82d3956bb","unresolved":false,"context_lines":[{"line_number":240,"context_line":""},{"line_number":241,"context_line":"    def handle_obj_versions_put(self, req, object_versions,"},{"line_number":242,"context_line":"                                object_name):"},{"line_number":243,"context_line":"        ret \u003d None"},{"line_number":244,"context_line":""},{"line_number":245,"context_line":"        get_resp \u003d self._get_source_object(req, req.path_info)"},{"line_number":246,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_f2b7ec37","line":243,"updated":"2016-01-22 17:00:58.000000000","message":"ret re-defined later, this line can be deleted","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"570f22e7a7691569a046b81db47c26755c6cca71","unresolved":false,"context_lines":[{"line_number":240,"context_line":""},{"line_number":241,"context_line":"    def handle_obj_versions_put(self, req, object_versions,"},{"line_number":242,"context_line":"                                object_name):"},{"line_number":243,"context_line":"        ret \u003d None"},{"line_number":244,"context_line":""},{"line_number":245,"context_line":"        get_resp \u003d self._get_source_object(req, req.path_info)"},{"line_number":246,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"3a57f1b5_239ae16e","line":243,"in_reply_to":"9a68dd71_f2b7ec37","updated":"2016-02-12 21:50:42.000000000","message":"Done","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9d7bc1a70c267ad58da70e1367558eceb7187300","unresolved":false,"context_lines":[{"line_number":253,"context_line":"            lcontainer \u003d object_versions.split(\u0027/\u0027)[0]"},{"line_number":254,"context_line":"            prefix_len \u003d \u0027%03x\u0027 % len(object_name)"},{"line_number":255,"context_line":"            lprefix \u003d prefix_len + object_name + \u0027/\u0027"},{"line_number":256,"context_line":"            ts_source \u003d get_resp.environ.get(\u0027swift_x_timestamp\u0027)"},{"line_number":257,"context_line":"            if ts_source is None:"},{"line_number":258,"context_line":"                ts_source \u003d time.mktime(time.strptime("},{"line_number":259,"context_line":"                                        get_resp.headers[\u0027last-modified\u0027],"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_3e26ab15","line":256,"updated":"2016-01-22 18:19:34.000000000","message":"an EC GET response does not have \u0027swift_x_timestamp\u0027 in environ. (On master this response was from a HEAD, which always has \u0027swift_x_timestamp\u0027 in environ).\n\nThe fallback of using last-modified gives a timestamp rounded to nearest second which causes func tests to fail with EC policy :(\n\nI don\u0027t know why this didn\u0027t just use get_resp.headers.get(\u0027x-timestamp\u0027) historically.","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"570f22e7a7691569a046b81db47c26755c6cca71","unresolved":false,"context_lines":[{"line_number":253,"context_line":"            lcontainer \u003d object_versions.split(\u0027/\u0027)[0]"},{"line_number":254,"context_line":"            prefix_len \u003d \u0027%03x\u0027 % len(object_name)"},{"line_number":255,"context_line":"            lprefix \u003d prefix_len + object_name + \u0027/\u0027"},{"line_number":256,"context_line":"            ts_source \u003d get_resp.environ.get(\u0027swift_x_timestamp\u0027)"},{"line_number":257,"context_line":"            if ts_source is None:"},{"line_number":258,"context_line":"                ts_source \u003d time.mktime(time.strptime("},{"line_number":259,"context_line":"                                        get_resp.headers[\u0027last-modified\u0027],"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a57f1b5_43803df5","line":256,"in_reply_to":"9a68dd71_3e26ab15","updated":"2016-02-12 21:50:42.000000000","message":"Done","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5766521495e5226949fd064b49fc57a82d3956bb","unresolved":false,"context_lines":[{"line_number":279,"context_line":"                    ret \u003d HTTPServiceUnavailable(request\u003dreq)"},{"line_number":280,"context_line":""},{"line_number":281,"context_line":"        else:"},{"line_number":282,"context_line":"            if get_resp.status_int \u003d\u003d HTTP_NOT_FOUND or is_dlo_manifest:"},{"line_number":283,"context_line":"                # nothing to version"},{"line_number":284,"context_line":"                # return None and handle original request"},{"line_number":285,"context_line":"                ret \u003d None"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_ecab9573","line":282,"updated":"2016-01-22 17:00:58.000000000","message":"do we need to close the resp app_iter? perhaps using close_if_possible()","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"47e3f42f78954c5768b8d8ebd9c9dfb0b07d4189","unresolved":false,"context_lines":[{"line_number":315,"context_line":"            # current object and delete the previous version"},{"line_number":316,"context_line":"            prev_obj_name \u003d previous_version[\u0027name\u0027].encode(\u0027utf-8\u0027)"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"            (version, account, container, obj) \u003d req.split_path(3, 4, True)"},{"line_number":319,"context_line":"            get_path \u003d \"/%s/%s/%s/%s\" % ("},{"line_number":320,"context_line":"                version, account_name, lcontainer, prev_obj_name)"},{"line_number":321,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"ba63e191_acb70fd7","line":318,"updated":"2016-01-21 05:08:13.000000000","message":"Is this split_path only done in order to get the version?  If so, it seem like the calling method has the version from that same request and can pass it into this method (in the same spirit of how it passes account_name, container_name).","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"570f22e7a7691569a046b81db47c26755c6cca71","unresolved":false,"context_lines":[{"line_number":315,"context_line":"            # current object and delete the previous version"},{"line_number":316,"context_line":"            prev_obj_name \u003d previous_version[\u0027name\u0027].encode(\u0027utf-8\u0027)"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"            (version, account, container, obj) \u003d req.split_path(3, 4, True)"},{"line_number":319,"context_line":"            get_path \u003d \"/%s/%s/%s/%s\" % ("},{"line_number":320,"context_line":"                version, account_name, lcontainer, prev_obj_name)"},{"line_number":321,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"3a57f1b5_43cefd63","line":318,"in_reply_to":"ba63e191_acb70fd7","updated":"2016-02-12 21:50:42.000000000","message":"Done","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5766521495e5226949fd064b49fc57a82d3956bb","unresolved":false,"context_lines":[{"line_number":469,"context_line":"        if is_enabled and object_versions:"},{"line_number":470,"context_line":"            object_versions \u003d unquote(object_versions)"},{"line_number":471,"context_line":"            vw_ctx \u003d VersionedWritesContext(self.app, self.logger)"},{"line_number":472,"context_line":"            if req.method in (\u0027PUT\u0027, \u0027COPY\u0027):"},{"line_number":473,"context_line":"                resp \u003d vw_ctx.handle_obj_versions_put("},{"line_number":474,"context_line":"                    req, object_versions, object_name)"},{"line_number":475,"context_line":"            else:  # handle DELETE"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba63e191_908a7cbe","line":472,"updated":"2016-01-22 17:00:58.000000000","message":"ok. for time being we still have to accept handle COPY requests because we don\u0027t have COPY middleware yet","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"570f22e7a7691569a046b81db47c26755c6cca71","unresolved":false,"context_lines":[{"line_number":469,"context_line":"        if is_enabled and object_versions:"},{"line_number":470,"context_line":"            object_versions \u003d unquote(object_versions)"},{"line_number":471,"context_line":"            vw_ctx \u003d VersionedWritesContext(self.app, self.logger)"},{"line_number":472,"context_line":"            if req.method in (\u0027PUT\u0027, \u0027COPY\u0027):"},{"line_number":473,"context_line":"                resp \u003d vw_ctx.handle_obj_versions_put("},{"line_number":474,"context_line":"                    req, object_versions, object_name)"},{"line_number":475,"context_line":"            else:  # handle DELETE"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_75968194","line":472,"in_reply_to":"ba63e191_908a7cbe","updated":"2016-02-12 21:50:42.000000000","message":"good point","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"5d58cab4dec1adc7179eaf76c7de58b1b5bcef9e","unresolved":false,"context_lines":[{"line_number":514,"context_line":"                                              allow_versioned_writes)"},{"line_number":515,"context_line":"            except HTTPException as error_response:"},{"line_number":516,"context_line":"                return error_response(env, start_response)"},{"line_number":517,"context_line":"        elif obj and req.method in (\u0027PUT\u0027, \u0027COPY\u0027, \u0027DELETE\u0027):"},{"line_number":518,"context_line":"            try:"},{"line_number":519,"context_line":"                return self.object_request("},{"line_number":520,"context_line":"                    req, version, account, container, obj,"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_c4f4b488","line":517,"updated":"2016-01-21 13:42:22.000000000","message":"COPY requests no longer reach here. Same on line 439, 472 and 486","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"570f22e7a7691569a046b81db47c26755c6cca71","unresolved":false,"context_lines":[{"line_number":514,"context_line":"                                              allow_versioned_writes)"},{"line_number":515,"context_line":"            except HTTPException as error_response:"},{"line_number":516,"context_line":"                return error_response(env, start_response)"},{"line_number":517,"context_line":"        elif obj and req.method in (\u0027PUT\u0027, \u0027COPY\u0027, \u0027DELETE\u0027):"},{"line_number":518,"context_line":"            try:"},{"line_number":519,"context_line":"                return self.object_request("},{"line_number":520,"context_line":"                    req, version, account, container, obj,"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_d5ebad11","line":517,"in_reply_to":"9a68dd71_5bb09143","updated":"2016-02-12 21:50:42.000000000","message":"good points","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5766521495e5226949fd064b49fc57a82d3956bb","unresolved":false,"context_lines":[{"line_number":514,"context_line":"                                              allow_versioned_writes)"},{"line_number":515,"context_line":"            except HTTPException as error_response:"},{"line_number":516,"context_line":"                return error_response(env, start_response)"},{"line_number":517,"context_line":"        elif obj and req.method in (\u0027PUT\u0027, \u0027COPY\u0027, \u0027DELETE\u0027):"},{"line_number":518,"context_line":"            try:"},{"line_number":519,"context_line":"                return self.object_request("},{"line_number":520,"context_line":"                    req, version, account, container, obj,"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_5bb09143","line":517,"in_reply_to":"9a68dd71_c4f4b488","updated":"2016-01-22 17:00:58.000000000","message":"They do until COPY is moved to middleware I think. Only then can the references to COPY be removed.","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"a0fda8250de7a4c99e8ff3c19809959dd911a340","unresolved":false,"context_lines":[{"line_number":308,"context_line":"            # redirect the original DELETE to the source of the reinstated"},{"line_number":309,"context_line":"            # version object - we already auth\u0027d original req so make a"},{"line_number":310,"context_line":"            # pre-authed request"},{"line_number":311,"context_line":"            # TODO: should we be setting DELETE req source to \u0027VW\u0027 ?"},{"line_number":312,"context_line":"            req \u003d make_pre_authed_request("},{"line_number":313,"context_line":"                req.environ, path\u003dget_path, method\u003d\u0027DELETE\u0027,"},{"line_number":314,"context_line":"                swift_source\u003d\u0027VW\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a57f1b5_805579c7","line":311,"updated":"2016-02-10 04:04:29.000000000","message":"Why is this in question?  Do you mean because it is essentially is the request that maps to the original delete request rather than an internal child request?","commit_id":"74f3c5492698d635eb24023603be86346848f99c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3916ab4adc8faf7674d8ee861d61c2122e654e5d","unresolved":false,"context_lines":[{"line_number":308,"context_line":"            # redirect the original DELETE to the source of the reinstated"},{"line_number":309,"context_line":"            # version object - we already auth\u0027d original req so make a"},{"line_number":310,"context_line":"            # pre-authed request"},{"line_number":311,"context_line":"            # TODO: should we be setting DELETE req source to \u0027VW\u0027 ?"},{"line_number":312,"context_line":"            req \u003d make_pre_authed_request("},{"line_number":313,"context_line":"                req.environ, path\u003dget_path, method\u003d\u0027DELETE\u0027,"},{"line_number":314,"context_line":"                swift_source\u003d\u0027VW\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a57f1b5_d717aaeb","line":311,"in_reply_to":"3a57f1b5_805579c7","updated":"2016-02-10 10:13:36.000000000","message":"Yes. This behaviour does match master, if I read master branch correctly. But I wonder if it is correct since I think it means all internal requests are marked as source VW and none if therefore attributed to the client.\n\nIt needs further investigation, and a test perhaps. Maybe its a bug on master.","commit_id":"74f3c5492698d635eb24023603be86346848f99c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4576fb9fcac56fff52d92bc25494bacd85fd619","unresolved":false,"context_lines":[{"line_number":228,"context_line":"                                account_name, object_name):"},{"line_number":229,"context_line":"        get_resp \u003d self._get_source_object(req, req.path_info)"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"        if(\u0027X-Object-Manifest\u0027 in req.headers or"},{"line_number":232,"context_line":"                \u0027X-Object-Manifest\u0027 in get_resp.headers):"},{"line_number":233,"context_line":"            # do not version DLO manifest, proceed with original request"},{"line_number":234,"context_line":"            close_if_possible(get_resp.app_iter)"}],"source_content_type":"text/x-python","patch_set":6,"id":"dae33548_8f1c9d78","line":231,"updated":"2016-02-16 16:46:53.000000000","message":"test for req being a dlo manifest BEFORE issuing the get","commit_id":"0503d96e26b33ea7426fc8a6dd4002f3e5b28f41"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4576fb9fcac56fff52d92bc25494bacd85fd619","unresolved":false,"context_lines":[{"line_number":238,"context_line":"            return None"},{"line_number":239,"context_line":"        if not is_success(get_resp.status_int):"},{"line_number":240,"context_line":"            # return error immediately"},{"line_number":241,"context_line":"            return self._get_response_error(req, get_resp)"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":"        # if there\u0027s an existing object, then copy it to"},{"line_number":244,"context_line":"        # X-Versions-Location"}],"source_content_type":"text/x-python","patch_set":6,"id":"dae33548_2f7911c9","line":241,"updated":"2016-02-16 16:46:53.000000000","message":"this is a change in client-perceived behaviour.\n\nalso, could be:\n\n  resp \u003d self._get_response_error(req, get_resp)\n  if resp:\n      return resp\n\nIDK, just looks weird to test for is_success before and then in the method. Better still would be to have the method *raise* the response if an error, then catch somewhere and return.","commit_id":"0503d96e26b33ea7426fc8a6dd4002f3e5b28f41"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"58a5bd55701d1584c665aa5f62d2f85442ecf4e9","unresolved":false,"context_lines":[{"line_number":207,"context_line":"    def _put_versioned_obj(self, req, put_path_info, source_resp):"},{"line_number":208,"context_line":"        # Create a new Request object to PUT to the versions container, copying"},{"line_number":209,"context_line":"        # all headers from the source object apart from x-timestamp."},{"line_number":210,"context_line":"        put_req \u003d Request.blank(put_path_info, method\u003d\u0027PUT\u0027)"},{"line_number":211,"context_line":"        copy_header_subset(source_resp, put_req,"},{"line_number":212,"context_line":"                           lambda k: k.lower() !\u003d \u0027x-timestamp\u0027)"},{"line_number":213,"context_line":"        put_req.headers[\u0027x-auth-token\u0027] \u003d req.headers.get(\u0027x-auth-token\u0027)"}],"source_content_type":"text/x-python","patch_set":7,"id":"dae33548_c8585635","line":210,"updated":"2016-02-16 18:10:18.000000000","message":"The PUT requests are logging with a different txn id and without the swift source set to VW - to be consistent with current behavior the GET/PUT subrequests should both have swift source VW and same transaction ID.\n\nI think that perhaps we should be using a make_subrequest method call here, which will copy the trans_id across to the PUT, and also set swift source in the method params.","commit_id":"f610b4185595a600c8003de18194a3c52801c2f1"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"969078d974ac11b3496bbe42ed700b19736e62ce","unresolved":false,"context_lines":[{"line_number":207,"context_line":"    def _put_versioned_obj(self, req, put_path_info, source_resp):"},{"line_number":208,"context_line":"        # Create a new Request object to PUT to the versions container, copying"},{"line_number":209,"context_line":"        # all headers from the source object apart from x-timestamp."},{"line_number":210,"context_line":"        put_req \u003d Request.blank(put_path_info, method\u003d\u0027PUT\u0027)"},{"line_number":211,"context_line":"        copy_header_subset(source_resp, put_req,"},{"line_number":212,"context_line":"                           lambda k: k.lower() !\u003d \u0027x-timestamp\u0027)"},{"line_number":213,"context_line":"        put_req.headers[\u0027x-auth-token\u0027] \u003d req.headers.get(\u0027x-auth-token\u0027)"}],"source_content_type":"text/x-python","patch_set":7,"id":"dae33548_63d4cc1f","line":210,"in_reply_to":"dae33548_c8585635","updated":"2016-02-16 21:12:36.000000000","message":"changed it to use make_subrequest: http://ur1.ca/oj0s5","commit_id":"f610b4185595a600c8003de18194a3c52801c2f1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3da81f9a1fea8dd8b35eff77fe945ab38798255d","unresolved":false,"context_lines":[{"line_number":311,"context_line":"            # redirect the original DELETE to the source of the reinstated"},{"line_number":312,"context_line":"            # version object - we already auth\u0027d original req so make a"},{"line_number":313,"context_line":"            # pre-authed request"},{"line_number":314,"context_line":"            # TODO: should we be setting DELETE req source to \u0027VW\u0027 ?"},{"line_number":315,"context_line":"            req \u003d make_pre_authed_request("},{"line_number":316,"context_line":"                req.environ, path\u003dget_path, method\u003d\u0027DELETE\u0027,"},{"line_number":317,"context_line":"                swift_source\u003d\u0027VW\u0027)"}],"source_content_type":"text/x-python","patch_set":7,"id":"dae33548_e86efa94","line":314,"updated":"2016-02-16 18:13:12.000000000","message":"I believe this is correct i.e. the subrequest DELETE should be tagged \"VW\"\n\nso the TODO needs removing.","commit_id":"f610b4185595a600c8003de18194a3c52801c2f1"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"cdf3bd3f389027818e72dd99b7377ba1c286f5c5","unresolved":false,"context_lines":[{"line_number":246,"context_line":"            return ret"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"        # if there\u0027s an existing object, then copy it to"},{"line_number":249,"context_line":"        # X-Versions-Location"},{"line_number":250,"context_line":"        lcontainer \u003d object_versions.split(\u0027/\u0027)[0]"},{"line_number":251,"context_line":"        prefix_len \u003d \u0027%03x\u0027 % len(object_name)"},{"line_number":252,"context_line":"        lprefix \u003d prefix_len + object_name + \u0027/\u0027"}],"source_content_type":"text/x-python","patch_set":9,"id":"dae33548_33e5a9db","line":249,"updated":"2016-02-18 00:44:47.000000000","message":"NIT: it\u0027s really:\n\n  # if there\u0027s an existing object, then put it in X-Versions-Location\n\nBut that isn\u0027t really a blocker cause you are copying the existing :)","commit_id":"688c3a899233637c07ae624eae843076a1680300"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"bdcab502cff35d94a3a92f004c7153da20c02583","unresolved":false,"context_lines":[{"line_number":214,"context_line":"                           lambda k: k.lower() !\u003d \u0027x-timestamp\u0027)"},{"line_number":215,"context_line":"        put_req.headers[\u0027x-auth-token\u0027] \u003d req.headers.get(\u0027x-auth-token\u0027)"},{"line_number":216,"context_line":"        put_req.environ[\u0027wsgi.input\u0027] \u003d InputProxy("},{"line_number":217,"context_line":"            six.BytesIO(source_resp.body))"},{"line_number":218,"context_line":"        return put_req.get_response(self.app)"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"    def _get_response_error(self, req, resp):"}],"source_content_type":"text/x-python","patch_set":11,"id":"1af94dfe_7b5396e2","line":217,"updated":"2016-03-18 00:05:28.000000000","message":"Calling .body here will slurp the entire response body into memory. See swob._resp_body_property() for details.","commit_id":"ef47e08f734a0d879c0890c99039050b94a6b9b8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"27b531d9c06b7b4423d7b433cb038d4e354b5c39","unresolved":false,"context_lines":[{"line_number":214,"context_line":"                           lambda k: k.lower() !\u003d \u0027x-timestamp\u0027)"},{"line_number":215,"context_line":"        put_req.headers[\u0027x-auth-token\u0027] \u003d req.headers.get(\u0027x-auth-token\u0027)"},{"line_number":216,"context_line":"        put_req.environ[\u0027wsgi.input\u0027] \u003d InputProxy("},{"line_number":217,"context_line":"            six.BytesIO(source_resp.body))"},{"line_number":218,"context_line":"        return put_req.get_response(self.app)"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"    def _get_response_error(self, req, resp):"}],"source_content_type":"text/x-python","patch_set":11,"id":"1af94dfe_9e011e09","line":217,"in_reply_to":"1af94dfe_7b5396e2","updated":"2016-03-18 11:06:18.000000000","message":"Done, switched to use a FileLikeIter","commit_id":"ef47e08f734a0d879c0890c99039050b94a6b9b8"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"da631ba657074197d9a5e452bace4b867684d3e6","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        return HTTPServiceUnavailable(request\u003dreq)"},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"    def handle_obj_versions_put(self, req, object_versions, version,"},{"line_number":229,"context_line":"                                account_name, object_name):"},{"line_number":230,"context_line":"        if \u0027X-Object-Manifest\u0027 in req.headers:"},{"line_number":231,"context_line":"            # do not version DLO manifest, proceed with original request"},{"line_number":232,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba0121b8_970ec2e3","line":229,"updated":"2016-04-04 11:22:26.000000000","message":"Memo:\n- What\u0027s mean (difference) about \"object_versions\" and \"version\".\n\n\nYeah, this is too complicated. \"object_version\" is the versioned_container and \"version\" is API version. Hmm...interesting but ok, I got it about this.\n\n\n\n- Why we don\u0027t need container_name, here.\n\nThe reason we don\u0027t need the container name of original request is that handle_obj_versions_put doesn\u0027t care about the original request, it does just copy the object into version container (object_versions). However I like to make versions_writes to do like req.get_response for the put too because it can help to trace the route how versioning middleware works. I think this point is not urgent just a wish so it\u0027s not strong opinion to guard this to merge.","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"692fe07ca15ed7445b80243c4b1cf61faa900cc9","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        return HTTPServiceUnavailable(request\u003dreq)"},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"    def handle_obj_versions_put(self, req, object_versions, version,"},{"line_number":229,"context_line":"                                account_name, object_name):"},{"line_number":230,"context_line":"        if \u0027X-Object-Manifest\u0027 in req.headers:"},{"line_number":231,"context_line":"            # do not version DLO manifest, proceed with original request"},{"line_number":232,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":15,"id":"9a061dce_926529e3","line":229,"in_reply_to":"ba0121b8_970ec2e3","updated":"2016-04-06 15:49:00.000000000","message":"For now, I\u0027ve renamed \"object_versions\" to \"versions_cont\" and \"version\" to \"api_version\"","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"da631ba657074197d9a5e452bace4b867684d3e6","unresolved":false,"context_lines":[{"line_number":237,"context_line":"            # do not version DLO manifest, proceed with original request"},{"line_number":238,"context_line":"            close_if_possible(get_resp.app_iter)"},{"line_number":239,"context_line":"            return None"},{"line_number":240,"context_line":"        if get_resp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":241,"context_line":"            # nothing to version, proceed with original request"},{"line_number":242,"context_line":"            return None"},{"line_number":243,"context_line":"        ret \u003d self._get_response_error(req, get_resp)"},{"line_number":244,"context_line":"        if ret:"},{"line_number":245,"context_line":"            return ret"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba0121b8_b7cae66c","line":242,"range":{"start_line":240,"start_character":0,"end_line":242,"end_character":23},"updated":"2016-04-04 11:22:26.000000000","message":"(memo) Looks like HTTP_NOT_FOUND is a part of error statement in _get_response_error.","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"692fe07ca15ed7445b80243c4b1cf61faa900cc9","unresolved":false,"context_lines":[{"line_number":237,"context_line":"            # do not version DLO manifest, proceed with original request"},{"line_number":238,"context_line":"            close_if_possible(get_resp.app_iter)"},{"line_number":239,"context_line":"            return None"},{"line_number":240,"context_line":"        if get_resp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":241,"context_line":"            # nothing to version, proceed with original request"},{"line_number":242,"context_line":"            return None"},{"line_number":243,"context_line":"        ret \u003d self._get_response_error(req, get_resp)"},{"line_number":244,"context_line":"        if ret:"},{"line_number":245,"context_line":"            return ret"}],"source_content_type":"text/x-python","patch_set":15,"id":"9a061dce_f2b90530","line":242,"range":{"start_line":240,"start_character":0,"end_line":242,"end_character":23},"in_reply_to":"ba0121b8_b7cae66c","updated":"2016-04-06 15:49:00.000000000","message":"yes, the reason we treat HTTP_NOT_FOUND differently is because it is an OK outcome. It just means the current PUT is the first version for this object","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"da631ba657074197d9a5e452bace4b867684d3e6","unresolved":false,"context_lines":[{"line_number":241,"context_line":"            # nothing to version, proceed with original request"},{"line_number":242,"context_line":"            return None"},{"line_number":243,"context_line":"        ret \u003d self._get_response_error(req, get_resp)"},{"line_number":244,"context_line":"        if ret:"},{"line_number":245,"context_line":"            return ret"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"        # if there\u0027s an existing object, then copy it to"},{"line_number":248,"context_line":"        # X-Versions-Location"}],"source_content_type":"text/x-python","patch_set":15,"id":"9a061dce_b7496891","line":245,"range":{"start_line":244,"start_character":0,"end_line":245,"end_character":22},"updated":"2016-04-04 11:22:26.000000000","message":"Some places which checks the return code from _get_response_error but I don\u0027t think we have to do this. Instead just raise HTTPException in _get_response_error because the HTTPException will be caught in __call__ and if we do so, we can avoid a bunch of \"if ret:\" statement everywhere :)\n\nThe fix is like:\n\nhttp://paste.openstack.org/show/492855/","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"692fe07ca15ed7445b80243c4b1cf61faa900cc9","unresolved":false,"context_lines":[{"line_number":241,"context_line":"            # nothing to version, proceed with original request"},{"line_number":242,"context_line":"            return None"},{"line_number":243,"context_line":"        ret \u003d self._get_response_error(req, get_resp)"},{"line_number":244,"context_line":"        if ret:"},{"line_number":245,"context_line":"            return ret"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"        # if there\u0027s an existing object, then copy it to"},{"line_number":248,"context_line":"        # X-Versions-Location"}],"source_content_type":"text/x-python","patch_set":15,"id":"9a061dce_90ab6189","line":245,"range":{"start_line":244,"start_character":0,"end_line":245,"end_character":22},"in_reply_to":"9a061dce_b7496891","updated":"2016-04-06 15:49:00.000000000","message":"Done","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"da631ba657074197d9a5e452bace4b867684d3e6","unresolved":false,"context_lines":[{"line_number":246,"context_line":""},{"line_number":247,"context_line":"        # if there\u0027s an existing object, then copy it to"},{"line_number":248,"context_line":"        # X-Versions-Location"},{"line_number":249,"context_line":"        lcontainer \u003d object_versions.split(\u0027/\u0027)[0]"},{"line_number":250,"context_line":"        prefix_len \u003d \u0027%03x\u0027 % len(object_name)"},{"line_number":251,"context_line":"        lprefix \u003d prefix_len + object_name + \u0027/\u0027"},{"line_number":252,"context_line":"        ts_source \u003d get_resp.headers.get("}],"source_content_type":"text/x-python","patch_set":15,"id":"ba0121b8_dae6a115","line":249,"updated":"2016-04-04 11:22:26.000000000","message":"split(\u0027/\u0027)[0] is probably meaningless.\n\nobject_versions is a container name from container-info (\u0027versions-location\u0027 or \u0027x-container-sysmeta-versions-location\u0027) and the name format should be verified at PUT/POST container (at the time to set versioning against to the container). The verification will be done by swift.common.constraints.check_container_format which obviously prevents \u0027/\u0027 included in the container name [1].\n\n\nOnce I tried to remove the split (i.e. just lcontainer \u003d object_veresions), nothing of unit tests failed. Am I missing somethhing?\n\n1: https://github.com/openstack/swift/blob/master/swift/common/constraints.py#L413-L440","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"692fe07ca15ed7445b80243c4b1cf61faa900cc9","unresolved":false,"context_lines":[{"line_number":246,"context_line":""},{"line_number":247,"context_line":"        # if there\u0027s an existing object, then copy it to"},{"line_number":248,"context_line":"        # X-Versions-Location"},{"line_number":249,"context_line":"        lcontainer \u003d object_versions.split(\u0027/\u0027)[0]"},{"line_number":250,"context_line":"        prefix_len \u003d \u0027%03x\u0027 % len(object_name)"},{"line_number":251,"context_line":"        lprefix \u003d prefix_len + object_name + \u0027/\u0027"},{"line_number":252,"context_line":"        ts_source \u003d get_resp.headers.get("}],"source_content_type":"text/x-python","patch_set":15,"id":"9a061dce_d0ce7982","line":249,"in_reply_to":"ba0121b8_dae6a115","updated":"2016-04-06 15:49:00.000000000","message":"Done","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"da631ba657074197d9a5e452bace4b867684d3e6","unresolved":false,"context_lines":[{"line_number":303,"context_line":""},{"line_number":304,"context_line":"            put_path_info \u003d \"/%s/%s/%s/%s\" % ("},{"line_number":305,"context_line":"                version, account_name, container_name, object_name)"},{"line_number":306,"context_line":"            put_resp \u003d self._put_versioned_obj(req, put_path_info, get_resp)"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"            ret \u003d self._get_response_error(req, put_resp)"},{"line_number":309,"context_line":"            if ret:"}],"source_content_type":"text/x-python","patch_set":15,"id":"9a061dce_fddc5f48","line":306,"updated":"2016-04-04 11:22:26.000000000","message":"So if we use _put_versioned_obj method here, and another PUT request from client comming, what\u0027s happen?\n\ni.e.:\n\nt0: PUT /a/c/o\nt1: PUT /a/c/o -\u003e versiond_writes will make versioned object into /a/versioned_container/o\n\nt3: DELETE /a/c/o -\u003e versioned_writes will do PUT /a/c/o with response iter from GET /a/versioned_container/o (i.e. t0 object) with *t3* timestamp.\n\nt2: PUT /a/c/o -\u003e this object may be lost?\n\nThe reason I thought is _put_versioned_obj method drops X-Timestamp intentionally so the PUT t3 will get current timestamp as PUT timestamp and it will delete everything happned during T3 request.\n\nI\u0027m not sure (not tested yet), and current Swift (w/o this patch) probably has same issue for this.","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"e8b797711eac1fc97eda339fbc0a588abd451265","unresolved":false,"context_lines":[{"line_number":303,"context_line":""},{"line_number":304,"context_line":"            put_path_info \u003d \"/%s/%s/%s/%s\" % ("},{"line_number":305,"context_line":"                version, account_name, container_name, object_name)"},{"line_number":306,"context_line":"            put_resp \u003d self._put_versioned_obj(req, put_path_info, get_resp)"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"            ret \u003d self._get_response_error(req, put_resp)"},{"line_number":309,"context_line":"            if ret:"}],"source_content_type":"text/x-python","patch_set":15,"id":"9a061dce_0310d1a7","line":306,"in_reply_to":"9a061dce_fddc5f48","updated":"2016-04-08 10:10:46.000000000","message":"ah, this is probably ok because semantically t3 DELETE will affect the newest object (i.e. t2 here) so t2 deleted is ok and t2 PUT will make a t1 object into versioned container so hopefully it is safe. Maybe just inconsistency the object got back to the container may be not the newest.","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"183d9fc19efbd7f4005ac28f11748da327a9b90b","unresolved":false,"context_lines":[{"line_number":372,"context_line":"                    # could not copy the data, bail"},{"line_number":373,"context_line":"                    return HTTPServiceUnavailable(request\u003dreq)"},{"line_number":374,"context_line":""},{"line_number":375,"context_line":"            # reset these because the COPY changed them"},{"line_number":376,"context_line":"            new_del_req \u003d make_pre_authed_request("},{"line_number":377,"context_line":"                req.environ, path\u003dcopy_path, method\u003d\u0027DELETE\u0027,"},{"line_number":378,"context_line":"                swift_source\u003d\u0027VW\u0027)"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_51cd8664","side":"PARENT","line":375,"range":{"start_line":375,"start_character":34,"end_line":375,"end_character":55},"updated":"2016-04-08 18:47:32.000000000","message":"Why did we think that before? Did make_pre_authed_request use the same env dict long ago, or something?","commit_id":"da6031067ed2b873e9edcdea1502d522e6aafd12"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a2b432f7263ae9917e3688cf0b8ec7e4f0b70b0e","unresolved":false,"context_lines":[{"line_number":372,"context_line":"                    # could not copy the data, bail"},{"line_number":373,"context_line":"                    return HTTPServiceUnavailable(request\u003dreq)"},{"line_number":374,"context_line":""},{"line_number":375,"context_line":"            # reset these because the COPY changed them"},{"line_number":376,"context_line":"            new_del_req \u003d make_pre_authed_request("},{"line_number":377,"context_line":"                req.environ, path\u003dcopy_path, method\u003d\u0027DELETE\u0027,"},{"line_number":378,"context_line":"                swift_source\u003d\u0027VW\u0027)"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_899c7b5e","side":"PARENT","line":375,"range":{"start_line":375,"start_character":34,"end_line":375,"end_character":55},"in_reply_to":"1a122d0e_f5e986e7","updated":"2016-04-19 17:03:08.000000000","message":"Yeah, I\u0027ll chalk that up to a bad comment. Not worried.","commit_id":"da6031067ed2b873e9edcdea1502d522e6aafd12"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"371c12a8ca18fb61eeec6d36837996316209da96","unresolved":false,"context_lines":[{"line_number":372,"context_line":"                    # could not copy the data, bail"},{"line_number":373,"context_line":"                    return HTTPServiceUnavailable(request\u003dreq)"},{"line_number":374,"context_line":""},{"line_number":375,"context_line":"            # reset these because the COPY changed them"},{"line_number":376,"context_line":"            new_del_req \u003d make_pre_authed_request("},{"line_number":377,"context_line":"                req.environ, path\u003dcopy_path, method\u003d\u0027DELETE\u0027,"},{"line_number":378,"context_line":"                swift_source\u003d\u0027VW\u0027)"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_f5e986e7","side":"PARENT","line":375,"range":{"start_line":375,"start_character":34,"end_line":375,"end_character":55},"in_reply_to":"9a061dce_51cd8664","updated":"2016-04-19 15:43:49.000000000","message":"not sure I understand the question. probably the comment is not well written, but basically the DELETE request now becomes delete the \"old\" version in the versions container that just got copied over to the source container.","commit_id":"da6031067ed2b873e9edcdea1502d522e6aafd12"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"183d9fc19efbd7f4005ac28f11748da327a9b90b","unresolved":false,"context_lines":[{"line_number":271,"context_line":"            headers\u003d_headers, method\u003d\u0027GET\u0027, swift_source\u003d\u0027VW\u0027)"},{"line_number":272,"context_line":"        source_resp \u003d get_req.get_response(self.app)"},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"        if source_resp.content_length \u003e MAX_FILE_SIZE:"},{"line_number":275,"context_line":"            return HTTPRequestEntityTooLarge(request\u003dreq)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        return source_resp"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_d1019606","line":274,"range":{"start_line":274,"start_character":23,"end_line":274,"end_character":37},"updated":"2016-04-08 18:47:32.000000000","message":"Have we considered the implications of this being None? This can happen, e.g., with DLOs when there are more segments than can fit in a single container listing.\n\nDo we just assume that no one would have stuck a DLO in the versions location behind our backs?\n\nFWIW, looks like we used to 413 there as well, though depending on chunk size that may not be entirely appropriate...","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a2b432f7263ae9917e3688cf0b8ec7e4f0b70b0e","unresolved":false,"context_lines":[{"line_number":271,"context_line":"            headers\u003d_headers, method\u003d\u0027GET\u0027, swift_source\u003d\u0027VW\u0027)"},{"line_number":272,"context_line":"        source_resp \u003d get_req.get_response(self.app)"},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"        if source_resp.content_length \u003e MAX_FILE_SIZE:"},{"line_number":275,"context_line":"            return HTTPRequestEntityTooLarge(request\u003dreq)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        return source_resp"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_d7caae6d","line":274,"range":{"start_line":274,"start_character":23,"end_line":274,"end_character":37},"in_reply_to":"1a122d0e_73501c5e","updated":"2016-04-19 17:03:08.000000000","message":"Huh.\n\nWith DLO explicitly in the pipeline but letting versioned_writes be auto-inserted, we should never get a chunk-encoded response (at least, not from DLO). While DLOs will never be backed up, if you manually add one to the versions container, it *will* be restored (and as a manifest). This seems to indicate it would at least be *feasible* to version DLOs, which seems to make sense.\n\nOn the other hand, if you explicitly include both of them *and swap the order*, you (1) can get a chunk-encoded response on restore and (2) will get a 499 (?) on the PUT if you don\u0027t have the is-None check. Even without the disconnect, the response includes an X-Object-Manifest header (!), which means that you\u0027d both have the full content copied out *and* rely on the integrity of the old segments (!!).\n\nSo I wonder if the lack of DLO support is just a preventative measure in case someone messes up their pipeline. We have no way of enforcing a particular pipeline order (and I\u0027m not quite sure that we should), so maybe this is for the best? Maybe we could get around it by ensuring that there\u0027s a ?multipart-manifest\u003dget in get_req; I\u0027m not sure.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"aae011438f2bb88ad1601fc50b1ffbd936f171d8","unresolved":false,"context_lines":[{"line_number":271,"context_line":"            headers\u003d_headers, method\u003d\u0027GET\u0027, swift_source\u003d\u0027VW\u0027)"},{"line_number":272,"context_line":"        source_resp \u003d get_req.get_response(self.app)"},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"        if source_resp.content_length \u003e MAX_FILE_SIZE:"},{"line_number":275,"context_line":"            return HTTPRequestEntityTooLarge(request\u003dreq)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        return source_resp"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_73501c5e","line":274,"range":{"start_line":274,"start_character":23,"end_line":274,"end_character":37},"in_reply_to":"5a18252c_59c83e74","updated":"2016-04-18 20:20:10.000000000","message":"Kota, so you are correct to affirm that this was coded this way based on what\u0027s in _handle_copy_request. removing that check from there, I can see that this [1] test fails, so at some point there was definetely a concern that a GET could return a \"large\" object, but I\u0027m not sure what situation that would occur???\n\n[1] - https://github.com/openstack/swift/blob/master/test/unit/proxy/test_server.py#L5130","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a395920c12b72f714b646140fb4cae79713ebe59","unresolved":false,"context_lines":[{"line_number":271,"context_line":"            headers\u003d_headers, method\u003d\u0027GET\u0027, swift_source\u003d\u0027VW\u0027)"},{"line_number":272,"context_line":"        source_resp \u003d get_req.get_response(self.app)"},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"        if source_resp.content_length \u003e MAX_FILE_SIZE:"},{"line_number":275,"context_line":"            return HTTPRequestEntityTooLarge(request\u003dreq)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        return source_resp"}],"source_content_type":"text/x-python","patch_set":16,"id":"5a18252c_59c83e74","line":274,"range":{"start_line":274,"start_character":23,"end_line":274,"end_character":37},"in_reply_to":"7a1b2928_6be21a05","updated":"2016-04-15 06:00:32.000000000","message":"Looking at the conversations above, I am realizing we don\u0027t have to have this check here. That is because the transfer-bytes check (around [1][2]) will happen in the put sequence of proxy-server app in both case the put request have the content-length (or not have).\n\nProbably I am missing the original intention the swift.proxy.controller.obj._handle_copy_request has similar code with this and it might be still lack to set the resp content length to the put req yet though (not sure digging deeply yet). But IMO, what we need is just setting resp content-length (even if it\u0027s None) to the put request, and then trust the proxy-sever handling. Is it right?\n\nPlus, once I removed this checking, nothing fails in the Swift test cases...\n\n1: https://github.com/openstack/swift/blob/master/swift/proxy/controllers/obj.py#L976-L977\n2: https://github.com/openstack/swift/blob/master/swift/common/constraints.py#L171-L201","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"400f7a3b0ce5b402bf126c18ec89096358b901c0","unresolved":false,"context_lines":[{"line_number":271,"context_line":"            headers\u003d_headers, method\u003d\u0027GET\u0027, swift_source\u003d\u0027VW\u0027)"},{"line_number":272,"context_line":"        source_resp \u003d get_req.get_response(self.app)"},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"        if source_resp.content_length \u003e MAX_FILE_SIZE:"},{"line_number":275,"context_line":"            return HTTPRequestEntityTooLarge(request\u003dreq)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        return source_resp"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a1b2928_6be21a05","line":274,"range":{"start_line":274,"start_character":23,"end_line":274,"end_character":37},"in_reply_to":"7a1b2928_d0a31d9d","updated":"2016-04-11 18:48:23.000000000","message":"ok, I\u0027ll add it back to be on the safe side.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"58afadde99fc251889d6fec05a3c1a876e851628","unresolved":false,"context_lines":[{"line_number":271,"context_line":"            headers\u003d_headers, method\u003d\u0027GET\u0027, swift_source\u003d\u0027VW\u0027)"},{"line_number":272,"context_line":"        source_resp \u003d get_req.get_response(self.app)"},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"        if source_resp.content_length \u003e MAX_FILE_SIZE:"},{"line_number":275,"context_line":"            return HTTPRequestEntityTooLarge(request\u003dreq)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        return source_resp"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a1b2928_d0a31d9d","line":274,"range":{"start_line":274,"start_character":23,"end_line":274,"end_character":37},"in_reply_to":"9a061dce_d1019606","updated":"2016-04-11 16:47:01.000000000","message":"can this happen? I can see that a DLO GET response may have content-length\u003dNone, but versioned_writes comes after DLO in the pipeline (and even if DLO manifests were versioned, I\u0027m not sure we\u0027d expect a versioned_write copy to transform a DLO manifest into its composed object).\n\nI can\u0027t (yet) see that a backend object server response would ever not have a content-length.\n\nThat said it may make sense to add \u0027None\u0027 to the conditions for returning HTTPRequestEntityTooLarge, to be safe. I see that handle_copy_request in obj.py on master does that but I assume that is for handling real COPY requests which could be copying a DLO.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"183d9fc19efbd7f4005ac28f11748da327a9b90b","unresolved":false,"context_lines":[{"line_number":283,"context_line":"            req.environ, path\u003dput_path_info, method\u003d\u0027PUT\u0027,"},{"line_number":284,"context_line":"            swift_source\u003d\u0027VW\u0027)"},{"line_number":285,"context_line":"        copy_header_subset(source_resp, put_req,"},{"line_number":286,"context_line":"                           lambda k: k.lower() !\u003d \u0027x-timestamp\u0027)"},{"line_number":287,"context_line":"        put_req.headers[\u0027x-auth-token\u0027] \u003d req.headers.get(\u0027x-auth-token\u0027)"},{"line_number":288,"context_line":"        put_req.environ[\u0027wsgi.input\u0027] \u003d FileLikeIter(source_resp.app_iter)"},{"line_number":289,"context_line":"        return put_req.get_response(self.app)"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_c79fea4e","line":286,"range":{"start_line":286,"start_character":51,"end_line":286,"end_character":62},"updated":"2016-04-08 18:47:32.000000000","message":"Is this the only header we need to worry about?\n\nWould X-Backend-Storage-Policy-Index show up in the GET response? If so, would it be problematic if the two containers had different policies?\n\nAny other potential pitfalls?","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"58afadde99fc251889d6fec05a3c1a876e851628","unresolved":false,"context_lines":[{"line_number":283,"context_line":"            req.environ, path\u003dput_path_info, method\u003d\u0027PUT\u0027,"},{"line_number":284,"context_line":"            swift_source\u003d\u0027VW\u0027)"},{"line_number":285,"context_line":"        copy_header_subset(source_resp, put_req,"},{"line_number":286,"context_line":"                           lambda k: k.lower() !\u003d \u0027x-timestamp\u0027)"},{"line_number":287,"context_line":"        put_req.headers[\u0027x-auth-token\u0027] \u003d req.headers.get(\u0027x-auth-token\u0027)"},{"line_number":288,"context_line":"        put_req.environ[\u0027wsgi.input\u0027] \u003d FileLikeIter(source_resp.app_iter)"},{"line_number":289,"context_line":"        return put_req.get_response(self.app)"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a1b2928_5537ffaf","line":286,"range":{"start_line":286,"start_character":51,"end_line":286,"end_character":62},"in_reply_to":"9a061dce_c79fea4e","updated":"2016-04-11 16:47:01.000000000","message":"Great question. X-Backend-Storage-Policy-Index is not AFAIK (and I looked at the code!) returned in responses. No X-Backend header is persisted on disk so it would have to be explicitly added by the object server GET/HEAD methods.\n\nI do have a patch https://review.openstack.org/#/c/272724/ to fix some missing headers from copied objects. I am waiting for the dust to settle with this patch and the copy middleware before actively promoting that - seemed like it would be confusing to introduce bug fixes (and therefore change behaviour) in these patches.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"183d9fc19efbd7f4005ac28f11748da327a9b90b","unresolved":false,"context_lines":[{"line_number":285,"context_line":"        copy_header_subset(source_resp, put_req,"},{"line_number":286,"context_line":"                           lambda k: k.lower() !\u003d \u0027x-timestamp\u0027)"},{"line_number":287,"context_line":"        put_req.headers[\u0027x-auth-token\u0027] \u003d req.headers.get(\u0027x-auth-token\u0027)"},{"line_number":288,"context_line":"        put_req.environ[\u0027wsgi.input\u0027] \u003d FileLikeIter(source_resp.app_iter)"},{"line_number":289,"context_line":"        return put_req.get_response(self.app)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"    def _check_response_error(self, req, resp):"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_2706a620","line":288,"range":{"start_line":288,"start_character":40,"end_line":288,"end_character":52},"updated":"2016-04-08 18:47:32.000000000","message":"It makes me a little sad that we have to turn our iter into a file-like just to have it turned back into an iter in swift/proxy/controllers/obj.py\n\nOh well.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"183d9fc19efbd7f4005ac28f11748da327a9b90b","unresolved":false,"context_lines":[{"line_number":293,"context_line":"        Raise Error Response in case of error"},{"line_number":294,"context_line":"        \"\"\""},{"line_number":295,"context_line":"        if is_success(resp.status_int):"},{"line_number":296,"context_line":"            return None"},{"line_number":297,"context_line":"        if is_client_error(resp.status_int):"},{"line_number":298,"context_line":"            # missing container or bad permissions"},{"line_number":299,"context_line":"            raise HTTPPreconditionFailed(request\u003dreq)"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_712eca8c","line":296,"range":{"start_line":296,"start_character":19,"end_line":296,"end_character":23},"updated":"2016-04-08 18:47:32.000000000","message":"nit: May as well just return.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"400f7a3b0ce5b402bf126c18ec89096358b901c0","unresolved":false,"context_lines":[{"line_number":293,"context_line":"        Raise Error Response in case of error"},{"line_number":294,"context_line":"        \"\"\""},{"line_number":295,"context_line":"        if is_success(resp.status_int):"},{"line_number":296,"context_line":"            return None"},{"line_number":297,"context_line":"        if is_client_error(resp.status_int):"},{"line_number":298,"context_line":"            # missing container or bad permissions"},{"line_number":299,"context_line":"            raise HTTPPreconditionFailed(request\u003dreq)"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a1b2928_8fe22902","line":296,"range":{"start_line":296,"start_character":19,"end_line":296,"end_character":23},"in_reply_to":"9a061dce_712eca8c","updated":"2016-04-11 18:48:23.000000000","message":"Done","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a1a1207933bd12e90b83a93e332190814cde1860","unresolved":false,"context_lines":[{"line_number":311,"context_line":"                              are stored."},{"line_number":312,"context_line":"        :param api_version: api version."},{"line_number":313,"context_line":"        :param account_name: account name."},{"line_number":314,"context_line":"        :param object_name: name of object of original request"},{"line_number":315,"context_line":"        \"\"\""},{"line_number":316,"context_line":"        if \u0027X-Object-Manifest\u0027 in req.headers:"},{"line_number":317,"context_line":"            # do not version DLO manifest, proceed with original request"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_eedab477","line":314,"updated":"2016-04-08 10:20:15.000000000","message":"Great inline docs! This is much helpful to find the meaning of each variable.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"183d9fc19efbd7f4005ac28f11748da327a9b90b","unresolved":false,"context_lines":[{"line_number":314,"context_line":"        :param object_name: name of object of original request"},{"line_number":315,"context_line":"        \"\"\""},{"line_number":316,"context_line":"        if \u0027X-Object-Manifest\u0027 in req.headers:"},{"line_number":317,"context_line":"            # do not version DLO manifest, proceed with original request"},{"line_number":318,"context_line":"            return self.app"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"        get_resp \u003d self._get_source_object(req, req.path_info)"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_dc4a1d27","line":317,"updated":"2016-04-08 18:47:32.000000000","message":"Wait, so overwriting a plain-old-swift-object with a DLO won\u0027t retain the old object?\n\nI see how that must have been the previous behavior as well, but that feels like a bug...","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"400f7a3b0ce5b402bf126c18ec89096358b901c0","unresolved":false,"context_lines":[{"line_number":314,"context_line":"        :param object_name: name of object of original request"},{"line_number":315,"context_line":"        \"\"\""},{"line_number":316,"context_line":"        if \u0027X-Object-Manifest\u0027 in req.headers:"},{"line_number":317,"context_line":"            # do not version DLO manifest, proceed with original request"},{"line_number":318,"context_line":"            return self.app"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"        get_resp \u003d self._get_source_object(req, req.path_info)"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a1b2928_104f55be","line":317,"in_reply_to":"7a1b2928_35bfe3d1","updated":"2016-04-11 18:48:23.000000000","message":"Maybe we can solve that as a separate patch?","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"58afadde99fc251889d6fec05a3c1a876e851628","unresolved":false,"context_lines":[{"line_number":314,"context_line":"        :param object_name: name of object of original request"},{"line_number":315,"context_line":"        \"\"\""},{"line_number":316,"context_line":"        if \u0027X-Object-Manifest\u0027 in req.headers:"},{"line_number":317,"context_line":"            # do not version DLO manifest, proceed with original request"},{"line_number":318,"context_line":"            return self.app"},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"        get_resp \u003d self._get_source_object(req, req.path_info)"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a1b2928_35bfe3d1","line":317,"in_reply_to":"9a061dce_dc4a1d27","updated":"2016-04-11 16:47:01.000000000","message":"I also stared at this - I don\u0027t know and I have not found an answer as to why dlo manifests are not versioned.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"183d9fc19efbd7f4005ac28f11748da327a9b90b","unresolved":false,"context_lines":[{"line_number":325,"context_line":"            return self.app"},{"line_number":326,"context_line":"        if get_resp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":327,"context_line":"            # nothing to version, proceed with original request"},{"line_number":328,"context_line":"            return self.app"},{"line_number":329,"context_line":""},{"line_number":330,"context_line":"        # check for any other errors"},{"line_number":331,"context_line":"        self._check_response_error(req, get_resp)"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_dc717d79","line":328,"updated":"2016-04-08 18:47:32.000000000","message":"No\n\n close_if_possible(get_resp.app_iter)\n\nlike above?","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"400f7a3b0ce5b402bf126c18ec89096358b901c0","unresolved":false,"context_lines":[{"line_number":325,"context_line":"            return self.app"},{"line_number":326,"context_line":"        if get_resp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":327,"context_line":"            # nothing to version, proceed with original request"},{"line_number":328,"context_line":"            return self.app"},{"line_number":329,"context_line":""},{"line_number":330,"context_line":"        # check for any other errors"},{"line_number":331,"context_line":"        self._check_response_error(req, get_resp)"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a1b2928_419bc5c9","line":328,"in_reply_to":"9a061dce_dc717d79","updated":"2016-04-11 18:48:23.000000000","message":"Done","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"183d9fc19efbd7f4005ac28f11748da327a9b90b","unresolved":false,"context_lines":[{"line_number":336,"context_line":"        lprefix \u003d prefix_len + object_name + \u0027/\u0027"},{"line_number":337,"context_line":"        ts_source \u003d get_resp.headers.get("},{"line_number":338,"context_line":"            \u0027x-timestamp\u0027,"},{"line_number":339,"context_line":"            calendar.timegm(time.strptime("},{"line_number":340,"context_line":"                get_resp.headers[\u0027last-modified\u0027],"},{"line_number":341,"context_line":"                \u0027%a, %d %b %Y %H:%M:%S GMT\u0027)))"},{"line_number":342,"context_line":"        vers_obj_name \u003d lprefix + Timestamp(ts_source).internal"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_3ccb5920","line":339,"updated":"2016-04-08 18:47:32.000000000","message":"Huh. I wonder under what circumstances we could have a 2xx response but no X-Timestamp... I can see that this was the old behavior, too, but it still seems somewhat odd to me...","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"400f7a3b0ce5b402bf126c18ec89096358b901c0","unresolved":false,"context_lines":[{"line_number":336,"context_line":"        lprefix \u003d prefix_len + object_name + \u0027/\u0027"},{"line_number":337,"context_line":"        ts_source \u003d get_resp.headers.get("},{"line_number":338,"context_line":"            \u0027x-timestamp\u0027,"},{"line_number":339,"context_line":"            calendar.timegm(time.strptime("},{"line_number":340,"context_line":"                get_resp.headers[\u0027last-modified\u0027],"},{"line_number":341,"context_line":"                \u0027%a, %d %b %Y %H:%M:%S GMT\u0027)))"},{"line_number":342,"context_line":"        vers_obj_name \u003d lprefix + Timestamp(ts_source).internal"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a1b2928_810f9de0","line":339,"in_reply_to":"9a061dce_3ccb5920","updated":"2016-04-11 18:48:23.000000000","message":"Yeah, lines 335-341 always causes a lot of questions, but it\u0027s always been the old behavior so it never really get changed. There was a patch a while back to change line 335 but it never moved forward. Maybe we can address this in a separate patch?","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"183d9fc19efbd7f4005ac28f11748da327a9b90b","unresolved":false,"context_lines":[{"line_number":405,"context_line":"            # redirect the original DELETE to the source of the reinstated"},{"line_number":406,"context_line":"            # version object - we already auth\u0027d original req so make a"},{"line_number":407,"context_line":"            # pre-authed request"},{"line_number":408,"context_line":"            req \u003d make_pre_authed_request("},{"line_number":409,"context_line":"                req.environ, path\u003dget_path, method\u003d\u0027DELETE\u0027,"},{"line_number":410,"context_line":"                swift_source\u003d\u0027VW\u0027)"},{"line_number":411,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_f113fa62","line":408,"range":{"start_line":408,"start_character":12,"end_line":408,"end_character":15},"updated":"2016-04-08 18:47:32.000000000","message":"We seem to have lost our X-Auth-Token after being careful to keep it through GETs and PUTs; was this intentional?\n\nNot that the old version kept X-Auth-Token here...","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a2b432f7263ae9917e3688cf0b8ec7e4f0b70b0e","unresolved":false,"context_lines":[{"line_number":405,"context_line":"            # redirect the original DELETE to the source of the reinstated"},{"line_number":406,"context_line":"            # version object - we already auth\u0027d original req so make a"},{"line_number":407,"context_line":"            # pre-authed request"},{"line_number":408,"context_line":"            req \u003d make_pre_authed_request("},{"line_number":409,"context_line":"                req.environ, path\u003dget_path, method\u003d\u0027DELETE\u0027,"},{"line_number":410,"context_line":"                swift_source\u003d\u0027VW\u0027)"},{"line_number":411,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_495423fe","line":408,"range":{"start_line":408,"start_character":12,"end_line":408,"end_character":15},"in_reply_to":"1a122d0e_35801e8b","updated":"2016-04-19 17:03:08.000000000","message":"I think the idea is just to make it easier to trace through the requests in a session. When tracing through a single client request, it\u0027s easy enough to grep for a transaction ID. But if you want to follow someone through several requests, auth token would be easier.\n\nLike I said originally, the old version left it off. We definitely don\u0027t *need* it, but I\u0027ll add it as a follow-up.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"371c12a8ca18fb61eeec6d36837996316209da96","unresolved":false,"context_lines":[{"line_number":405,"context_line":"            # redirect the original DELETE to the source of the reinstated"},{"line_number":406,"context_line":"            # version object - we already auth\u0027d original req so make a"},{"line_number":407,"context_line":"            # pre-authed request"},{"line_number":408,"context_line":"            req \u003d make_pre_authed_request("},{"line_number":409,"context_line":"                req.environ, path\u003dget_path, method\u003d\u0027DELETE\u0027,"},{"line_number":410,"context_line":"                swift_source\u003d\u0027VW\u0027)"},{"line_number":411,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_35801e8b","line":408,"range":{"start_line":408,"start_character":12,"end_line":408,"end_character":15},"in_reply_to":"5a18252c_2c441eb5","updated":"2016-04-19 15:43:49.000000000","message":"I don\u0027t remember if it was intentional that x-auth-token was not kept here, but I think this code is correct as is.\n\nI don\u0027t think it is necessary. If the user has permission to DELETE (which became a PUT in this method) the object in the source container, then the middleware should be able to DELETE the previous version in the versions container (through this code path).\n\nThe user might not have actual acls to send a DELETE request directly to the versions container.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a395920c12b72f714b646140fb4cae79713ebe59","unresolved":false,"context_lines":[{"line_number":405,"context_line":"            # redirect the original DELETE to the source of the reinstated"},{"line_number":406,"context_line":"            # version object - we already auth\u0027d original req so make a"},{"line_number":407,"context_line":"            # pre-authed request"},{"line_number":408,"context_line":"            req \u003d make_pre_authed_request("},{"line_number":409,"context_line":"                req.environ, path\u003dget_path, method\u003d\u0027DELETE\u0027,"},{"line_number":410,"context_line":"                swift_source\u003d\u0027VW\u0027)"},{"line_number":411,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"5a18252c_2c441eb5","line":408,"range":{"start_line":408,"start_character":12,"end_line":408,"end_character":15},"in_reply_to":"9a061dce_f113fa62","updated":"2016-04-15 06:00:32.000000000","message":"Good point. Looking at current mechanism, X-Auth-Token seems needn\u0027t here because versioned_writes located in right place of any auth system. i.e. X-Auth-Token means nothing for the authentication.\n\nThinking about the security, the write permission will be checked when the put_versioned_obj happen at L401 so the client probably has the permission to write something into the versioned container. And then, if we don\u0027t use pre authed request and this DELETE fails for the permission check, (i.e. the client may not have the write permission of the container which keeps versioned objects), the client can not recover the older files into the versioned container via DELETE anymore. Circle back to the security consideration, IMHO, it seems ok to use pre authed request because the data which this request can delete should be recovered into the versioned container already and it is an evidence that the client has the permission to handle this object, anyway.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"183d9fc19efbd7f4005ac28f11748da327a9b90b","unresolved":false,"context_lines":[{"line_number":518,"context_line":"        # for backwards compatibility feature is enabled."},{"line_number":519,"context_line":"        versions_cont \u003d container_info.get("},{"line_number":520,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-location\u0027)"},{"line_number":521,"context_line":"        if versions_cont and isinstance(versions_cont, six.text_type):"},{"line_number":522,"context_line":"            versions_cont \u003d versions_cont.encode(\u0027utf-8\u0027)"},{"line_number":523,"context_line":"        elif not versions_cont:"},{"line_number":524,"context_line":"            versions_cont \u003d container_info.get(\u0027versions\u0027)"},{"line_number":525,"context_line":"            # if allow_versioned_writes is not set in the configuration files"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_c6d8be55","line":522,"range":{"start_line":521,"start_character":0,"end_line":522,"end_character":57},"updated":"2016-04-08 18:47:32.000000000","message":"nit: we could probably nix this block following https://review.openstack.org/#/c/267016/","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"400f7a3b0ce5b402bf126c18ec89096358b901c0","unresolved":false,"context_lines":[{"line_number":518,"context_line":"        # for backwards compatibility feature is enabled."},{"line_number":519,"context_line":"        versions_cont \u003d container_info.get("},{"line_number":520,"context_line":"            \u0027sysmeta\u0027, {}).get(\u0027versions-location\u0027)"},{"line_number":521,"context_line":"        if versions_cont and isinstance(versions_cont, six.text_type):"},{"line_number":522,"context_line":"            versions_cont \u003d versions_cont.encode(\u0027utf-8\u0027)"},{"line_number":523,"context_line":"        elif not versions_cont:"},{"line_number":524,"context_line":"            versions_cont \u003d container_info.get(\u0027versions\u0027)"},{"line_number":525,"context_line":"            # if allow_versioned_writes is not set in the configuration files"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a1b2928_0bf286d2","line":522,"range":{"start_line":521,"start_character":0,"end_line":522,"end_character":57},"in_reply_to":"9a061dce_c6d8be55","updated":"2016-04-11 18:48:23.000000000","message":"Done","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"183d9fc19efbd7f4005ac28f11748da327a9b90b","unresolved":false,"context_lines":[{"line_number":521,"context_line":"        if versions_cont and isinstance(versions_cont, six.text_type):"},{"line_number":522,"context_line":"            versions_cont \u003d versions_cont.encode(\u0027utf-8\u0027)"},{"line_number":523,"context_line":"        elif not versions_cont:"},{"line_number":524,"context_line":"            versions_cont \u003d container_info.get(\u0027versions\u0027)"},{"line_number":525,"context_line":"            # if allow_versioned_writes is not set in the configuration files"},{"line_number":526,"context_line":"            # but \u0027versions\u0027 is configured, enable feature to maintain"},{"line_number":527,"context_line":"            # backwards compatibility"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_2659ba8e","line":524,"range":{"start_line":524,"start_character":28,"end_line":524,"end_character":58},"updated":"2016-04-08 18:47:32.000000000","message":"We want a .split(\u0027/\u0027)[0] here. While any sysmeta value should be clean (thanks, check_container_format!), there could still be existing versioned containers that have a \"bad\" X-Versions-Location.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"400f7a3b0ce5b402bf126c18ec89096358b901c0","unresolved":false,"context_lines":[{"line_number":521,"context_line":"        if versions_cont and isinstance(versions_cont, six.text_type):"},{"line_number":522,"context_line":"            versions_cont \u003d versions_cont.encode(\u0027utf-8\u0027)"},{"line_number":523,"context_line":"        elif not versions_cont:"},{"line_number":524,"context_line":"            versions_cont \u003d container_info.get(\u0027versions\u0027)"},{"line_number":525,"context_line":"            # if allow_versioned_writes is not set in the configuration files"},{"line_number":526,"context_line":"            # but \u0027versions\u0027 is configured, enable feature to maintain"},{"line_number":527,"context_line":"            # backwards compatibility"}],"source_content_type":"text/x-python","patch_set":16,"id":"7a1b2928_04e8bb0f","line":524,"range":{"start_line":524,"start_character":28,"end_line":524,"end_character":58},"in_reply_to":"9a061dce_2659ba8e","updated":"2016-04-11 18:48:23.000000000","message":"Done","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"}],"test/functional/tests.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a1a1207933bd12e90b83a93e332190814cde1860","unresolved":false,"context_lines":[{"line_number":3920,"context_line":""},{"line_number":3921,"context_line":"        # expect the original manifest file to be restored"},{"line_number":3922,"context_line":"        self._assert_is_manifest(file_item, \u0027a\u0027)"},{"line_number":3923,"context_line":"        self._assert_is_object(file_item, \u0027a\u0027)"},{"line_number":3924,"context_line":""},{"line_number":3925,"context_line":""},{"line_number":3926,"context_line":"class TestTempurlEnv(object):"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_c33419fd","line":3923,"updated":"2016-04-08 10:20:15.000000000","message":"These tests are great, i found my mistake of pipline config in proxy-server.conf with this.\n\nNote that if versioned_writes placed in left side of slo/dlo middleware, these tests will probably fail.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"}],"test/unit/common/middleware/test_versioned_writes.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e8a6ce58de63956af350600214eaca291cb166a0","unresolved":false,"context_lines":[{"line_number":289,"context_line":"            \u0027PUT\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPOk, {}, \u0027passed\u0027)"},{"line_number":290,"context_line":"        self.app.register("},{"line_number":291,"context_line":"            \u0027GET\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPOk,"},{"line_number":292,"context_line":"            {\u0027last-modified\u0027: \u0027Thu, 1 Jan 1970 00:00:01 GMT\u0027}, \u0027passed\u0027)"},{"line_number":293,"context_line":"        self.app.register("},{"line_number":294,"context_line":"            \u0027PUT\u0027, \u0027/v1/a/ver_cont/001o/0000000001.00000\u0027, swob.HTTPOk,"},{"line_number":295,"context_line":"            {}, None)"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_5c54c251","line":292,"updated":"2016-01-22 21:15:11.000000000","message":"these tests failed on my machine, when rebased onto master, because the result of https://github.com/openstack/swift/blob/master/swift/common/middleware/versioned_writes.py#L212-212 came to be -3599 which is now an invalid value for a Timestamp.\n\nI worked around by setting my machine timezone to UTC. Maybe that\u0027s well-known? But it might be an idea to use a time that is \u003e0 in any timezone.","commit_id":"26598c2e9008fcc71afa1d3c80fa167d8eeda9d2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4576fb9fcac56fff52d92bc25494bacd85fd619","unresolved":false,"context_lines":[{"line_number":134,"context_line":"            status, headers, body \u003d self.call_vw(req)"},{"line_number":135,"context_line":"            self.assertEqual(status, \"412 Precondition Failed\")"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        # GET performs as normal"},{"line_number":138,"context_line":"        self.app.register(\u0027GET\u0027, \u0027/v1/a/c\u0027, swob.HTTPOk, {}, \u0027passed\u0027)"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"        for method in (\u0027GET\u0027, \u0027HEAD\u0027):"}],"source_content_type":"text/x-python","patch_set":6,"id":"dae33548_751654a8","line":137,"updated":"2016-02-16 16:46:53.000000000","message":"HEAD is still being checked","commit_id":"0503d96e26b33ea7426fc8a6dd4002f3e5b28f41"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4576fb9fcac56fff52d92bc25494bacd85fd619","unresolved":false,"context_lines":[{"line_number":158,"context_line":"        self.assertEqual(\u0027POST\u0027, method)"},{"line_number":159,"context_line":"        self.assertEqual(\u0027/v1/a/c\u0027, path)"},{"line_number":160,"context_line":"        self.assertTrue(\u0027x-container-sysmeta-versions-location\u0027 in req_headers)"},{"line_number":161,"context_line":"        self.assertTrue(\u0027x-versions-location\u0027 in req_headers)"},{"line_number":162,"context_line":"        self.assertEqual(len(self.authorized), 1)"},{"line_number":163,"context_line":"        self.assertRequestEqual(req, self.authorized[0])"},{"line_number":164,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"dae33548_f5f42488","line":161,"updated":"2016-02-16 16:46:53.000000000","message":"should be checking the value of these two headers.\n\n(I see they are not checked in the existing test_remove_versions_location test so same applies there)","commit_id":"0503d96e26b33ea7426fc8a6dd4002f3e5b28f41"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4576fb9fcac56fff52d92bc25494bacd85fd619","unresolved":false,"context_lines":[{"line_number":264,"context_line":"        status, headers, body \u003d self.call_vw(req)"},{"line_number":265,"context_line":"        self.assertEqual(status, \u0027200 OK\u0027)"},{"line_number":266,"context_line":"        self.assertEqual(len(self.authorized), 1)"},{"line_number":267,"context_line":"        self.assertRequestEqual(req, self.authorized[0])"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    def test_put_object_no_versioning_with_container_config_true(self):"},{"line_number":270,"context_line":"        # set False to versions_write and expect no GET occurred"}],"source_content_type":"text/x-python","patch_set":6,"id":"dae33548_b539fc43","line":267,"updated":"2016-02-16 16:46:53.000000000","message":"hmmm, nothing in this test actually asserts that the object PUT is made. \n\n        self.assertEqual((\u0027GET\u0027, \u0027/v1/a/c/o\u0027),\n                         self.app.calls_with_headers[0][0:2])\n        self.assertEqual((\u0027PUT\u0027, \u0027/v1/a/c/o\u0027),\n                         self.app.calls_with_headers[1][0:2])","commit_id":"0503d96e26b33ea7426fc8a6dd4002f3e5b28f41"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4576fb9fcac56fff52d92bc25494bacd85fd619","unresolved":false,"context_lines":[{"line_number":283,"context_line":"        called_method \u003d [method for (method, path, hdrs) in self.app._calls]"},{"line_number":284,"context_line":"        self.assertTrue(\u0027GET\u0027 not in called_method)"},{"line_number":285,"context_line":""},{"line_number":286,"context_line":"    def test_put_object_manifest_with_container_config_true(self):"},{"line_number":287,"context_line":"        # set x-object-manifest on request and expect no versioning occurred"},{"line_number":288,"context_line":"        self.app.register("},{"line_number":289,"context_line":"            \u0027PUT\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPCreated, {}, \u0027passed\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"dae33548_586425e3","line":286,"updated":"2016-02-16 16:46:53.000000000","message":"nit: s/object_manifest/dlo_manifest/","commit_id":"0503d96e26b33ea7426fc8a6dd4002f3e5b28f41"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4576fb9fcac56fff52d92bc25494bacd85fd619","unresolved":false,"context_lines":[{"line_number":288,"context_line":"        self.app.register("},{"line_number":289,"context_line":"            \u0027PUT\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPCreated, {}, \u0027passed\u0027)"},{"line_number":290,"context_line":"        self.app.register("},{"line_number":291,"context_line":"            \u0027GET\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPOk, {}, \u0027passed\u0027)"},{"line_number":292,"context_line":"        cache \u003d FakeCache({\u0027versions\u0027: \u0027ver_cont\u0027})"},{"line_number":293,"context_line":"        req \u003d Request.blank("},{"line_number":294,"context_line":"            \u0027/v1/a/c/o\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"dae33548_9e2df548","line":291,"updated":"2016-02-16 16:46:53.000000000","message":"interesting, so we do a GET even though the inbound request is a manifest, then we discard the GET response?\n\nlooks like we should avoid the GET in this case!","commit_id":"0503d96e26b33ea7426fc8a6dd4002f3e5b28f41"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4576fb9fcac56fff52d92bc25494bacd85fd619","unresolved":false,"context_lines":[{"line_number":304,"context_line":"        # initial GET on source object ok, but not a PUT to version location"},{"line_number":305,"context_line":"        # only the PUT for the original client request"},{"line_number":306,"context_line":"        self.assertEqual(called_method.count(\u0027GET\u0027), 1)"},{"line_number":307,"context_line":"        self.assertEqual(called_method.count(\u0027PUT\u0027), 1)"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"        # set x-object-manifest on response and expect no versioning occurred"},{"line_number":310,"context_line":"        self.app.register(\u0027GET\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPOk,"}],"source_content_type":"text/x-python","patch_set":6,"id":"dae33548_184d7d3e","line":307,"updated":"2016-02-16 16:46:53.000000000","message":"check the paths of the calls","commit_id":"0503d96e26b33ea7426fc8a6dd4002f3e5b28f41"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4576fb9fcac56fff52d92bc25494bacd85fd619","unresolved":false,"context_lines":[{"line_number":306,"context_line":"        self.assertEqual(called_method.count(\u0027GET\u0027), 1)"},{"line_number":307,"context_line":"        self.assertEqual(called_method.count(\u0027PUT\u0027), 1)"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"        # set x-object-manifest on response and expect no versioning occurred"},{"line_number":310,"context_line":"        self.app.register(\u0027GET\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPOk,"},{"line_number":311,"context_line":"                          {\u0027X-Object-Manifest\u0027: \u0027resp/manifest\u0027}, \u0027passed\u0027)"},{"line_number":312,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"dae33548_987a2df0","line":309,"updated":"2016-02-16 16:46:53.000000000","message":"I suggest making this a new test method to avoid confusion over the accumulation of requests captured by FakeSwift._calls","commit_id":"0503d96e26b33ea7426fc8a6dd4002f3e5b28f41"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4576fb9fcac56fff52d92bc25494bacd85fd619","unresolved":false,"context_lines":[{"line_number":408,"context_line":"            \u0027GET\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPOk,"},{"line_number":409,"context_line":"            {\u0027last-modified\u0027: \u0027Thu, 1 Jan 1970 00:00:01 GMT\u0027}, \u0027passed\u0027)"},{"line_number":410,"context_line":"        self.app.register("},{"line_number":411,"context_line":"            \u0027PUT\u0027, \u0027/v1/a/ver_cont/001o/0000000001.00000\u0027, swob.HTTPBadRequest,"},{"line_number":412,"context_line":"            {}, None)"},{"line_number":413,"context_line":"        cache \u003d FakeCache({\u0027sysmeta\u0027: {\u0027versions-location\u0027: \u0027ver_cont\u0027}})"},{"line_number":414,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":6,"id":"dae33548_3ee2e99f","line":411,"updated":"2016-02-16 16:46:53.000000000","message":"more realistic would be a HTTPUnauthorized","commit_id":"0503d96e26b33ea7426fc8a6dd4002f3e5b28f41"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4576fb9fcac56fff52d92bc25494bacd85fd619","unresolved":false,"context_lines":[{"line_number":666,"context_line":"        self.assertEqual(len(authorize_call), 1)"},{"line_number":667,"context_line":"        self.assertRequestEqual(req, authorize_call[0])"},{"line_number":668,"context_line":""},{"line_number":669,"context_line":"    def test_delete_latest_version_errors(self):"},{"line_number":670,"context_line":"        self.app.register("},{"line_number":671,"context_line":"            \u0027GET\u0027,"},{"line_number":672,"context_line":"            \u0027/v1/a/ver_cont?format\u003djson\u0026prefix\u003d001o/\u0026reverse\u003don\u0026marker\u003d\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"dae33548_afbd216a","line":669,"updated":"2016-02-16 16:46:53.000000000","message":"split into separate tests so that the FakeSwift app calls can be better tracked","commit_id":"0503d96e26b33ea7426fc8a6dd4002f3e5b28f41"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"da631ba657074197d9a5e452bace4b867684d3e6","unresolved":false,"context_lines":[{"line_number":374,"context_line":"            \u0027GET\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPOk,"},{"line_number":375,"context_line":"            {\u0027last-modified\u0027: \u0027Thu, 1 Jan 1970 00:00:01 GMT\u0027}, \u0027passed\u0027)"},{"line_number":376,"context_line":"        self.app.register("},{"line_number":377,"context_line":"            \u0027PUT\u0027, \u0027/v1/a/ver_cont/001o/0000000001.00000\u0027, swob.HTTPOk,"},{"line_number":378,"context_line":"            {}, None)"},{"line_number":379,"context_line":"        cache \u003d FakeCache({\u0027sysmeta\u0027: {\u0027versions-location\u0027: \u0027ver_cont\u0027}})"},{"line_number":380,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":15,"id":"9a061dce_16e80d7c","line":377,"range":{"start_line":377,"start_character":64,"end_line":377,"end_character":70},"updated":"2016-04-04 11:22:26.000000000","message":"nits) HTTPCreated","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"692fe07ca15ed7445b80243c4b1cf61faa900cc9","unresolved":false,"context_lines":[{"line_number":374,"context_line":"            \u0027GET\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPOk,"},{"line_number":375,"context_line":"            {\u0027last-modified\u0027: \u0027Thu, 1 Jan 1970 00:00:01 GMT\u0027}, \u0027passed\u0027)"},{"line_number":376,"context_line":"        self.app.register("},{"line_number":377,"context_line":"            \u0027PUT\u0027, \u0027/v1/a/ver_cont/001o/0000000001.00000\u0027, swob.HTTPOk,"},{"line_number":378,"context_line":"            {}, None)"},{"line_number":379,"context_line":"        cache \u003d FakeCache({\u0027sysmeta\u0027: {\u0027versions-location\u0027: \u0027ver_cont\u0027}})"},{"line_number":380,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":15,"id":"9a061dce_3b3008e8","line":377,"range":{"start_line":377,"start_character":64,"end_line":377,"end_character":70},"in_reply_to":"9a061dce_16e80d7c","updated":"2016-04-06 15:49:00.000000000","message":"Done","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"da631ba657074197d9a5e452bace4b867684d3e6","unresolved":false,"context_lines":[{"line_number":383,"context_line":"                     \u0027CONTENT_LENGTH\u0027: \u0027100\u0027,"},{"line_number":384,"context_line":"                     \u0027swift.trans_id\u0027: \u0027fake_trans_id\u0027})"},{"line_number":385,"context_line":"        status, headers, body \u003d self.call_vw(req)"},{"line_number":386,"context_line":"        self.assertEqual(status, \u0027200 OK\u0027)"},{"line_number":387,"context_line":"        self.assertEqual(len(self.authorized), 1)"},{"line_number":388,"context_line":"        self.assertRequestEqual(req, self.authorized[0])"},{"line_number":389,"context_line":"        self.assertEqual([\u0027VW\u0027, \u0027VW\u0027, None], self.app.swift_sources)"}],"source_content_type":"text/x-python","patch_set":15,"id":"9a061dce_96937dfa","line":386,"updated":"2016-04-04 11:22:26.000000000","message":"nits) 201 Created","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"692fe07ca15ed7445b80243c4b1cf61faa900cc9","unresolved":false,"context_lines":[{"line_number":383,"context_line":"                     \u0027CONTENT_LENGTH\u0027: \u0027100\u0027,"},{"line_number":384,"context_line":"                     \u0027swift.trans_id\u0027: \u0027fake_trans_id\u0027})"},{"line_number":385,"context_line":"        status, headers, body \u003d self.call_vw(req)"},{"line_number":386,"context_line":"        self.assertEqual(status, \u0027200 OK\u0027)"},{"line_number":387,"context_line":"        self.assertEqual(len(self.authorized), 1)"},{"line_number":388,"context_line":"        self.assertRequestEqual(req, self.authorized[0])"},{"line_number":389,"context_line":"        self.assertEqual([\u0027VW\u0027, \u0027VW\u0027, None], self.app.swift_sources)"}],"source_content_type":"text/x-python","patch_set":15,"id":"9a061dce_5b333cf6","line":386,"in_reply_to":"9a061dce_96937dfa","updated":"2016-04-06 15:49:00.000000000","message":"Done","commit_id":"ffd35afa07b9a7c818e617b1ad9807cf110016b6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"58afadde99fc251889d6fec05a3c1a876e851628","unresolved":false,"context_lines":[{"line_number":333,"context_line":""},{"line_number":334,"context_line":"    def test_delete_object_no_versioning_with_container_config_true(self):"},{"line_number":335,"context_line":"        # set False to versions_write obviously and expect no GET versioning"},{"line_number":336,"context_line":"        # container and COPY called (just delete object as normal)"},{"line_number":337,"context_line":"        self.vw.conf \u003d {\u0027allow_versioned_writes\u0027: \u0027false\u0027}"},{"line_number":338,"context_line":"        self.app.register("},{"line_number":339,"context_line":"            \u0027DELETE\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPNoContent, {}, \u0027passed\u0027)"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_6793d5fa","line":336,"updated":"2016-04-11 16:47:01.000000000","message":"s/COPY/PUT/","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a1a1207933bd12e90b83a93e332190814cde1860","unresolved":false,"context_lines":[{"line_number":590,"context_line":"            \u0027\"name\": \"001o/1\", \u0027"},{"line_number":591,"context_line":"            \u0027\"content_type\": \"text/plain\"}]\u0027)"},{"line_number":592,"context_line":"        self.app.register("},{"line_number":593,"context_line":"            \u0027GET\u0027, \u0027/v1/a/ver_cont/001o/2\u0027, swob.HTTPCreated,"},{"line_number":594,"context_line":"            {\u0027content-length\u0027: \u00273\u0027}, None)"},{"line_number":595,"context_line":"        self.app.register("},{"line_number":596,"context_line":"            \u0027PUT\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPCreated, {}, None)"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_5ac9db77","line":593,"updated":"2016-04-08 10:20:15.000000000","message":"nits) ah, this should be HTTPOk :P","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a1a1207933bd12e90b83a93e332190814cde1860","unresolved":false,"context_lines":[{"line_number":591,"context_line":"            \u0027\"content_type\": \"text/plain\"}]\u0027)"},{"line_number":592,"context_line":"        self.app.register("},{"line_number":593,"context_line":"            \u0027GET\u0027, \u0027/v1/a/ver_cont/001o/2\u0027, swob.HTTPCreated,"},{"line_number":594,"context_line":"            {\u0027content-length\u0027: \u00273\u0027}, None)"},{"line_number":595,"context_line":"        self.app.register("},{"line_number":596,"context_line":"            \u0027PUT\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPCreated, {}, None)"},{"line_number":597,"context_line":"        self.app.register("}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_facb8f70","line":594,"updated":"2016-04-08 10:20:15.000000000","message":"nits) we should set 3 bytes body here even if the PUT for this doesn\u0027t raise 499 ClientDisconnected.","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a1a1207933bd12e90b83a93e332190814cde1860","unresolved":false,"context_lines":[{"line_number":595,"context_line":"        self.app.register("},{"line_number":596,"context_line":"            \u0027PUT\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPCreated, {}, None)"},{"line_number":597,"context_line":"        self.app.register("},{"line_number":598,"context_line":"            \u0027DELETE\u0027, \u0027/v1/a/ver_cont/001o/2\u0027, swob.HTTPOk,"},{"line_number":599,"context_line":"            {}, None)"},{"line_number":600,"context_line":""},{"line_number":601,"context_line":"        cache \u003d FakeCache({\u0027sysmeta\u0027: {\u0027versions-location\u0027: \u0027ver_cont\u0027}})"}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_9aa1b3ac","line":598,"updated":"2016-04-08 10:20:15.000000000","message":"nits) And HTTPNoContent?","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a1a1207933bd12e90b83a93e332190814cde1860","unresolved":false,"context_lines":[{"line_number":640,"context_line":"            \u0027\"content_type\": \"text/plain\"}]\u0027)"},{"line_number":641,"context_line":"        self.app.register("},{"line_number":642,"context_line":"            \u0027GET\u0027, \u0027/v1/a/ver_cont/001o/1\u0027, swob.HTTPOk,"},{"line_number":643,"context_line":"            {\u0027content-length\u0027: \u00273\u0027}, None)"},{"line_number":644,"context_line":"        self.app.register("},{"line_number":645,"context_line":"            \u0027PUT\u0027, \u0027/v1/a/c/o\u0027, swob.HTTPCreated, {}, None)"},{"line_number":646,"context_line":"        self.app.register("}],"source_content_type":"text/x-python","patch_set":16,"id":"9a061dce_1a42c33e","line":643,"range":{"start_line":643,"start_character":36,"end_line":643,"end_character":41},"updated":"2016-04-08 10:20:15.000000000","message":"same as above","commit_id":"4b616a763657b5b2090113baf555d36ff755e73c"}]}
