comparison mercurial/wireprotoframing.py @ 40133:762ef19a07e3

wireprotov2: send protocol settings frame from client Now that we have client and server reactor support for protocol settings and encoding frames, we can start to send them out over the wire! This commit teaches the client reactor to send out a protocol settings frame when needed. The httpv2 peer has been taught to gather a list of supported content encoders and to advertise them through the client reactor. Because the client is now sending new frame types by default, this constitutes a compatibility break in the framing protocol. The media type version has been bumped accordingly. This will ensure existing clients won't attempt to send the new frames to old servers not supporting this explicit media type. I'm not bothering with the BC annotation because everything wireprotov2 is highly experimental and nobody should be running a server yet. Differential Revision: https://phab.mercurial-scm.org/D4922
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 08 Oct 2018 17:00:16 -0700
parents e67522413ca8
children 966b5f7fd30b
comparison
equal deleted inserted replaced
40132:e67522413ca8 40133:762ef19a07e3
1546 1546
1547 ``expectmore`` and ``eos`` evaluate to True when more response data 1547 ``expectmore`` and ``eos`` evaluate to True when more response data
1548 is expected to follow or we're at the end of the response stream, 1548 is expected to follow or we're at the end of the response stream,
1549 respectively. 1549 respectively.
1550 """ 1550 """
1551 def __init__(self, ui, hasmultiplesend=False, buffersends=True): 1551 def __init__(self, ui, hasmultiplesend=False, buffersends=True,
1552 clientcontentencoders=None):
1552 """Create a new instance. 1553 """Create a new instance.
1553 1554
1554 ``hasmultiplesend`` indicates whether multiple sends are supported 1555 ``hasmultiplesend`` indicates whether multiple sends are supported
1555 by the transport. When True, it is possible to send commands immediately 1556 by the transport. When True, it is possible to send commands immediately
1556 instead of buffering until the caller signals an intent to finish a 1557 instead of buffering until the caller signals an intent to finish a
1557 send operation. 1558 send operation.
1558 1559
1559 ``buffercommands`` indicates whether sends should be buffered until the 1560 ``buffercommands`` indicates whether sends should be buffered until the
1560 last request has been issued. 1561 last request has been issued.
1562
1563 ``clientcontentencoders`` is an iterable of content encoders the client
1564 will advertise to the server and that the server can use for encoding
1565 data. If not defined, the client will not advertise content encoders
1566 to the server.
1561 """ 1567 """
1562 self._ui = ui 1568 self._ui = ui
1563 self._hasmultiplesend = hasmultiplesend 1569 self._hasmultiplesend = hasmultiplesend
1564 self._buffersends = buffersends 1570 self._buffersends = buffersends
1571 self._clientcontentencoders = clientcontentencoders
1565 1572
1566 self._canissuecommands = True 1573 self._canissuecommands = True
1567 self._cansend = True 1574 self._cansend = True
1575 self._protocolsettingssent = False
1568 1576
1569 self._nextrequestid = 1 1577 self._nextrequestid = 1
1570 # We only support a single outgoing stream for now. 1578 # We only support a single outgoing stream for now.
1571 self._outgoingstream = outputstream(1) 1579 self._outgoingstream = outputstream(1)
1572 self._pendingrequests = collections.deque() 1580 self._pendingrequests = collections.deque()
1648 As a side-effect, update request accounting to reflect its changed 1656 As a side-effect, update request accounting to reflect its changed
1649 state. 1657 state.
1650 """ 1658 """
1651 self._activerequests[request.requestid] = request 1659 self._activerequests[request.requestid] = request
1652 request.state = 'sending' 1660 request.state = 'sending'
1661
1662 if not self._protocolsettingssent and self._clientcontentencoders:
1663 self._protocolsettingssent = True
1664
1665 payload = b''.join(cborutil.streamencode({
1666 b'contentencodings': self._clientcontentencoders,
1667 }))
1668
1669 yield self._outgoingstream.makeframe(
1670 requestid=request.requestid,
1671 typeid=FRAME_TYPE_SENDER_PROTOCOL_SETTINGS,
1672 flags=FLAG_SENDER_PROTOCOL_SETTINGS_EOS,
1673 payload=payload)
1653 1674
1654 res = createcommandframes(self._outgoingstream, 1675 res = createcommandframes(self._outgoingstream,
1655 request.requestid, 1676 request.requestid,
1656 request.name, 1677 request.name,
1657 request.args, 1678 request.args,