)]}'
{"swift/common/constraints.py":[{"author":{"_account_id":2696,"name":"Darrell Bishop","email":"dbishop@nvidia.com","username":"darrellb"},"change_message_id":"1ae77f1461c9a4711798c9b5746d89e7c1bc76e7","unresolved":false,"context_lines":[{"line_number":214,"context_line":"        return False"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":""},{"line_number":217,"context_line":"def check_copy_from_header(req):"},{"line_number":218,"context_line":"    src_header \u003d unquote(req.headers.get(\u0027X-Copy-From\u0027))"},{"line_number":219,"context_line":"    if not src_header.startswith(\u0027/\u0027):"},{"line_number":220,"context_line":"        src_header \u003d \u0027/\u0027 + src_header"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2BGKw%3D","line":217,"updated":"2013-12-02 16:19:52.000000000","message":"Can you add a docstring for this utility method?  Be sure to mention that the caller is responsible for ensuring the header exists in req.headers prior to calling check_copy_from_header().  Both callers in this patch currently do that, but just passing a request to this function willy-nilly is a bug waiting to be written in the future.","commit_id":"586a431ff0861f6d700a512cee6fb7a03f9fb88d"},{"author":{"_account_id":2696,"name":"Darrell Bishop","email":"dbishop@nvidia.com","username":"darrellb"},"change_message_id":"1ae77f1461c9a4711798c9b5746d89e7c1bc76e7","unresolved":false,"context_lines":[{"line_number":222,"context_line":"        src_container_name, src_obj_name \u003d \\"},{"line_number":223,"context_line":"            src_header.split(\u0027/\u0027, 2)[1:]"},{"line_number":224,"context_line":"    except ValueError:"},{"line_number":225,"context_line":"        return HTTPPreconditionFailed("},{"line_number":226,"context_line":"            request\u003dreq,"},{"line_number":227,"context_line":"            body\u003d\u0027X-Copy-From header must be of the form\u0027"},{"line_number":228,"context_line":"                 \u0027\u003ccontainer name\u003e/\u003cobject name\u003e\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2BGHE%3D","line":225,"updated":"2013-12-02 16:19:52.000000000","message":"You should be able to just raise this HTTPPreconditionFailed instance (since it\u0027s both a swob.Response and an Exception), leading to a simpler interface at the call-sites.","commit_id":"586a431ff0861f6d700a512cee6fb7a03f9fb88d"},{"author":{"_account_id":2696,"name":"Darrell Bishop","email":"dbishop@nvidia.com","username":"darrellb"},"change_message_id":"2f2baf4e1d76c9d7aa3cd1ca3f3b47f6bdde3c19","unresolved":false,"context_lines":[{"line_number":229,"context_line":"    if not src_header.startswith(\u0027/\u0027):"},{"line_number":230,"context_line":"        src_header \u003d \u0027/\u0027 + src_header"},{"line_number":231,"context_line":"    try:"},{"line_number":232,"context_line":"        src_container_name, src_obj_name \u003d \\"},{"line_number":233,"context_line":"            src_header.split(\u0027/\u0027, 2)[1:]"},{"line_number":234,"context_line":"    except ValueError:"},{"line_number":235,"context_line":"        raise HTTPPreconditionFailed("}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAUH%2F%2F%2FeQ%3D","line":232,"updated":"2014-01-04 15:57:32.000000000","message":"Did you consider (re)using swift.common.utils.split_path, here?  E.g.\n\n  ...\n  try:\n      return split_path(src_header, 2)\n  except ValueError:\n      raise HTTPPreconditionFailed(...)\n\nUnfortunately, split_path doesn\u0027t help with the unquoting or the ensuring of a leading \u0027/\u0027.","commit_id":"ba564dff8a3daa173701b6618bd75d01696f7255"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"2cbc50598f8ad525ba370d2dfc988b3437e8d86c","unresolved":false,"context_lines":[{"line_number":217,"context_line":"def check_copy_from_header(req):"},{"line_number":218,"context_line":"    \"\"\""},{"line_number":219,"context_line":"    Validate that the value from x-copy-from header is"},{"line_number":220,"context_line":"    well formated. We assume the caller ensure that"},{"line_number":221,"context_line":"    x-copy-from header is present in req.headers."},{"line_number":222,"context_line":""},{"line_number":223,"context_line":"    :param req: HTTP request object"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAUH%2F%2F6k8%3D","line":220,"updated":"2014-01-10 21:02:18.000000000","message":"*formatted\n\n*ensures","commit_id":"39c29c48e0ca4813abbe4a55e62ef1d0b723e147"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"2cbc50598f8ad525ba370d2dfc988b3437e8d86c","unresolved":false,"context_lines":[{"line_number":223,"context_line":"    :param req: HTTP request object"},{"line_number":224,"context_line":"    :returns: A tuple with container name and object name"},{"line_number":225,"context_line":"    :raise: HTTPPreconditionFailed if x-copy-from value"},{"line_number":226,"context_line":"            is not well formated."},{"line_number":227,"context_line":"    \"\"\""},{"line_number":228,"context_line":"    src_header \u003d unquote(req.headers.get(\u0027X-Copy-From\u0027))"},{"line_number":229,"context_line":"    if not src_header.startswith(\u0027/\u0027):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAUH%2F%2Fk8Q%3D","line":226,"updated":"2014-01-10 21:02:18.000000000","message":"*formatted","commit_id":"39c29c48e0ca4813abbe4a55e62ef1d0b723e147"}],"swift/common/middleware/container_quotas.py":[{"author":{"_account_id":2696,"name":"Darrell Bishop","email":"dbishop@nvidia.com","username":"darrellb"},"change_message_id":"82bf24a430472f0cfa9fd53e62a25b1f17d38d12","unresolved":false,"context_lines":[{"line_number":91,"context_line":"                content_length \u003d (req.content_length or 0)"},{"line_number":92,"context_line":"                copy_from \u003d req.headers.get(\u0027X-Copy-From\u0027)"},{"line_number":93,"context_line":"                if copy_from:"},{"line_number":94,"context_line":"                    copy_from \u003d copy_from.lstrip(\u0027/\u0027)"},{"line_number":95,"context_line":"                    # Check X-Copy-From format"},{"line_number":96,"context_line":"                    try:"},{"line_number":97,"context_line":"                        split_path(\"/\" + copy_from, 2, 2, True)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2BT8o%3D","line":94,"updated":"2013-11-27 14:37:35.000000000","message":"It would be good to refactor this validation with the proxy server\u0027s (into util code, perhaps in swift.common.constraints?).\n\nThis sort of thing (from the obj proxy controller; in this context, the local var \"source_header\" is analogous to this code\u0027s \"copy_from\" local var):\n\n            source_header \u003d unquote(source_header)\n            acct \u003d req.path_info.split(\u0027/\u0027, 2)[1]\n            if isinstance(acct, unicode):\n                acct \u003d acct.encode(\u0027utf-8\u0027)\n            if not source_header.startswith(\u0027/\u0027):\n                source_header \u003d \u0027/\u0027 + source_header\n            source_header \u003d \u0027/\u0027 + acct + source_header\n            try:\n                src_container_name, src_obj_name \u003d \\\n                    source_header.split(\u0027/\u0027, 3)[2:]\n            except ValueError:\n                return HTTPPreconditionFailed(\n                    request\u003dreq,\n                    body\u003d\u0027X-Copy-From header must be of the form\u0027\n                         \u0027\u003ccontainer name\u003e/\u003cobject name\u003e\u0027)","commit_id":"49dc21db091de1b3fc589e22e5073c601e64da07"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"f751c724f9cf35f83a3263e2c46052e005a99fb7","unresolved":false,"context_lines":[{"line_number":96,"context_line":"                    try:"},{"line_number":97,"context_line":"                        split_path(\"/\" + copy_from, 2, 2, True)"},{"line_number":98,"context_line":"                    except ValueError:"},{"line_number":99,"context_line":"                        # We let the proxy server ends up with 412 Error"},{"line_number":100,"context_line":"                        return self.app"},{"line_number":101,"context_line":"                    path \u003d \u0027/%s/%s/%s\u0027 % (version, account, copy_from)"},{"line_number":102,"context_line":"                    object_info \u003d get_object_info(req.environ, self.app, path)"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F%2BUF8%3D","line":99,"updated":"2013-11-27 14:13:17.000000000","message":"It\u0027s true that the error will be catched later on. However, if the middleware already stumbles upon the bad request it might be a better idea to return a HTTPBadRequest right now? This makes the test also better readable because we don\u0027t expect a \"200 OK\" then.","commit_id":"49dc21db091de1b3fc589e22e5073c601e64da07"},{"author":{"_account_id":2696,"name":"Darrell Bishop","email":"dbishop@nvidia.com","username":"darrellb"},"change_message_id":"1ae77f1461c9a4711798c9b5746d89e7c1bc76e7","unresolved":false,"context_lines":[{"line_number":94,"context_line":"                    ret \u003d check_copy_from_header(req)"},{"line_number":95,"context_line":"                    try:"},{"line_number":96,"context_line":"                        src_cont, src_obj \u003d ret"},{"line_number":97,"context_line":"                    except ValueError:"},{"line_number":98,"context_line":"                        return ret"},{"line_number":99,"context_line":"                    path \u003d \u0027/%s/%s/%s/%s\u0027 % (version, account,"},{"line_number":100,"context_line":"                                             src_cont, src_obj)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAATn%2F%2BGGc%3D","line":97,"updated":"2013-12-02 16:19:52.000000000","message":"See comment in constraints.py; the HTTPPreconditionFailed exception should just be raised and this try/except that returns \"ret\" can be removed (simplified).","commit_id":"586a431ff0861f6d700a512cee6fb7a03f9fb88d"},{"author":{"_account_id":9205,"name":"Gil Vernik","email":"gilv@il.ibm.com","username":"gilv"},"change_message_id":"7931faacbfe7c068970190d5cc212509d7d67c1f","unresolved":false,"context_lines":[{"line_number":90,"context_line":"                    \u0027bytes\u0027 in container_info and \\"},{"line_number":91,"context_line":"                    container_info[\u0027meta\u0027][\u0027quota-bytes\u0027].isdigit():"},{"line_number":92,"context_line":"                content_length \u003d (req.content_length or 0)"},{"line_number":93,"context_line":"                if \u0027x-copy-from\u0027 in req.headers:"},{"line_number":94,"context_line":"                    src_cont, src_obj \u003d check_copy_from_header(req)"},{"line_number":95,"context_line":"                    path \u003d \u0027/%s/%s/%s/%s\u0027 % (version, account,"},{"line_number":96,"context_line":"                                             src_cont, src_obj)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAUH%2F%2Fyp0%3D","line":93,"updated":"2014-01-08 12:34:23.000000000","message":"I am not sure about my remark, but should it be \u0027X-Copy-From\u0027 ?\n( for example, see constraints.py, line 135 )","commit_id":"39c29c48e0ca4813abbe4a55e62ef1d0b723e147"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"2cbc50598f8ad525ba370d2dfc988b3437e8d86c","unresolved":false,"context_lines":[{"line_number":90,"context_line":"                    \u0027bytes\u0027 in container_info and \\"},{"line_number":91,"context_line":"                    container_info[\u0027meta\u0027][\u0027quota-bytes\u0027].isdigit():"},{"line_number":92,"context_line":"                content_length \u003d (req.content_length or 0)"},{"line_number":93,"context_line":"                if \u0027x-copy-from\u0027 in req.headers:"},{"line_number":94,"context_line":"                    src_cont, src_obj \u003d check_copy_from_header(req)"},{"line_number":95,"context_line":"                    path \u003d \u0027/%s/%s/%s/%s\u0027 % (version, account,"},{"line_number":96,"context_line":"                                             src_cont, src_obj)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAUH%2F%2Fq2s%3D","line":93,"in_reply_to":"AAAAUH%2F%2Fyp0%3D","updated":"2014-01-10 21:02:18.000000000","message":"req.headers is a swob.HeaderKeyDict, and that provides case-insensitive comparison on keys. (RFC 2616 says header names are case-insensitive, so that\u0027s why we do it.)","commit_id":"39c29c48e0ca4813abbe4a55e62ef1d0b723e147"}],"swift/proxy/controllers/obj.py":[{"author":{"_account_id":2696,"name":"Darrell Bishop","email":"dbishop@nvidia.com","username":"darrellb"},"change_message_id":"2f2baf4e1d76c9d7aa3cd1ca3f3b47f6bdde3c19","unresolved":false,"context_lines":[{"line_number":994,"context_line":"                src_container_name, src_obj_name \u003d check_copy_from_header(req)"},{"line_number":995,"context_line":"            except HTTPException as error:"},{"line_number":996,"context_line":"                return error"},{"line_number":997,"context_line":"            source_header \u003d unquote(source_header)"},{"line_number":998,"context_line":"            acct \u003d req.swift_entity_path.split(\u0027/\u0027, 2)[1]"},{"line_number":999,"context_line":"            if isinstance(acct, unicode):"},{"line_number":1000,"context_line":"                acct \u003d acct.encode(\u0027utf-8\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAUH%2F%2F%2FeE%3D","line":997,"updated":"2014-01-04 15:57:32.000000000","message":"This assignment to source_header is no longer necessary.","commit_id":"ba564dff8a3daa173701b6618bd75d01696f7255"},{"author":{"_account_id":2696,"name":"Darrell Bishop","email":"dbishop@nvidia.com","username":"darrellb"},"change_message_id":"2f2baf4e1d76c9d7aa3cd1ca3f3b47f6bdde3c19","unresolved":false,"context_lines":[{"line_number":995,"context_line":"            except HTTPException as error:"},{"line_number":996,"context_line":"                return error"},{"line_number":997,"context_line":"            source_header \u003d unquote(source_header)"},{"line_number":998,"context_line":"            acct \u003d req.swift_entity_path.split(\u0027/\u0027, 2)[1]"},{"line_number":999,"context_line":"            if isinstance(acct, unicode):"},{"line_number":1000,"context_line":"                acct \u003d acct.encode(\u0027utf-8\u0027)"},{"line_number":1001,"context_line":"            source_header \u003d \u0027/v1/\u0027 + acct + \u0027/\u0027 + \\"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAUH%2F%2F%2FdE%3D","line":998,"updated":"2014-01-04 15:57:32.000000000","message":"In container_quotas.py, the source_header was more elegantly constructed as\n\n  path \u003d \u0027/%s/%s/%s/%s\u0027 % (...)\n\nAlso, it\u0027d be nice if the request\u0027s actual version was used instead of a hard-coded \"v1\".  Perhaps something like\n\n  version, acct, _rest \u003d req.split_path(2, 3, True)\n  ...\n  source_header \u003d \u0027/%s/%s/%s/%s\u0027 % (version, acct, src_container_name, src_obj_name)","commit_id":"ba564dff8a3daa173701b6618bd75d01696f7255"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"2cbc50598f8ad525ba370d2dfc988b3437e8d86c","unresolved":false,"context_lines":[{"line_number":993,"context_line":"            try:"},{"line_number":994,"context_line":"                src_container_name, src_obj_name \u003d check_copy_from_header(req)"},{"line_number":995,"context_line":"            except HTTPException as error:"},{"line_number":996,"context_line":"                return error"},{"line_number":997,"context_line":"            ver, acct, _rest \u003d req.split_path(2, 3, True)"},{"line_number":998,"context_line":"            if isinstance(acct, unicode):"},{"line_number":999,"context_line":"                acct \u003d acct.encode(\u0027utf-8\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAUH%2F%2Fk%2FI%3D","line":996,"updated":"2014-01-10 21:02:18.000000000","message":"You should be able to avoid this catch/return thing; I\u0027m pretty sure there\u0027s a high-level \"except HTTPException\" way up in the proxy server.\n\nOTOH, if there are a ton of unit tests that break when you remove this try/except, this is okay for now. Some unit tests used to call .PUT/.GET/etc. directly instead of going through __call__, and if there\u0027s any left, they\u0027ll break. It\u0027s an ongoing effort, and not one that should be jammed into this patch.\n\ntl;dr: please remove this try/except, but if tests break, you can put it back","commit_id":"39c29c48e0ca4813abbe4a55e62ef1d0b723e147"}],"test/unit/common/test_constraints.py":[{"author":{"_account_id":2696,"name":"Darrell Bishop","email":"dbishop@nvidia.com","username":"darrellb"},"change_message_id":"f615d2be2c845fb5e82ec5aaf8088eeb99601176","unresolved":false,"context_lines":[{"line_number":260,"context_line":"    def test_validate_copy_from(self):"},{"line_number":261,"context_line":"        req \u003d Request.blank("},{"line_number":262,"context_line":"            \u0027/v/a/c/o\u0027,"},{"line_number":263,"context_line":"            headers\u003d{\u0027x-copy-from\u0027: \u0027c/o2\u0027})"},{"line_number":264,"context_line":"        src_cont, src_obj \u003d constraints.check_copy_from_header(req)"},{"line_number":265,"context_line":"        self.assertEqual(src_cont, \u0027c\u0027)"},{"line_number":266,"context_line":"        self.assertEqual(src_obj, \u0027o2\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAUH%2F%2FhKc%3D","line":263,"updated":"2014-01-13 00:24:39.000000000","message":"Can you also add test coverage for a X-Copy-From value like\n\n  /c/o/foo.gz\n\nor something?  In particular, cover values with a leading slash (as suggested by, e.g., http://docs.openstack.org/api/openstack-object-storage/1.0/content/copy-object.html) and objects with a slash in their name as well.\n\nThe code handles both of those fine (I added the tests locally to see if they\u0027d uncover a bug), but the additional tests would still be good.","commit_id":"39c29c48e0ca4813abbe4a55e62ef1d0b723e147"}]}
