)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"a1341897f75e97aacae6e81fdfaa3e7611a46a02","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add containeralias middleware"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This middleware allows to set a metadata entry \"alias\" to an container."},{"line_number":10,"context_line":"Requests to a container with an alias-metadata entry will be redirected"},{"line_number":11,"context_line":"to the account/container value from the metadata entry. Think of it like"},{"line_number":12,"context_line":"symlinks for Swift containers."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"AAAAUX%2F%2BdGE%3D","line":9,"updated":"2014-02-21 03:14:24.000000000","message":"\"a container\"","commit_id":"ea5a546e56d03fbf87bc496dac5ea68791dad9ad"}],"swift/common/middleware/containeralias.py":[{"author":{"_account_id":9205,"name":"Gil Vernik","email":"gilv@il.ibm.com","username":"gilv"},"change_message_id":"af3f9d3ccf9b0f97bc1b000b59b37e63bc8a4e5c","unresolved":false,"context_lines":[{"line_number":92,"context_line":"                    if container_alias:"},{"line_number":93,"context_line":"                        return HTTPBadRequest()"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        if container:"},{"line_number":96,"context_line":"            container_info \u003d get_container_info(request.environ, self.app)"},{"line_number":97,"context_line":"            alias \u003d container_info.get(\u0027meta\u0027, {}).get(\u0027alias\u0027)"},{"line_number":98,"context_line":"            if alias:"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAUH%2F%2Fs9M%3D","line":95,"updated":"2014-01-09 13:19:29.000000000","message":"Any POST to container will enter both here and into condition in line 59. It will do twice get_container_info for example.  There are more duplicate code.\n\nIn addition, any PUT to create any new container - container_info here will return status 404, since container is not yet exists.","commit_id":"17e6211cae915a529ea779aa09282c01cc2608f3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"26fbb57a5847e53ad2dc35cb3e0f2d45a8a0b229","unresolved":false,"context_lines":[{"line_number":108,"context_line":""},{"line_number":109,"context_line":"            # Return Not Found if target container does not exist"},{"line_number":110,"context_line":"            status \u003d container_info_alias.get(\u0027status\u0027)"},{"line_number":111,"context_line":"            if not status:"},{"line_number":112,"context_line":"                return HTTPNotFound()(env, start_response)"},{"line_number":113,"context_line":"            # make sure there is no alias on the target container"},{"line_number":114,"context_line":"            # otherwise loops could be created"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAUH%2F%2FROc%3D","line":111,"updated":"2014-01-15 16:51:40.000000000","message":"I think you need to test for 200 \u003c\u003d status \u003c300","commit_id":"45275567d1d12f93d64790378626f699c5c11c20"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"a1341897f75e97aacae6e81fdfaa3e7611a46a02","unresolved":false,"context_lines":[{"line_number":114,"context_line":"                request.environ, self.app)"},{"line_number":115,"context_line":"            request.environ[\u0027PATH_INFO\u0027] \u003d old_path_info"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"            # Return Not Found if target container does not exist"},{"line_number":118,"context_line":"            status \u003d container_info_alias.get(\u0027status\u0027)"},{"line_number":119,"context_line":"            if not is_success(int(status)):"},{"line_number":120,"context_line":"                return HTTPBadRequest("}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAUX%2F%2BdC0%3D","line":117,"updated":"2014-02-21 03:14:24.000000000","message":"IMHO, pointless. The target can be deleted any time, resulting in the situation you\u0027re trying to prevent here.\n\nBelow there\u0027s a check for loops, which also can be defeated, but works as a useful advance warning to someone who\u0027s making an honest mistake. This one, however, may make sense to allow.","commit_id":"ea5a546e56d03fbf87bc496dac5ea68791dad9ad"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"40daeadff9619054c8caeaba3d421aafed6c6d8a","unresolved":false,"context_lines":[{"line_number":43,"context_line":"post container -H \u0027X-Container-Alias:\u0027"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"As long as an alias is set all requests to that container are redirected to"},{"line_number":46,"context_line":"the target container except alias updates. That also means that DELETE and"},{"line_number":47,"context_line":"HEAD requests are redirected to the alias container."},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"An additional header ``X-Container-Alias`` is returned when the request path"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAVn%2F%2FhzM%3D","line":46,"updated":"2014-03-05 17:20:04.000000000","message":"I wasn\u0027t expecting this behaviour i.e. that if container c1 is redirected to c2 then DELETE c1 will actually delete c2. I was expecting it to behave like a symlink i.e. that DELETE c1 would leave c2 in place and just delete c1.","commit_id":"243d51b5b170862cea455d499d0eb2ee6a9754e3"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"8f62e170c17bd8fd8648a57e7e3b61a31eec4558","unresolved":false,"context_lines":[{"line_number":43,"context_line":"post container -H \u0027X-Container-Alias:\u0027"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"As long as an alias is set all requests to that container are redirected to"},{"line_number":46,"context_line":"the target container except alias updates. That also means that DELETE and"},{"line_number":47,"context_line":"HEAD requests are redirected to the alias container."},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"An additional header ``X-Container-Alias`` is returned when the request path"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAVn%2F%2FaUw%3D","line":46,"in_reply_to":"AAAAVn%2F%2FhzM%3D","updated":"2014-03-06 08:46:11.000000000","message":"Yes, that makes much more sense to me, I\u0027ll change that.","commit_id":"243d51b5b170862cea455d499d0eb2ee6a9754e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"40daeadff9619054c8caeaba3d421aafed6c6d8a","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        except ValueError:"},{"line_number":77,"context_line":"            return self.app(env, start_response)"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        if not container:"},{"line_number":80,"context_line":"            return self.app(env, start_response)"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"        container_info \u003d get_container_info(request.environ, self.app)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAVn%2F%2FhQ0%3D","line":79,"updated":"2014-03-05 17:20:04.000000000","message":"if objname or not container:\n\notherwise if i accidentally include x-container-alias header with an *object* POST then the request fails to be redirected.","commit_id":"243d51b5b170862cea455d499d0eb2ee6a9754e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"484c2b6f3d34644650eafc6636e5c46dfcdf0042","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        except ValueError:"},{"line_number":77,"context_line":"            return self.app(env, start_response)"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        if not container:"},{"line_number":80,"context_line":"            return self.app(env, start_response)"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"        container_info \u003d get_container_info(request.environ, self.app)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAVn%2F%2FgWA%3D","line":79,"in_reply_to":"AAAAVn%2F%2FhQ0%3D","updated":"2014-03-05 18:03:45.000000000","message":"ignore, comment in wrong place","commit_id":"243d51b5b170862cea455d499d0eb2ee6a9754e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"484c2b6f3d34644650eafc6636e5c46dfcdf0042","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        container_info \u003d get_container_info(request.environ, self.app)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"        new_container_alias \u003d request.headers.get(\u0027X-Container-Alias\u0027)"},{"line_number":85,"context_line":"        if request.method \u003d\u003d \u0027POST\u0027 and new_container_alias is not None:"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"            # Save the alias setting as system metadata"},{"line_number":88,"context_line":"            request.headers[\u0027X-Container-Sysmeta-Alias\u0027] \u003d new_container_alias"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAVn%2F%2FgTM%3D","line":85,"updated":"2014-03-05 18:03:45.000000000","message":"add  \u0027not objname\u0027 condition here","commit_id":"243d51b5b170862cea455d499d0eb2ee6a9754e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"40daeadff9619054c8caeaba3d421aafed6c6d8a","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        container_info \u003d get_container_info(request.environ, self.app)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"        new_container_alias \u003d request.headers.get(\u0027X-Container-Alias\u0027)"},{"line_number":85,"context_line":"        if request.method \u003d\u003d \u0027POST\u0027 and new_container_alias is not None:"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"            # Save the alias setting as system metadata"},{"line_number":88,"context_line":"            request.headers[\u0027X-Container-Sysmeta-Alias\u0027] \u003d new_container_alias"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAVn%2F%2Fhxo%3D","line":85,"updated":"2014-03-05 17:20:04.000000000","message":"why not also on PUT?","commit_id":"243d51b5b170862cea455d499d0eb2ee6a9754e3"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"8f62e170c17bd8fd8648a57e7e3b61a31eec4558","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        container_info \u003d get_container_info(request.environ, self.app)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"        new_container_alias \u003d request.headers.get(\u0027X-Container-Alias\u0027)"},{"line_number":85,"context_line":"        if request.method \u003d\u003d \u0027POST\u0027 and new_container_alias is not None:"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"            # Save the alias setting as system metadata"},{"line_number":88,"context_line":"            request.headers[\u0027X-Container-Sysmeta-Alias\u0027] \u003d new_container_alias"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAVn%2F%2FaYo%3D","line":85,"in_reply_to":"AAAAVn%2F%2FgTM%3D","updated":"2014-03-06 08:46:11.000000000","message":"Oh, I just forgot the PUT, thanks - I\u0027m always using POST to change metadata. I\u0027ll also include the \u0027not objname\u0027.","commit_id":"243d51b5b170862cea455d499d0eb2ee6a9754e3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"40daeadff9619054c8caeaba3d421aafed6c6d8a","unresolved":false,"context_lines":[{"line_number":112,"context_line":""},{"line_number":113,"context_line":"        def _start_response(status, headers, exc_info\u003dNone):"},{"line_number":114,"context_line":"            if alias:"},{"line_number":115,"context_line":"                headers.append((\u0027X-Container-Alias\u0027, alias))"},{"line_number":116,"context_line":"            return start_response(status, headers, exc_info)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"        return self.app(env, _start_response)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAVn%2F%2FiiI%3D","line":115,"updated":"2014-03-05 17:20:04.000000000","message":"I was surprised to see \u0027x-container-alias: /AUTH_test/container_name/object_name\u0027 returned in response to an object request I made - only because when the object name is appended its no longer the x-container-alias value I provided, and its really an object-alias. I\u0027m not saying that is wrong, and I understand its usefulness, I just wonder if a different response header name would be less confusing? I don\u0027t know...just x-alias maybe??\n\nAlso, if container c1 is redirected to c2, and c2 is redirected to c3, then when I do a HEAD on c1 I get x-container-alias:c2 because the middleware has overwritten the x-container-alias:c3 metadata returned from c2. So I am not seeing the complete metadata from c2.\n\nThe alternative would be for the middleware to leave the actual metadata from c2 unchanged (x-container-alias:c3 metadata) AND add a different header (such as x-alias:c2) telling me the request was redirected.","commit_id":"243d51b5b170862cea455d499d0eb2ee6a9754e3"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"8f62e170c17bd8fd8648a57e7e3b61a31eec4558","unresolved":false,"context_lines":[{"line_number":112,"context_line":""},{"line_number":113,"context_line":"        def _start_response(status, headers, exc_info\u003dNone):"},{"line_number":114,"context_line":"            if alias:"},{"line_number":115,"context_line":"                headers.append((\u0027X-Container-Alias\u0027, alias))"},{"line_number":116,"context_line":"            return start_response(status, headers, exc_info)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"        return self.app(env, _start_response)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAVn%2F%2FaZM%3D","line":115,"in_reply_to":"AAAAVn%2F%2FiiI%3D","updated":"2014-03-06 08:46:11.000000000","message":"I like the idea to just use a different header. This will catch both issues and inform the user that the request was redirected without overwriting any existing metadata.\n\nI would suggest to use \u0027X-Alias-Redirected\u0027 to make it clear to the user that there is a redirection in place?","commit_id":"243d51b5b170862cea455d499d0eb2ee6a9754e3"},{"author":{"_account_id":2649,"name":"Zhang Hua","email":"zhuadl@cn.ibm.com","username":"zhang-hare"},"change_message_id":"4121c58a852ef006cfaaf00cbc995a56c9341f12","unresolved":false,"context_lines":[{"line_number":46,"context_line":"the target container except alias updates (using PUT/POST) and container"},{"line_number":47,"context_line":"DELETE requests."},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"An additional header ``X-Alias-Redirected-Redirected`` is returned when the"},{"line_number":50,"context_line":"request path was modified because of an alias. The header displays the full"},{"line_number":51,"context_line":"aliased path, informing the client where the request was redirected to."},{"line_number":52,"context_line":"\"\"\""}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAVn%2F%2FSCc%3D","line":49,"updated":"2014-03-07 03:30:27.000000000","message":"X-Alias-Redirected?","commit_id":"f206cf562f12489e9078261b2bdee7f9e5b9ae2f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"545372647fd9515dff877171bc09e74fa77a381f","unresolved":false,"context_lines":[{"line_number":120,"context_line":"            # is empty when setting an alias but a PUT at the same stored some"},{"line_number":121,"context_line":"            # data in it. To prevent silent hiding of these objects check if"},{"line_number":122,"context_line":"            # the alias container is really empty. Since we already have"},{"line_number":123,"context_line":"            # container_info no additional request is needed."},{"line_number":124,"context_line":"            objects \u003d container_info.get(\u0027object_count\u0027)"},{"line_number":125,"context_line":"            if objects and int(objects) \u003e 0:"},{"line_number":126,"context_line":"                msg \u003d \u0027Alias container contains objects\u0027"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F%2FCGw%3D","line":123,"updated":"2014-03-20 19:21:13.000000000","message":"Hmmm, what about if the container has user metadata? Are we happy to \u0027hide\u0027 that by aliasing or should that be treated in the same way as object content? i.e should there be a test here for user metadata in the container info? At least metadata does not show up as byte count in the container listings.","commit_id":"a1cc6c59a51da9f97f61be97096582038d0cab82"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"545372647fd9515dff877171bc09e74fa77a381f","unresolved":false,"context_lines":[{"line_number":123,"context_line":"            # container_info no additional request is needed."},{"line_number":124,"context_line":"            objects \u003d container_info.get(\u0027object_count\u0027)"},{"line_number":125,"context_line":"            if objects and int(objects) \u003e 0:"},{"line_number":126,"context_line":"                msg \u003d \u0027Alias container contains objects\u0027"},{"line_number":127,"context_line":"                return HTTPConflict(msg)(env, start_response)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"            if objname:"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F%2FCPA%3D","line":126,"updated":"2014-03-20 19:21:13.000000000","message":"msg gets lost from response if request is a HEAD","commit_id":"a1cc6c59a51da9f97f61be97096582038d0cab82"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"545372647fd9515dff877171bc09e74fa77a381f","unresolved":false,"context_lines":[{"line_number":137,"context_line":"            dst_info \u003d get_container_info(request.environ, self.app)"},{"line_number":138,"context_line":"            status \u003d int(dst_info.get(\u0027status\u0027, 0))"},{"line_number":139,"context_line":"            if not (status // 100 \u003d\u003d 2):"},{"line_number":140,"context_line":"                msg \u003d \u0027Alias target container missing\u0027"},{"line_number":141,"context_line":"                return HTTPConflict(msg)(env, start_response)"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        def _start_response(status, headers, exc_info\u003dNone):"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F%2FCPQ%3D","line":140,"updated":"2014-03-20 19:21:13.000000000","message":"msg gets lost from response if request is a HEAD","commit_id":"a1cc6c59a51da9f97f61be97096582038d0cab82"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"545372647fd9515dff877171bc09e74fa77a381f","unresolved":false,"context_lines":[{"line_number":138,"context_line":"            status \u003d int(dst_info.get(\u0027status\u0027, 0))"},{"line_number":139,"context_line":"            if not (status // 100 \u003d\u003d 2):"},{"line_number":140,"context_line":"                msg \u003d \u0027Alias target container missing\u0027"},{"line_number":141,"context_line":"                return HTTPConflict(msg)(env, start_response)"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        def _start_response(status, headers, exc_info\u003dNone):"},{"line_number":144,"context_line":"            if alias:"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F%2FCPs%3D","line":141,"updated":"2014-03-20 19:21:13.000000000","message":"This is a privacy leak - if the container exists but I do not have permission to access it I get a 403, if it does not exist I get a 409. That means I can probe another user\u0027s account to see what container names (do not) exist.\n\nIn previous patch I think I always got a 403 if I was not permitted access - if container existed or not.\n\nMaybe a better approach would be to allow the request to proceed, if it fails and it is a container request then map response code to a 409 \u0027Alias container is inaccessible - it may be missing or you may not have permission to access it.\u0027","commit_id":"a1cc6c59a51da9f97f61be97096582038d0cab82"},{"author":{"_account_id":860,"name":"Donagh McCabe","email":"donagh.mccabe@gmail.com","username":"donagh-mccabe"},"change_message_id":"1cae6444964404524c2cf3d1426f198bcdd973f8","unresolved":false,"context_lines":[{"line_number":46,"context_line":"As long as an alias is set all requests to that container are redirected to"},{"line_number":47,"context_line":"the target container except alias updates (using PUT/POST) and container"},{"line_number":48,"context_line":"DELETE requests."},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"An additional header ``X-Alias-Redirected`` is returned when the"},{"line_number":51,"context_line":"request path was modified because of an alias. The header displays the full"},{"line_number":52,"context_line":"aliased path, informing the client where the request was redirected to."}],"source_content_type":"text/x-python","patch_set":20,"id":"ba15a1d1_6fb223e7","line":49,"updated":"2015-09-23 13:00:39.000000000","message":"You should explain what access rights a user needs to use this feature.\n\nFor example, if I have a container as follows:\n\nAUTH_1234/container1 has X-Container-Alias: AUTH_5678/container1_alias\n\nSo, to do a PUT, you need read access to AUTH_1234/container1 and write access to AUTH_5678/container1_alias. Does sysmeta access need swift_owner or is an ACL enough (for the read access to AUTH_1234). Is my understanding correct?","commit_id":"e9b0a60d1b92935cd3bf2078b50bea42d1a63280"}]}
