)]}'
{"etc/proxy-server.conf-sample":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"970132671ef8041d005668bab5dc562ef2d29944","unresolved":false,"context_lines":[{"line_number":103,"context_line":"[pipeline:main]"},{"line_number":104,"context_line":"# This sample pipeline uses tempauth and is used for SAIO dev work and"},{"line_number":105,"context_line":"# testing. See below for a pipeline using keystone."},{"line_number":106,"context_line":"pipeline \u003d catch_errors gatekeeper healthcheck proxy-logging cache listing_formats container_sync bulk tempurl ratelimit tempauth copy container-quotas account-quotas slo dlo versioned_writes symlink proxy-logging proxy-server"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"# The following pipeline shows keystone integration. Comment out the one"},{"line_number":109,"context_line":"# above and uncomment this one. Additional steps for integrating keystone are"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"9f560f44_d0199ed1","line":106,"updated":"2020-10-05 19:13:25.000000000","message":"yes please!","commit_id":"1aa0058d566e531cf3570bf2a5308bf402d5c40f"}],"swift/common/middleware/proxy_logging.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9374fa9341d8bf4c2c7c13c1b9ac2af688858cbd","unresolved":false,"context_lines":[{"line_number":374,"context_line":"            else:"},{"line_number":375,"context_line":"                if isinstance(iterator, list):"},{"line_number":376,"context_line":"                    content_length \u003d sum(len(i) for i in iterator)"},{"line_number":377,"context_line":"                    iterator \u003d enforce_byte_count(iterator, content_length)"},{"line_number":378,"context_line":"                    start_response_args[0][1].append("},{"line_number":379,"context_line":"                        (\u0027Content-Length\u0027, str(content_length)))"},{"line_number":380,"context_line":"            wire_status_int \u003d int(start_response_args[0][0].split(\u0027 \u0027, 1)[0])"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_3abd6b67","line":377,"updated":"2020-10-03 05:45:05.000000000","message":"Not sure this is strictly necessary -- I guess it\u0027d maybe guard against some crazy thing like an app returning a list of bytearrays and *somehow* something changes a bytearray\u0027s size mid-iteration?? Seemed like better safe than sorry.","commit_id":"43f0ed071cac3647f45bd73192c83108e63a8324"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4a21c68349a7324fbdef16ef211c3a9f1b964b0f","unresolved":false,"context_lines":[{"line_number":427,"context_line":"                    req, status_int, input_proxy.bytes_received, bytes_sent,"},{"line_number":428,"context_line":"                    start_time, time.time(), resp_headers\u003dresp_headers,"},{"line_number":429,"context_line":"                    ttfb\u003dttfb, wire_status_int\u003dwire_status_int)"},{"line_number":430,"context_line":"                iterator.close()"},{"line_number":431,"context_line":""},{"line_number":432,"context_line":"        try:"},{"line_number":433,"context_line":"            iterable \u003d self.app(env, my_start_response)"}],"source_content_type":"text/x-python","patch_set":2,"id":"9f560f44_da20afb4","line":430,"updated":"2020-10-03 06:45:25.000000000","message":"I think a lot of my trouble traces back to this change... but it *really, really* seems like it ought to be good enough :-(\n\nOr, phrased differently, the fact that this *doesn\u0027t* seem to work makes me worry about the correctness of CloseableChain or reiterate or both.","commit_id":"ffa2d445faeec8fecf8b52af272071f97fa5df6d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"970132671ef8041d005668bab5dc562ef2d29944","unresolved":false,"context_lines":[{"line_number":77,"context_line":"from swift.common.middleware.catch_errors import enforce_byte_count"},{"line_number":78,"context_line":"from swift.common.swob import Request"},{"line_number":79,"context_line":"from swift.common.utils import (get_logger, get_remote_client,"},{"line_number":80,"context_line":"                                config_true_value, reiterate,"},{"line_number":81,"context_line":"                                InputProxy, list_from_csv, get_policy_index,"},{"line_number":82,"context_line":"                                split_path, StrAnonymizer, StrFormatTime,"},{"line_number":83,"context_line":"                                LogStringFormatter)"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f560f44_500e2e8c","line":80,"updated":"2020-10-05 19:13:25.000000000","message":"i don\u0027t really know how reiterate works","commit_id":"1aa0058d566e531cf3570bf2a5308bf402d5c40f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"970132671ef8041d005668bab5dc562ef2d29944","unresolved":false,"context_lines":[{"line_number":383,"context_line":"            if method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":384,"context_line":"                content_length \u003d 0"},{"line_number":385,"context_line":"            if content_length is not None:"},{"line_number":386,"context_line":"                iterator \u003d enforce_byte_count(iterator, content_length)"},{"line_number":387,"context_line":""},{"line_number":388,"context_line":"            wire_status_int \u003d int(start_response_args[0][0].split(\u0027 \u0027, 1)[0])"},{"line_number":389,"context_line":"            resp_headers \u003d dict(start_response_args[0][1])"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f560f44_901f26b7","line":386,"updated":"2020-10-05 19:13:25.000000000","message":"this seems pretty solid","commit_id":"1aa0058d566e531cf3570bf2a5308bf402d5c40f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"970132671ef8041d005668bab5dc562ef2d29944","unresolved":false,"context_lines":[{"line_number":419,"context_line":"                raise"},{"line_number":420,"context_line":"            except Exception:"},{"line_number":421,"context_line":"                start_status \u003d 500"},{"line_number":422,"context_line":"                raise"},{"line_number":423,"context_line":"            finally:"},{"line_number":424,"context_line":"                status_int \u003d status_int_for_logging("},{"line_number":425,"context_line":"                    start_status, client_disconnect)"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f560f44_f01e62b9","line":422,"updated":"2020-10-05 19:13:25.000000000","message":"this would handle the BadStatusLength same as before","commit_id":"1aa0058d566e531cf3570bf2a5308bf402d5c40f"}],"swift/common/utils.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"970132671ef8041d005668bab5dc562ef2d29944","unresolved":false,"context_lines":[{"line_number":3998,"context_line":""},{"line_number":3999,"context_line":"def reiterate(iterable):"},{"line_number":4000,"context_line":"    \"\"\""},{"line_number":4001,"context_line":"    Consume the first truthy item from an iterator, then re-chain it to the"},{"line_number":4002,"context_line":"    rest of the iterator.  This is useful when you want to make sure the"},{"line_number":4003,"context_line":"    prologue to downstream generators have been executed before continuing."},{"line_number":4004,"context_line":"    :param iterable: an iterable object"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f560f44_d08a3eba","line":4001,"updated":"2020-10-05 19:13:25.000000000","message":"so \"truthy\" isn\u0027t a change as much as clarification of existing behavior","commit_id":"1aa0058d566e531cf3570bf2a5308bf402d5c40f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"899010ec15836ba7cdc834b2f5248d709eaf784e","unresolved":false,"context_lines":[{"line_number":3998,"context_line":""},{"line_number":3999,"context_line":"def reiterate(iterable):"},{"line_number":4000,"context_line":"    \"\"\""},{"line_number":4001,"context_line":"    Consume the first truthy item from an iterator, then re-chain it to the"},{"line_number":4002,"context_line":"    rest of the iterator.  This is useful when you want to make sure the"},{"line_number":4003,"context_line":"    prologue to downstream generators have been executed before continuing."},{"line_number":4004,"context_line":"    :param iterable: an iterable object"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f560f44_b0218ab8","line":4001,"in_reply_to":"9f560f44_d08a3eba","updated":"2020-10-05 19:31:15.000000000","message":"100%","commit_id":"1aa0058d566e531cf3570bf2a5308bf402d5c40f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"970132671ef8041d005668bab5dc562ef2d29944","unresolved":false,"context_lines":[{"line_number":4004,"context_line":"    :param iterable: an iterable object"},{"line_number":4005,"context_line":"    \"\"\""},{"line_number":4006,"context_line":"    if isinstance(iterable, (list, tuple)):"},{"line_number":4007,"context_line":"        return iterable"},{"line_number":4008,"context_line":"    else:"},{"line_number":4009,"context_line":"        iterator \u003d iter(iterable)"},{"line_number":4010,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f560f44_b0850ab1","line":4007,"updated":"2020-10-05 19:13:25.000000000","message":"wat?  oh... maybe because it doesn\u0027t need to be... \"started\" so it\u0027s just the identity function if it\u0027s not a generator... ok, maybe.","commit_id":"1aa0058d566e531cf3570bf2a5308bf402d5c40f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"899010ec15836ba7cdc834b2f5248d709eaf784e","unresolved":false,"context_lines":[{"line_number":4004,"context_line":"    :param iterable: an iterable object"},{"line_number":4005,"context_line":"    \"\"\""},{"line_number":4006,"context_line":"    if isinstance(iterable, (list, tuple)):"},{"line_number":4007,"context_line":"        return iterable"},{"line_number":4008,"context_line":"    else:"},{"line_number":4009,"context_line":"        iterator \u003d iter(iterable)"},{"line_number":4010,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f560f44_b00a2a24","line":4007,"in_reply_to":"9f560f44_b0850ab1","updated":"2020-10-05 19:31:15.000000000","message":"Yeah -- the main reason we\u0027ve got this function *at all* is this bit from pep-3333:\n\n\u003e [T]he start_response callable must not actually transmit the response headers. Instead, it must store them for the server or gateway to transmit only after the first iteration of the application return value that yields a non-empty bytestring, or upon the application\u0027s first invocation of the write() callable. In other words, response headers must not be sent until there is actual body data available, or until the application\u0027s returned iterable is exhausted. (The only possible exception to this rule is if the response headers explicitly include a Content-Length of zero.)\n\u003e  \n\u003e This delaying of response header transmission is to ensure that buffered and asynchronous applications can replace their originally intended output with error output, up until the last possible moment. For example, the application may need to change the response status from \"200 OK\" to \"500 Internal Error\", if an error occurs while the body is being generated within an application buffer.\n\nSo, we read until there\u0027s some actual body data and the status code that we should send to the client is settled.","commit_id":"1aa0058d566e531cf3570bf2a5308bf402d5c40f"}],"swift/proxy/controllers/obj.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"80d39909501f9cc5b8c133756197c033fb6e8846","unresolved":false,"context_lines":[{"line_number":1198,"context_line":"            spec[\u0027resp_fragment_start\u0027] \u003d fstart"},{"line_number":1199,"context_line":"            spec[\u0027resp_fragment_end\u0027] \u003d fend"},{"line_number":1200,"context_line":""},{"line_number":1201,"context_line":"    def __iter__(self):"},{"line_number":1202,"context_line":"        if self.stashed_iter is not None:"},{"line_number":1203,"context_line":"            return self"},{"line_number":1204,"context_line":"        else:"},{"line_number":1205,"context_line":"            raise ValueError(\"Failed to call kickoff() before __iter__()\")"},{"line_number":1206,"context_line":""},{"line_number":1207,"context_line":"    def __next__(self):"},{"line_number":1208,"context_line":"        return next(self.stashed_iter)"},{"line_number":1209,"context_line":""},{"line_number":1210,"context_line":"    next \u003d __next__  # py2"},{"line_number":1211,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9f560f44_4a14bf4d","line":1208,"range":{"start_line":1201,"start_character":4,"end_line":1208,"end_character":38},"updated":"2020-10-05 17:01:10.000000000","message":"I wonder if this would help with https://bugs.launchpad.net/swift/+bug/1895739 -- I think part of why I\u0027m seeing GC clean up that generator at an inopportune time comes down to the fact that\n\n ec_app_iter.close is not iter(ec_app_iter).close\n\n(And that\u0027s assuming iter(ec_app_iter) has a \"close\" attribute at all!)","commit_id":"054de06150fdf053352f3f046b0c7c90ee4d8a6b"}],"test/unit/common/middleware/helpers.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9374fa9341d8bf4c2c7c13c1b9ac2af688858cbd","unresolved":false,"context_lines":[{"line_number":38,"context_line":"        self.key \u003d key"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"    def __iter__(self):"},{"line_number":41,"context_line":"        return self"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def __next__(self):"},{"line_number":44,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f560f44_9ab47784","line":41,"updated":"2020-10-03 05:45:05.000000000","message":"Needed this so that\n\n lti.close is iter(lti).close\n\nOtherwise when we reiterate(), the new iter\u0027s close closes the LTI\u0027s __iter__ generator, not the LTI. That caused TestInternalClient.test_make_request_acceptable_status_not_2xx to fail.","commit_id":"43f0ed071cac3647f45bd73192c83108e63a8324"}],"test/unit/common/middleware/test_proxy_logging.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"970132671ef8041d005668bab5dc562ef2d29944","unresolved":false,"context_lines":[{"line_number":780,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware("},{"line_number":781,"context_line":"            FakeAppNoContentLengthNoTransferEncoding("},{"line_number":782,"context_line":"                # test the \"while not chunk: chunk \u003d next(iterator)\""},{"line_number":783,"context_line":"                body\u003d[b\u0027\u0027, b\u0027\u0027, b\u0027\u0027],"},{"line_number":784,"context_line":"            ), {})"},{"line_number":785,"context_line":"        app.access_logger \u003d FakeLogger()"},{"line_number":786,"context_line":"        req \u003d Request.blank(\u0027/\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f560f44_1063161b","line":783,"updated":"2020-10-05 19:13:25.000000000","message":"it\u0027s not super obvious to me this is a reasonable thing to test, but I guess it works and was pre-existing","commit_id":"1aa0058d566e531cf3570bf2a5308bf402d5c40f"}]}
