mercurial/wireprotoserver.py
changeset 37056 861e9d37e56e
parent 37055 61393f888dfe
child 37057 2ec1fb9de638
--- a/mercurial/wireprotoserver.py	Wed Mar 14 13:57:52 2018 -0700
+++ b/mercurial/wireprotoserver.py	Wed Mar 14 14:01:16 2018 -0700
@@ -401,6 +401,10 @@
         states.append(json.dumps((action, meta), sort_keys=True,
                                  separators=(', ', ': ')))
 
+    action, meta = reactor.oninputeof()
+    meta['action'] = action
+    states.append(json.dumps(meta, sort_keys=True, separators=(', ',': ')))
+
     res.status = b'200 OK'
     res.headers[b'Content-Type'] = b'text/plain'
     res.setbodybytes(b'\n'.join(states))
@@ -411,7 +415,10 @@
     Called when the HTTP request contains unified frame-based protocol
     frames for evaluation.
     """
-    reactor = wireprotoframing.serverreactor()
+    # TODO Some HTTP clients are full duplex and can receive data before
+    # the entire request is transmitted. Figure out a way to indicate support
+    # for that so we can opt into full duplex mode.
+    reactor = wireprotoframing.serverreactor(deferoutput=True)
     seencommand = False
 
     while True:
@@ -448,6 +455,19 @@
             raise error.ProgrammingError(
                 'unhandled action from frame processor: %s' % action)
 
+    action, meta = reactor.oninputeof()
+    if action == 'sendframes':
+        # We assume we haven't started sending the response yet. If we're
+        # wrong, the response type will raise an exception.
+        res.status = b'200 OK'
+        res.headers[b'Content-Type'] = FRAMINGTYPE
+        res.setbodygen(meta['framegen'])
+    elif action == 'noop':
+        pass
+    else:
+        raise error.ProgrammingError('unhandled action from frame processor: %s'
+                                     % action)
+
 def _httpv2runcommand(ui, repo, req, res, authedperm, reqcommand, reactor,
                       command):
     """Dispatch a wire protocol command made from HTTPv2 requests.
@@ -504,6 +524,8 @@
 
     if action == 'sendframes':
         res.setbodygen(meta['framegen'])
+    elif action == 'noop':
+        pass
     else:
         raise error.ProgrammingError('unhandled event from reactor: %s' %
                                      action)