Mercurial > public > mercurial-scm > hg
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, |