)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"554e7829ff476439919f59b790605706fcc125ee","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     Matthew Oliver \u003cmatt@oliver.net.au\u003e"},{"line_number":5,"context_line":"CommitDate: 2021-09-06 17:32:42 +1000"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"DNM: Close connection on requests that still have unsent content"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The wsgi Input class gives us some paraments we can use to see if the"},{"line_number":10,"context_line":"client has send all it\u0027s expected data. If not chunked input, then we"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"bc527334_5ff0beef","line":7,"updated":"2021-09-07 22:08:02.000000000","message":"Might be worth noting... somewhere... that we may or may not end up including a\n\n Connection: close\n\nheader. Basically, it comes down to whether or not we\u0027ve already sent response headers back.","commit_id":"490ef305a5ed161d70caf5222b2932f387b32ebd"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"554e7829ff476439919f59b790605706fcc125ee","unresolved":true,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The wsgi Input class gives us some paraments we can use to see if the"},{"line_number":10,"context_line":"client has send all it\u0027s expected data. If not chunked input, then we"},{"line_number":11,"context_line":"can compare the content_length and position. When in chucked mode if"},{"line_number":12,"context_line":"chucked_length is ever 0 then there is no more data (if I read it"},{"line_number":13,"context_line":"right). So this patch extends the Swift WSGI HttpProtocol from eventlets"},{"line_number":14,"context_line":"to close connections if the client still has data."},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"6ad2ab29_67bcf2ad","line":12,"range":{"start_line":11,"start_character":66,"end_line":12,"end_character":51},"updated":"2021-09-07 22:08:02.000000000","message":"Yeah, that\u0027s my read on https://github.com/eventlet/eventlet/blob/0100950/eventlet/wsgi.py#L172 too.","commit_id":"490ef305a5ed161d70caf5222b2932f387b32ebd"}],"swift/common/swob.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"8426de647ef7c7f1f10bde06b11e74958a0d1e65","unresolved":false,"context_lines":[{"line_number":1554,"context_line":"    @staticmethod"},{"line_number":1555,"context_line":"    def should_close_hook(self):"},{"line_number":1556,"context_line":"        return is_server_error(self.status_int) or \\"},{"line_number":1557,"context_line":"               is_client_error(self.status_int)"},{"line_number":1558,"context_line":""},{"line_number":1559,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":1560,"context_line":"        Response.__init__(self, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":1,"id":"1ed26930_049088bb","line":1557,"updated":"2021-09-04 00:28:24.000000000","message":"I\u0027ve obviously changed this not to be static as it references self. Just haven\u0027t bothered pushing up a new version.","commit_id":"f5ae47770ac07e634ede9c1f26c1618909b535b5"}],"swift/common/wsgi.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"554e7829ff476439919f59b790605706fcc125ee","unresolved":true,"context_lines":[{"line_number":566,"context_line":""},{"line_number":567,"context_line":"        # Force a close of the connection if we detect any unwritten data,"},{"line_number":568,"context_line":"        # writing this out verbosely for easier maintenence."},{"line_number":569,"context_line":"        input \u003d self.environ.get(\u0027eventlet.input\u0027)"},{"line_number":570,"context_line":"        if input and input.chunked_input:"},{"line_number":571,"context_line":"            has_unused_data \u003d input.chunk_length !\u003d 0"},{"line_number":572,"context_line":"        elif input and input.content_length:"}],"source_content_type":"text/x-python","patch_set":4,"id":"e3944bde_c373c762","line":569,"updated":"2021-09-07 22:08:02.000000000","message":"We might want to grab this *before* we hand off to the application -- there\u0027s a chance application code could wrap it or otherwise swap it out.\n\nMight also want to choose a name that doesn\u0027t shadow a built-in.","commit_id":"490ef305a5ed161d70caf5222b2932f387b32ebd"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b598c44159b48f89bcafd33675ff554b90fe2fc4","unresolved":true,"context_lines":[{"line_number":566,"context_line":""},{"line_number":567,"context_line":"        # Force a close of the connection if we detect any unwritten data,"},{"line_number":568,"context_line":"        # writing this out verbosely for easier maintenence."},{"line_number":569,"context_line":"        input \u003d self.environ.get(\u0027eventlet.input\u0027)"},{"line_number":570,"context_line":"        if input and input.chunked_input:"},{"line_number":571,"context_line":"            has_unused_data \u003d input.chunk_length !\u003d 0"},{"line_number":572,"context_line":"        elif input and input.content_length:"}],"source_content_type":"text/x-python","patch_set":4,"id":"35339712_03746f48","line":569,"in_reply_to":"e3944bde_c373c762","updated":"2021-09-09 05:02:04.000000000","message":"True, but it also why I use eventlet.input and not the wsgi.input. They start off the same https://github.com/eventlet/eventlet/blob/master/eventlet/wsgi.py#L720\n\nAnd I think we tend to use wsgi.input so if we change it out the other still exists. But yeah, doesn\u0027t hurt to pull it out, just in case. The env is generated in handle_one_request should should exist wefore we run handle_one_response above.","commit_id":"490ef305a5ed161d70caf5222b2932f387b32ebd"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"554e7829ff476439919f59b790605706fcc125ee","unresolved":true,"context_lines":[{"line_number":572,"context_line":"        elif input and input.content_length:"},{"line_number":573,"context_line":"            has_unused_data \u003d input.position \u003c input.content_length"},{"line_number":574,"context_line":"        else:"},{"line_number":575,"context_line":"            has_unused_data \u003d False"},{"line_number":576,"context_line":"        if has_unused_data:"},{"line_number":577,"context_line":"            self.close_connection \u003d 1"},{"line_number":578,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"e09d7be1_38b9a629","line":575,"updated":"2021-09-07 22:08:02.000000000","message":"I could see us hitting this in tests -- do we ever get here in practice? I would\u0027ve hoped eventlet would *always* set up the input...","commit_id":"490ef305a5ed161d70caf5222b2932f387b32ebd"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b598c44159b48f89bcafd33675ff554b90fe2fc4","unresolved":true,"context_lines":[{"line_number":572,"context_line":"        elif input and input.content_length:"},{"line_number":573,"context_line":"            has_unused_data \u003d input.position \u003c input.content_length"},{"line_number":574,"context_line":"        else:"},{"line_number":575,"context_line":"            has_unused_data \u003d False"},{"line_number":576,"context_line":"        if has_unused_data:"},{"line_number":577,"context_line":"            self.close_connection \u003d 1"},{"line_number":578,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"130bd27b_7d133dee","line":575,"in_reply_to":"e09d7be1_38b9a629","updated":"2021-09-09 05:02:04.000000000","message":"To be honest, no I don\u0027t think we would get here in practice.. esp if we pull out the input so there is no chance we\u0027ve done anything or lost it down in the swift layer.","commit_id":"490ef305a5ed161d70caf5222b2932f387b32ebd"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"49101af6ffe27fd02fd00f801cbe0e1f1fe29c93","unresolved":true,"context_lines":[{"line_number":565,"context_line":"        ev_input \u003d self.environ.get(\u0027eventlet.input\u0027)"},{"line_number":566,"context_line":""},{"line_number":567,"context_line":"        # Note this is not a new-style class, so super() won\u0027t work"},{"line_number":568,"context_line":"        got \u003d wsgi.HttpProtocol.handle_one_response(self)"},{"line_number":569,"context_line":""},{"line_number":570,"context_line":"        # Force a close of the connection if we detect any unwritten data,"},{"line_number":571,"context_line":"        # writing this out verbosely for easier maintenence."}],"source_content_type":"text/x-python","patch_set":6,"id":"599973ca_b2ae9c06","line":568,"updated":"2021-09-09 17:55:05.000000000","message":"If you\u0027re running https://github.com/eventlet/eventlet/pull/578 the server will have already tried to drain the body by the time this method finishes","commit_id":"86269d85d432167051374ed5a547df87b02cb434"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"deffb283fb9dac17857b0ebf3342a38b897d78b6","unresolved":true,"context_lines":[{"line_number":572,"context_line":"        # writing this out verbosely for easier maintenence."},{"line_number":573,"context_line":"        has_unused_data \u003d False"},{"line_number":574,"context_line":"        if ev_input and ev_input.chunked_input:"},{"line_number":575,"context_line":"            has_unused_data \u003d ev_input.chunk_length !\u003d 0"},{"line_number":576,"context_line":"        elif ev_input and ev_input.content_length:"},{"line_number":577,"context_line":"            has_unused_data \u003d ev_input.position \u003c ev_input.content_length"},{"line_number":578,"context_line":"        if has_unused_data:"}],"source_content_type":"text/x-python","patch_set":7,"id":"ffcf80cd_52a2073c","line":575,"updated":"2021-09-16 19:22:09.000000000","message":"We do some funky things with sending zero-length chunks mid-stream: https://bugs.launchpad.net/swift/+bug/1496636\n\nSo I guess there may be a way we\u0027ll fire off a response between receiving data and footers, or between footers and commit, and the *object-server* will fire off a 400 Bad Request when it tries to parse the next MIME doc (if sent) as a new request. IDK that we can avoid that short of *actually speaking HTTP* though.","commit_id":"3c7d35871ad1d75d72be7b171f537f72dbf294a0"}],"test/unit/common/middleware/test_ratelimit.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"8426de647ef7c7f1f10bde06b11e74958a0d1e65","unresolved":true,"context_lines":[{"line_number":165,"context_line":""},{"line_number":166,"context_line":"        # flush the response body"},{"line_number":167,"context_line":"        fd.write(obj)"},{"line_number":168,"context_line":"        headers \u003d readuntil2crlfs(fd)"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":"class TestRateLimit(unittest.TestCase):"},{"line_number":171,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"fe9723a4_b980ac97","line":168,"updated":"2021-09-04 00:28:24.000000000","message":"Haven\u0027t got to actually testing the ratelimit side yet.. this is just really a setup.","commit_id":"f5ae47770ac07e634ede9c1f26c1618909b535b5"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"6fb8523790bf592735c69b12c9232e5ff2c1c649","unresolved":true,"context_lines":[{"line_number":165,"context_line":""},{"line_number":166,"context_line":"        # flush the response body"},{"line_number":167,"context_line":"        fd.write(obj)"},{"line_number":168,"context_line":"        headers \u003d readuntil2crlfs(fd)"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":"class TestRateLimit(unittest.TestCase):"},{"line_number":171,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"81c5b9e5_176b00f9","line":168,"in_reply_to":"fe9723a4_b980ac97","updated":"2021-09-04 00:29:01.000000000","message":"opss, old comment, I have done this.","commit_id":"f5ae47770ac07e634ede9c1f26c1618909b535b5"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"554e7829ff476439919f59b790605706fcc125ee","unresolved":true,"context_lines":[{"line_number":88,"context_line":"    def __call__(self, env, start_response):"},{"line_number":89,"context_line":"        assert self.skip_handled_check or env.get(\u0027swift.ratelimit.handled\u0027)"},{"line_number":90,"context_line":"        start_response(self.response_code, [(\u0027Connection\u0027, \u0027close\u0027)])"},{"line_number":91,"context_line":"        return [self.response_content]"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"class FakeReq(object):"}],"source_content_type":"text/x-python","patch_set":4,"id":"fc7d89e2_5c121ae3","line":91,"updated":"2021-09-07 22:08:02.000000000","message":"None of this is getting used anywhere, is it?\n\nFWIW, I\u0027m pretty sure the WSGI server is responsible for managing Connection headers, not WSGI applications. But maybe this white lie would be OK for tests?","commit_id":"490ef305a5ed161d70caf5222b2932f387b32ebd"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b598c44159b48f89bcafd33675ff554b90fe2fc4","unresolved":true,"context_lines":[{"line_number":88,"context_line":"    def __call__(self, env, start_response):"},{"line_number":89,"context_line":"        assert self.skip_handled_check or env.get(\u0027swift.ratelimit.handled\u0027)"},{"line_number":90,"context_line":"        start_response(self.response_code, [(\u0027Connection\u0027, \u0027close\u0027)])"},{"line_number":91,"context_line":"        return [self.response_content]"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"class FakeReq(object):"}],"source_content_type":"text/x-python","patch_set":4,"id":"e8d6faa5_82e9777a","line":91,"in_reply_to":"fc7d89e2_5c121ae3","updated":"2021-09-09 05:02:04.000000000","message":"oh no, not in the simplified version. I\u0027ll remove it.","commit_id":"490ef305a5ed161d70caf5222b2932f387b32ebd"}],"test/unit/proxy/test_server.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"554e7829ff476439919f59b790605706fcc125ee","unresolved":true,"context_lines":[{"line_number":3474,"context_line":"                fd.flush()"},{"line_number":3475,"context_line":"                readuntil2crlfs(fd)"},{"line_number":3476,"context_line":"                import struct"},{"line_number":3477,"context_line":"                tcp_info \u003d struct.unpack(\"B\" * 7 + \"I\" * 21,"},{"line_number":3478,"context_line":"                                         sock.getsockopt(socket.IPPROTO_TCP,"},{"line_number":3479,"context_line":"                                                         socket.TCP_INFO, 92))"},{"line_number":3480,"context_line":"                # Numbers according to"}],"source_content_type":"text/x-python","patch_set":4,"id":"428560ce_d9cccd3d","line":3477,"range":{"start_line":3477,"start_character":41,"end_line":3477,"end_character":59},"updated":"2021-09-07 22:08:02.000000000","message":"IIRC, you can just say\n\n \"7B21I\"","commit_id":"490ef305a5ed161d70caf5222b2932f387b32ebd"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b598c44159b48f89bcafd33675ff554b90fe2fc4","unresolved":true,"context_lines":[{"line_number":3474,"context_line":"                fd.flush()"},{"line_number":3475,"context_line":"                readuntil2crlfs(fd)"},{"line_number":3476,"context_line":"                import struct"},{"line_number":3477,"context_line":"                tcp_info \u003d struct.unpack(\"B\" * 7 + \"I\" * 21,"},{"line_number":3478,"context_line":"                                         sock.getsockopt(socket.IPPROTO_TCP,"},{"line_number":3479,"context_line":"                                                         socket.TCP_INFO, 92))"},{"line_number":3480,"context_line":"                # Numbers according to"}],"source_content_type":"text/x-python","patch_set":4,"id":"1589ea43_893f8929","line":3477,"range":{"start_line":3477,"start_character":41,"end_line":3477,"end_character":59},"in_reply_to":"428560ce_d9cccd3d","updated":"2021-09-09 05:02:04.000000000","message":"True, but infact we can do much better. The first byte in the struct is the state, and that\u0027s all we\u0027re checking.. so we can just return the first byte rather then 92 and it should be:\n\n  struct.unpack(\"B\", sock.getsockopt(.., 1))","commit_id":"490ef305a5ed161d70caf5222b2932f387b32ebd"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b598c44159b48f89bcafd33675ff554b90fe2fc4","unresolved":true,"context_lines":[{"line_number":3419,"context_line":"        with mock.patch(\u0027swift.proxy.server.Application.handle_request\u0027,"},{"line_number":3420,"context_line":"                        mock_handle_request):"},{"line_number":3421,"context_line":"            # if not sock:"},{"line_number":3422,"context_line":"            #    sock \u003d connect_tcp((\u0027localhost\u0027, prolis.getsockname()[1]))"},{"line_number":3423,"context_line":""},{"line_number":3424,"context_line":"            fd \u003d sock.makefile(\u0027rwb\u0027)"},{"line_number":3425,"context_line":"            path \u003d b\u0027/v1/a/c/o-%s\u0027 % str(uuid.uuid4()).encode(\u0027ascii\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"36baf0cb_c74635e0","line":3422,"updated":"2021-09-09 05:02:04.000000000","message":"Opps need to get rid of this","commit_id":"e3b6a6086ec44ebbd1ed586af32b897f37067fe8"}]}
