mercurial/wireprotoframing.py
author Matt Harbison <matt_harbison@yahoo.com>
Mon, 06 Jan 2025 20:32:31 -0500
changeset 52699 068398a8c9cb
parent 52698 1a612f9ec2c4
permissions -rw-r--r--
typing: add some type annotations to the `wireprotoframing` module `flushcommands()` and a few other generators got a slightly modified return type after the pyupgrade series ending with 70a75d379daf. This fixes those, and grabs some other low and mid hanging fruit here. Note that there are possibly two bugs detected here- in the `inputstream` and `outputstream` classes, the `flush()` and `finish()` methods respectively have surprising issues. pytype flagged the latter when the return value was typed, but it surprisingly doesn't see the lack of `flush()` on the `Decoder` class. I wonder if either of these are the cause of the occasional odd-length string error I see in the `hg serve` output from time to time. In any event, punt those changes down the road for now, and mark with a TODO.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     1
# wireprotoframing.py - unified framing protocol for wire protocol
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     2
#
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     3
# Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     4
#
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     7
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     8
# This file contains functionality to support the unified frame-based wire
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     9
# protocol. For details about the protocol, see
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    10
# `hg help internals.wireprotocol`.
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    11
51859
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 51725
diff changeset
    12
from __future__ import annotations
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    13
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
    14
import abc
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
    15
import collections
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    16
import struct
51725
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51699
diff changeset
    17
import typing
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    18
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
    19
from typing import (
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
    20
    Protocol,
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
    21
    Type,
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
    22
)
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
    23
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
    24
from .i18n import _
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
    25
from .thirdparty import attr
51725
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51699
diff changeset
    26
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51699
diff changeset
    27
# Force pytype to use the non-vendored package
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51699
diff changeset
    28
if typing.TYPE_CHECKING:
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51699
diff changeset
    29
    # noinspection PyPackageRequirements
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51699
diff changeset
    30
    import attr
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51699
diff changeset
    31
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    32
from . import (
37474
d33997123ea5 py3: system-stringify repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents: 37473
diff changeset
    33
    encoding,
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
    34
    error,
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
    35
    pycompat,
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    36
    util,
40020
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
    37
    wireprototypes,
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    38
)
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37063
diff changeset
    39
from .utils import (
39446
36f487a332ad wireprotoframing: use our CBOR module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
    40
    cborutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37063
diff changeset
    41
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37063
diff changeset
    42
)
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    43
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
    44
if typing.TYPE_CHECKING:
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
    45
    from typing import (
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
    46
        Iterator,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
    47
    )
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
    48
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
    49
    HandleSendFramesReturnT = tuple[bytes, dict[bytes, Iterator[bytearray]]]
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
    50
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    51
FRAME_HEADER_SIZE = 8
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    52
DEFAULT_MAX_FRAME_SIZE = 32768
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    53
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    54
STREAM_FLAG_BEGIN_STREAM = 0x01
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    55
STREAM_FLAG_END_STREAM = 0x02
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    56
STREAM_FLAG_ENCODING_APPLIED = 0x04
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    57
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
    58
STREAM_FLAGS: dict[bytes, int] = {
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    59
    b'stream-begin': STREAM_FLAG_BEGIN_STREAM,
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    60
    b'stream-end': STREAM_FLAG_END_STREAM,
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    61
    b'encoded': STREAM_FLAG_ENCODING_APPLIED,
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    62
}
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    63
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    64
FRAME_TYPE_COMMAND_REQUEST = 0x01
37723
e8fba6d578f0 wireprotov2: change frame type value for command data
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37722
diff changeset
    65
FRAME_TYPE_COMMAND_DATA = 0x02
37724
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
    66
FRAME_TYPE_COMMAND_RESPONSE = 0x03
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
    67
FRAME_TYPE_ERROR_RESPONSE = 0x05
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
    68
FRAME_TYPE_TEXT_OUTPUT = 0x06
37291
b0041036214e wireproto: define frame to represent progress updates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37290
diff changeset
    69
FRAME_TYPE_PROGRESS = 0x07
40125
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    70
FRAME_TYPE_SENDER_PROTOCOL_SETTINGS = 0x08
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    71
FRAME_TYPE_STREAM_SETTINGS = 0x09
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    72
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
    73
FRAME_TYPES: dict[bytes, int] = {
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    74
    b'command-request': FRAME_TYPE_COMMAND_REQUEST,
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    75
    b'command-data': FRAME_TYPE_COMMAND_DATA,
37724
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
    76
    b'command-response': FRAME_TYPE_COMMAND_RESPONSE,
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
    77
    b'error-response': FRAME_TYPE_ERROR_RESPONSE,
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
    78
    b'text-output': FRAME_TYPE_TEXT_OUTPUT,
37291
b0041036214e wireproto: define frame to represent progress updates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37290
diff changeset
    79
    b'progress': FRAME_TYPE_PROGRESS,
40125
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    80
    b'sender-protocol-settings': FRAME_TYPE_SENDER_PROTOCOL_SETTINGS,
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    81
    b'stream-settings': FRAME_TYPE_STREAM_SETTINGS,
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    82
}
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    83
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    84
FLAG_COMMAND_REQUEST_NEW = 0x01
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    85
FLAG_COMMAND_REQUEST_CONTINUATION = 0x02
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    86
FLAG_COMMAND_REQUEST_MORE_FRAMES = 0x04
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    87
FLAG_COMMAND_REQUEST_EXPECT_DATA = 0x08
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    88
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
    89
FLAGS_COMMAND_REQUEST: dict[bytes, int] = {
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    90
    b'new': FLAG_COMMAND_REQUEST_NEW,
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    91
    b'continuation': FLAG_COMMAND_REQUEST_CONTINUATION,
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    92
    b'more': FLAG_COMMAND_REQUEST_MORE_FRAMES,
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    93
    b'have-data': FLAG_COMMAND_REQUEST_EXPECT_DATA,
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    94
}
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    95
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    96
FLAG_COMMAND_DATA_CONTINUATION = 0x01
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    97
FLAG_COMMAND_DATA_EOS = 0x02
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    98
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
    99
FLAGS_COMMAND_DATA: dict[bytes, int] = {
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   100
    b'continuation': FLAG_COMMAND_DATA_CONTINUATION,
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   101
    b'eos': FLAG_COMMAND_DATA_EOS,
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   102
}
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   103
37724
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
   104
FLAG_COMMAND_RESPONSE_CONTINUATION = 0x01
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
   105
FLAG_COMMAND_RESPONSE_EOS = 0x02
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
   106
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   107
FLAGS_COMMAND_RESPONSE: dict[bytes, int] = {
37724
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
   108
    b'continuation': FLAG_COMMAND_RESPONSE_CONTINUATION,
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
   109
    b'eos': FLAG_COMMAND_RESPONSE_EOS,
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
   110
}
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
   111
40125
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   112
FLAG_SENDER_PROTOCOL_SETTINGS_CONTINUATION = 0x01
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   113
FLAG_SENDER_PROTOCOL_SETTINGS_EOS = 0x02
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   114
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   115
FLAGS_SENDER_PROTOCOL_SETTINGS: dict[bytes, int] = {
40125
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   116
    b'continuation': FLAG_SENDER_PROTOCOL_SETTINGS_CONTINUATION,
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   117
    b'eos': FLAG_SENDER_PROTOCOL_SETTINGS_EOS,
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   118
}
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   119
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   120
FLAG_STREAM_ENCODING_SETTINGS_CONTINUATION = 0x01
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   121
FLAG_STREAM_ENCODING_SETTINGS_EOS = 0x02
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   122
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   123
FLAGS_STREAM_ENCODING_SETTINGS: dict[bytes, int] = {
40125
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   124
    b'continuation': FLAG_STREAM_ENCODING_SETTINGS_CONTINUATION,
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   125
    b'eos': FLAG_STREAM_ENCODING_SETTINGS_EOS,
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   126
}
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   127
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   128
# Maps frame types to their available flags.
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   129
FRAME_TYPE_FLAGS: dict[int, dict[bytes, int]] = {
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   130
    FRAME_TYPE_COMMAND_REQUEST: FLAGS_COMMAND_REQUEST,
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   131
    FRAME_TYPE_COMMAND_DATA: FLAGS_COMMAND_DATA,
37724
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
   132
    FRAME_TYPE_COMMAND_RESPONSE: FLAGS_COMMAND_RESPONSE,
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
   133
    FRAME_TYPE_ERROR_RESPONSE: {},
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   134
    FRAME_TYPE_TEXT_OUTPUT: {},
37291
b0041036214e wireproto: define frame to represent progress updates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37290
diff changeset
   135
    FRAME_TYPE_PROGRESS: {},
40125
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   136
    FRAME_TYPE_SENDER_PROTOCOL_SETTINGS: FLAGS_SENDER_PROTOCOL_SETTINGS,
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   137
    FRAME_TYPE_STREAM_SETTINGS: FLAGS_STREAM_ENCODING_SETTINGS,
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   138
}
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   139
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   140
ARGUMENT_RECORD_HEADER = struct.Struct('<HH')
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   141
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   142
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   143
def humanflags(mapping: dict[bytes, int], value: int) -> bytes:
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   144
    """Convert a numeric flags value to a human value, using a mapping table."""
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48900
diff changeset
   145
    namemap = {v: k for k, v in mapping.items()}
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   146
    flags = []
37473
7c2c7c749411 wireproto: show unknown id and flags in repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents: 37472
diff changeset
   147
    val = 1
7c2c7c749411 wireproto: show unknown id and flags in repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents: 37472
diff changeset
   148
    while value >= val:
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   149
        if value & val:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   150
            flags.append(namemap.get(val, b'<unknown 0x%02x>' % val))
37473
7c2c7c749411 wireproto: show unknown id and flags in repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents: 37472
diff changeset
   151
        val <<= 1
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   152
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   153
    return b'|'.join(flags)
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   154
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   155
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   156
@attr.s(slots=True)
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   157
class frameheader:
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   158
    """Represents the data in a frame header."""
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   159
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   160
    length = attr.ib(type=int)
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   161
    requestid = attr.ib(type=int)
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   162
    streamid = attr.ib(type=int)
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   163
    streamflags = attr.ib(type=int)
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   164
    typeid = attr.ib(type=int)
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   165
    flags = attr.ib(type=int)
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   166
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   167
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   168
@attr.s(slots=True, repr=False)
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   169
class frame:
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   170
    """Represents a parsed frame."""
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   171
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   172
    requestid = attr.ib(type=int)
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   173
    streamid = attr.ib(type=int)
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   174
    streamflags = attr.ib(type=int)
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   175
    typeid = attr.ib(type=int)
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   176
    flags = attr.ib(type=int)
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   177
    payload = attr.ib(type=bytes)
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   178
37474
d33997123ea5 py3: system-stringify repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents: 37473
diff changeset
   179
    @encoding.strmethod
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   180
    def __repr__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   181
        typename = b'<unknown 0x%02x>' % self.typeid
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48900
diff changeset
   182
        for name, value in FRAME_TYPES.items():
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   183
            if value == self.typeid:
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   184
                typename = name
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   185
                break
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   186
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   187
        return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   188
            b'frame(size=%d; request=%d; stream=%d; streamflags=%s; '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   189
            b'type=%s; flags=%s)'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   190
            % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   191
                len(self.payload),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   192
                self.requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   193
                self.streamid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   194
                humanflags(STREAM_FLAGS, self.streamflags),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   195
                typename,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   196
                humanflags(FRAME_TYPE_FLAGS.get(self.typeid, {}), self.flags),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   197
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   198
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   199
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   200
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   201
def makeframe(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   202
    requestid: int,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   203
    streamid: int,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   204
    streamflags: int,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   205
    typeid: int,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   206
    flags: int,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   207
    payload: bytes,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   208
) -> bytearray:
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   209
    """Assemble a frame into a byte array."""
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   210
    # TODO assert size of payload.
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   211
    frame = bytearray(FRAME_HEADER_SIZE + len(payload))
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   212
37057
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   213
    # 24 bits length
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   214
    # 16 bits request id
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   215
    # 8 bits stream id
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   216
    # 8 bits stream flags
37057
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   217
    # 4 bits type
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   218
    # 4 bits flags
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   219
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   220
    l = struct.pack('<I', len(payload))
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   221
    frame[0:3] = l[0:3]
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   222
    struct.pack_into('<HBB', frame, 3, requestid, streamid, streamflags)
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   223
    frame[7] = (typeid << 4) | flags
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   224
    frame[8:] = payload
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   225
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   226
    return frame
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   227
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   228
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   229
def makeframefromhumanstring(s: bytes) -> bytearray:
37057
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   230
    """Create a frame from a human readable string
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   231
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   232
    Strings have the form:
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   233
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   234
        <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   235
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   236
    This can be used by user-facing applications and tests for creating
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   237
    frames easily without having to type out a bunch of constants.
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   238
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   239
    Request ID and stream IDs are integers.
37057
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   240
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   241
    Stream flags, frame type, and flags can be specified by integer or
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   242
    named constant.
37057
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   243
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   244
    Flags can be delimited by `|` to bitwise OR them together.
37290
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   245
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   246
    If the payload begins with ``cbor:``, the following string will be
37476
e9dea82ea1f3 wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents: 37474
diff changeset
   247
    evaluated as Python literal and the resulting object will be fed into
37290
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   248
    a CBOR encoder. Otherwise, the payload is interpreted as a Python
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   249
    byte string literal.
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   250
    """
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   251
    fields = s.split(b' ', 5)
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   252
    requestid, streamid, streamflags, frametype, frameflags, payload = fields
37057
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   253
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   254
    requestid = int(requestid)
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   255
    streamid = int(streamid)
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   256
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   257
    finalstreamflags = 0
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   258
    for flag in streamflags.split(b'|'):
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   259
        if flag in STREAM_FLAGS:
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   260
            finalstreamflags |= STREAM_FLAGS[flag]
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   261
        else:
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   262
            finalstreamflags |= int(flag)
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   263
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   264
    if frametype in FRAME_TYPES:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   265
        frametype = FRAME_TYPES[frametype]
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   266
    else:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   267
        frametype = int(frametype)
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   268
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   269
    finalflags = 0
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   270
    validflags = FRAME_TYPE_FLAGS[frametype]
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   271
    for flag in frameflags.split(b'|'):
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   272
        if flag in validflags:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   273
            finalflags |= validflags[flag]
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   274
        else:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   275
            finalflags |= int(flag)
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   276
37290
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   277
    if payload.startswith(b'cbor:'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   278
        payload = b''.join(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   279
            cborutil.streamencode(stringutil.evalpythonliteral(payload[5:]))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   280
        )
37290
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   281
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   282
    else:
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   283
        payload = stringutil.unescapestr(payload)
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   284
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   285
    return makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   286
        requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   287
        streamid=streamid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   288
        streamflags=finalstreamflags,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   289
        typeid=frametype,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   290
        flags=finalflags,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   291
        payload=payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   292
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   293
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   294
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   295
def parseheader(data: bytes) -> frameheader:
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   296
    """Parse a unified framing protocol frame header from a buffer.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   297
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   298
    The header is expected to be in the buffer at offset 0 and the
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   299
    buffer is expected to be large enough to hold a full header.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   300
    """
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   301
    # 24 bits payload length (little endian)
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   302
    # 16 bits request ID
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   303
    # 8 bits stream ID
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   304
    # 8 bits stream flags
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   305
    # 4 bits frame type
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   306
    # 4 bits frame flags
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   307
    # ... payload
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   308
    framelength = data[0] + 256 * data[1] + 16384 * data[2]
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   309
    requestid, streamid, streamflags = struct.unpack_from('<HBB', data, 3)
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   310
    typeflags = data[7]
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   311
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   312
    frametype = (typeflags & 0xF0) >> 4
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   313
    frameflags = typeflags & 0x0F
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   314
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   315
    return frameheader(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   316
        framelength, requestid, streamid, streamflags, frametype, frameflags
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   317
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   318
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   319
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   320
def readframe(fh) -> frame | None:
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   321
    """Read a unified framing protocol frame from a file object.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   322
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   323
    Returns a 3-tuple of (type, flags, payload) for the decoded frame or
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   324
    None if no frame is available. May raise if a malformed frame is
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   325
    seen.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   326
    """
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   327
    header = bytearray(FRAME_HEADER_SIZE)
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   328
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   329
    readcount = fh.readinto(header)
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   330
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   331
    if readcount == 0:
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   332
        return None
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   333
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   334
    if readcount != FRAME_HEADER_SIZE:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   335
        raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   336
            _(b'received incomplete frame: got %d bytes: %s')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   337
            % (readcount, header)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   338
        )
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   339
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   340
    h = parseheader(header)
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   341
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   342
    payload = fh.read(h.length)
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   343
    if len(payload) != h.length:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   344
        raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   345
            _(b'frame length error: expected %d; got %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   346
            % (h.length, len(payload))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   347
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   348
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   349
    return frame(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   350
        h.requestid, h.streamid, h.streamflags, h.typeid, h.flags, payload
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   351
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   352
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   353
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   354
def createcommandframes(
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   355
    stream: stream,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   356
    requestid: int,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   357
    cmd,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   358
    args,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   359
    datafh=None,
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   360
    maxframesize: int = DEFAULT_MAX_FRAME_SIZE,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   361
    redirect=None,
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   362
) -> Iterator[bytearray]:
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   363
    """Create frames necessary to transmit a request to run a command.
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   364
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   365
    This is a generator of bytearrays. Each item represents a frame
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   366
    ready to be sent over the wire to a peer.
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   367
    """
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   368
    data = {b'name': cmd}
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   369
    if args:
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   370
        data[b'args'] = args
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   371
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40020
diff changeset
   372
    if redirect:
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40020
diff changeset
   373
        data[b'redirect'] = redirect
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40020
diff changeset
   374
39446
36f487a332ad wireprotoframing: use our CBOR module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
   375
    data = b''.join(cborutil.streamencode(data))
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   376
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   377
    offset = 0
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   378
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   379
    while True:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   380
        flags = 0
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   381
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   382
        # Must set new or continuation flag.
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   383
        if not offset:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   384
            flags |= FLAG_COMMAND_REQUEST_NEW
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   385
        else:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   386
            flags |= FLAG_COMMAND_REQUEST_CONTINUATION
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   387
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   388
        # Data frames is set on all frames.
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   389
        if datafh:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   390
            flags |= FLAG_COMMAND_REQUEST_EXPECT_DATA
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   391
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   392
        payload = data[offset : offset + maxframesize]
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   393
        offset += len(payload)
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   394
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   395
        if len(payload) == maxframesize and offset < len(data):
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   396
            flags |= FLAG_COMMAND_REQUEST_MORE_FRAMES
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   397
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   398
        yield stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   399
            requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   400
            typeid=FRAME_TYPE_COMMAND_REQUEST,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   401
            flags=flags,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   402
            payload=payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   403
        )
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   404
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   405
        if not (flags & FLAG_COMMAND_REQUEST_MORE_FRAMES):
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   406
            break
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   407
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   408
    if datafh:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   409
        while True:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   410
            data = datafh.read(DEFAULT_MAX_FRAME_SIZE)
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   411
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   412
            done = False
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   413
            if len(data) == DEFAULT_MAX_FRAME_SIZE:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   414
                flags = FLAG_COMMAND_DATA_CONTINUATION
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   415
            else:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   416
                flags = FLAG_COMMAND_DATA_EOS
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   417
                assert datafh.read(1) == b''
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   418
                done = True
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   419
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   420
            yield stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   421
                requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   422
                typeid=FRAME_TYPE_COMMAND_DATA,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   423
                flags=flags,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   424
                payload=data,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   425
            )
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   426
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   427
            if done:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   428
                break
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   429
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   430
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   431
def createcommandresponseokframe(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   432
    stream: outputstream, requestid: int
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   433
) -> bytearray | None:
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
   434
    overall = b''.join(cborutil.streamencode({b'status': b'ok'}))
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
   435
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   436
    if stream.streamsettingssent:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   437
        overall = stream.encode(overall)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   438
        encoded = True
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   439
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   440
        if not overall:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   441
            return None
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   442
    else:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   443
        encoded = False
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   444
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   445
    return stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   446
        requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   447
        typeid=FRAME_TYPE_COMMAND_RESPONSE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   448
        flags=FLAG_COMMAND_RESPONSE_CONTINUATION,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   449
        payload=overall,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   450
        encoded=encoded,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   451
    )
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
   452
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   453
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   454
def createcommandresponseeosframes(
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   455
    stream: outputstream,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   456
    requestid: int,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   457
    maxframesize: int = DEFAULT_MAX_FRAME_SIZE,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   458
) -> Iterator[bytearray]:
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
   459
    """Create an empty payload frame representing command end-of-stream."""
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   460
    payload = stream.flush()
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   461
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   462
    offset = 0
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   463
    while True:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   464
        chunk = payload[offset : offset + maxframesize]
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   465
        offset += len(chunk)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   466
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   467
        done = offset == len(payload)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   468
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   469
        if done:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   470
            flags = FLAG_COMMAND_RESPONSE_EOS
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   471
        else:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   472
            flags = FLAG_COMMAND_RESPONSE_CONTINUATION
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   473
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   474
        yield stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   475
            requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   476
            typeid=FRAME_TYPE_COMMAND_RESPONSE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   477
            flags=flags,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   478
            payload=chunk,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   479
            encoded=payload != b'',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   480
        )
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   481
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   482
        if done:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   483
            break
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   484
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   485
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   486
def createalternatelocationresponseframe(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   487
    stream: outputstream, requestid: int, location
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   488
) -> bytearray:
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   489
    data = {
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   490
        b'status': b'redirect',
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   491
        b'location': {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   492
            b'url': location.url,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   493
            b'mediatype': location.mediatype,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   494
        },
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   495
    }
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   496
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   497
    for a in (
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   498
        'size',
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   499
        'fullhashes',
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   500
        'fullhashseed',
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   501
        'serverdercerts',
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   502
        'servercadercerts',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   503
    ):
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   504
        value = getattr(location, a)
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   505
        if value is not None:
52124
0c260e7158e0 typing: suppress bogus pytype errors in `mercurial/wireprotoframing.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51859
diff changeset
   506
            # pytype: disable=unsupported-operands
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   507
            data[b'location'][pycompat.bytestr(a)] = value
52124
0c260e7158e0 typing: suppress bogus pytype errors in `mercurial/wireprotoframing.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51859
diff changeset
   508
            # pytype: enable=unsupported-operands
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   509
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   510
    payload = b''.join(cborutil.streamencode(data))
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   511
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   512
    if stream.streamsettingssent:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   513
        payload = stream.encode(payload)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   514
        encoded = True
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   515
    else:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   516
        encoded = False
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   517
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   518
    return stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   519
        requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   520
        typeid=FRAME_TYPE_COMMAND_RESPONSE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   521
        flags=FLAG_COMMAND_RESPONSE_CONTINUATION,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   522
        payload=payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   523
        encoded=encoded,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   524
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   525
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   526
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   527
def createcommanderrorresponse(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   528
    stream: stream, requestid: int, message: bytes, args=None
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   529
) -> Iterator[bytearray]:
39486
43d92d68ac88 wireprotov2peer: properly format errors
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39446
diff changeset
   530
    # TODO should this be using a list of {'msg': ..., 'args': {}} so atom
43d92d68ac88 wireprotov2peer: properly format errors
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39446
diff changeset
   531
    # formatting works consistently?
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   532
    m = {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   533
        b'status': b'error',
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   534
        b'error': {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   535
            b'message': message,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   536
        },
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   537
    }
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   538
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   539
    if args:
52124
0c260e7158e0 typing: suppress bogus pytype errors in `mercurial/wireprotoframing.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51859
diff changeset
   540
        m[b'error'][b'args'] = args  # pytype: disable=unsupported-operands
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   541
39446
36f487a332ad wireprotoframing: use our CBOR module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
   542
    overall = b''.join(cborutil.streamencode(m))
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   543
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   544
    yield stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   545
        requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   546
        typeid=FRAME_TYPE_COMMAND_RESPONSE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   547
        flags=FLAG_COMMAND_RESPONSE_EOS,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   548
        payload=overall,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   549
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   550
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   551
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   552
def createerrorframe(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   553
    stream: stream, requestid: int, msg: bytes, errtype: bytes
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   554
) -> Iterator[bytearray]:
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
   555
    # TODO properly handle frame size limits.
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
   556
    assert len(msg) <= DEFAULT_MAX_FRAME_SIZE
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
   557
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   558
    payload = b''.join(
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   559
        cborutil.streamencode(
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   560
            {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   561
                b'type': errtype,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   562
                b'message': [{b'msg': msg}],
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   563
            }
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   564
        )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   565
    )
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
   566
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   567
    yield stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   568
        requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   569
        typeid=FRAME_TYPE_ERROR_RESPONSE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   570
        flags=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   571
        payload=payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   572
    )
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
   573
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   574
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   575
def createtextoutputframe(
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   576
    stream: stream,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   577
    requestid: int,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   578
    atoms,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   579
    maxframesize: int = DEFAULT_MAX_FRAME_SIZE,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   580
) -> Iterator[bytearray]:
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   581
    """Create a text output frame to render text to people.
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   582
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   583
    ``atoms`` is a 3-tuple of (formatting string, args, labels).
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   584
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   585
    The formatting string contains ``%s`` tokens to be replaced by the
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   586
    corresponding indexed entry in ``args``. ``labels`` is an iterable of
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   587
    formatters to be applied at rendering time. In terms of the ``ui``
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   588
    class, each atom corresponds to a ``ui.write()``.
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   589
    """
37319
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   590
    atomdicts = []
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   591
51699
ca7bde5dbafb black: format the codebase with 23.3.0
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51696
diff changeset
   592
    for formatting, args, labels in atoms:
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   593
        # TODO look for localstr, other types here?
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   594
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   595
        if not isinstance(formatting, bytes):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   596
            raise ValueError(b'must use bytes formatting strings')
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   597
        for arg in args:
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   598
            if not isinstance(arg, bytes):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   599
                raise ValueError(b'must use bytes for arguments')
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   600
        for label in labels:
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   601
            if not isinstance(label, bytes):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   602
                raise ValueError(b'must use bytes for labels')
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   603
37319
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   604
        # Formatting string must be ASCII.
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   605
        formatting = formatting.decode('ascii', 'replace').encode('ascii')
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   606
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   607
        # Arguments must be UTF-8.
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   608
        args = [a.decode('utf-8', 'replace').encode('utf-8') for a in args]
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   609
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   610
        # Labels must be ASCII.
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   611
        labels = [l.decode('ascii', 'strict').encode('ascii') for l in labels]
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   612
37319
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   613
        atom = {b'msg': formatting}
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   614
        if args:
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   615
            atom[b'args'] = args
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   616
        if labels:
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   617
            atom[b'labels'] = labels
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   618
37319
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   619
        atomdicts.append(atom)
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   620
39446
36f487a332ad wireprotoframing: use our CBOR module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
   621
    payload = b''.join(cborutil.streamencode(atomdicts))
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   622
37319
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   623
    if len(payload) > maxframesize:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   624
        raise ValueError(b'cannot encode data in a single frame')
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   625
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   626
    yield stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   627
        requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   628
        typeid=FRAME_TYPE_TEXT_OUTPUT,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   629
        flags=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   630
        payload=payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   631
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   632
37285
3ed344546d9e wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37084
diff changeset
   633
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   634
class bufferingcommandresponseemitter:
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   635
    """Helper object to emit command response frames intelligently.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   636
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   637
    Raw command response data is likely emitted in chunks much smaller
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   638
    than what can fit in a single frame. This class exists to buffer
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   639
    chunks until enough data is available to fit in a single frame.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   640
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   641
    TODO we'll need something like this when compression is supported.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   642
    So it might make sense to implement this functionality at the stream
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   643
    level.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   644
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   645
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   646
    def __init__(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   647
        self, stream, requestid: int, maxframesize: int = DEFAULT_MAX_FRAME_SIZE
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   648
    ) -> None:
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   649
        self._stream = stream
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   650
        self._requestid = requestid
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   651
        self._maxsize = maxframesize
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   652
        self._chunks = []
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   653
        self._chunkssize = 0
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   654
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   655
    def send(self, data):
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   656
        """Send new data for emission.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   657
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   658
        Is a generator of new frames that were derived from the new input.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   659
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   660
        If the special input ``None`` is received, flushes all buffered
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   661
        data to frames.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   662
        """
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   663
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   664
        if data is None:
52644
e627cc25b6f3 pyupgrade: rewrite `yield` statements in a loop to `yield from`
Matt Harbison <matt_harbison@yahoo.com>
parents: 52643
diff changeset
   665
            yield from self._flush()
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   666
            return
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   667
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   668
        data = self._stream.encode(data)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   669
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   670
        # There is a ton of potential to do more complicated things here.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   671
        # Our immediate goal is to coalesce small chunks into big frames,
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   672
        # not achieve the fewest number of frames possible. So we go with
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   673
        # a simple implementation:
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   674
        #
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   675
        # * If a chunk is too large for a frame, we flush and emit frames
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   676
        #   for the new chunk.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   677
        # * If a chunk can be buffered without total buffered size limits
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   678
        #   being exceeded, we do that.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   679
        # * If a chunk causes us to go over our buffering limit, we flush
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   680
        #   and then buffer the new chunk.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   681
40136
3a6d6c54bd81 wireprotov2: don't emit empty frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40135
diff changeset
   682
        if not data:
3a6d6c54bd81 wireprotov2: don't emit empty frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40135
diff changeset
   683
            return
3a6d6c54bd81 wireprotov2: don't emit empty frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40135
diff changeset
   684
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   685
        if len(data) > self._maxsize:
52644
e627cc25b6f3 pyupgrade: rewrite `yield` statements in a loop to `yield from`
Matt Harbison <matt_harbison@yahoo.com>
parents: 52643
diff changeset
   686
            yield from self._flush()
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   687
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   688
            # Now emit frames for the big chunk.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   689
            offset = 0
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   690
            while True:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   691
                chunk = data[offset : offset + self._maxsize]
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   692
                offset += len(chunk)
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   693
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   694
                yield self._stream.makeframe(
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   695
                    self._requestid,
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   696
                    typeid=FRAME_TYPE_COMMAND_RESPONSE,
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   697
                    flags=FLAG_COMMAND_RESPONSE_CONTINUATION,
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   698
                    payload=chunk,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   699
                    encoded=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   700
                )
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   701
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   702
                if offset == len(data):
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   703
                    return
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   704
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   705
        # If we don't have enough to constitute a full frame, buffer and
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   706
        # return.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   707
        if len(data) + self._chunkssize < self._maxsize:
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   708
            self._chunks.append(data)
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   709
            self._chunkssize += len(data)
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   710
            return
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   711
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   712
        # Else flush what we have and buffer the new chunk. We could do
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   713
        # something more intelligent here, like break the chunk. Let's
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   714
        # keep things simple for now.
52644
e627cc25b6f3 pyupgrade: rewrite `yield` statements in a loop to `yield from`
Matt Harbison <matt_harbison@yahoo.com>
parents: 52643
diff changeset
   715
        yield from self._flush()
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   716
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   717
        self._chunks.append(data)
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   718
        self._chunkssize = len(data)
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   719
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   720
    def _flush(self):
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   721
        payload = b''.join(self._chunks)
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   722
        assert len(payload) <= self._maxsize
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   723
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   724
        self._chunks[:] = []
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   725
        self._chunkssize = 0
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   726
40136
3a6d6c54bd81 wireprotov2: don't emit empty frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40135
diff changeset
   727
        if not payload:
3a6d6c54bd81 wireprotov2: don't emit empty frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40135
diff changeset
   728
            return
3a6d6c54bd81 wireprotov2: don't emit empty frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40135
diff changeset
   729
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   730
        yield self._stream.makeframe(
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   731
            self._requestid,
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   732
            typeid=FRAME_TYPE_COMMAND_RESPONSE,
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   733
            flags=FLAG_COMMAND_RESPONSE_CONTINUATION,
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   734
            payload=payload,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   735
            encoded=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   736
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   737
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   738
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   739
# TODO consider defining encoders/decoders using the util.compressionengine
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   740
# mechanism.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   741
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   742
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   743
class Encoder(Protocol):
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   744
    """A protocol class for the various encoder implementations."""
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   745
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   746
    @abc.abstractmethod
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   747
    def encode(self, data) -> bytes:
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   748
        raise NotImplementedError
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   749
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   750
    @abc.abstractmethod
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   751
    def flush(self) -> bytes:
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   752
        raise NotImplementedError
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   753
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   754
    @abc.abstractmethod
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   755
    def finish(self) -> bytes:
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   756
        raise NotImplementedError
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   757
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   758
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   759
class Decoder(Protocol):
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   760
    """A protocol class for the various encoder implementations."""
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   761
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   762
    @abc.abstractmethod
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   763
    def decode(self, data) -> bytes:
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   764
        raise NotImplementedError
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   765
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   766
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   767
class identityencoder(Encoder):
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   768
    """Encoder for the "identity" stream encoding profile."""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   769
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   770
    def __init__(self, ui) -> None:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   771
        pass
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   772
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   773
    def encode(self, data) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   774
        return data
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   775
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   776
    def flush(self) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   777
        return b''
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   778
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   779
    def finish(self) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   780
        return b''
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   781
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   782
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   783
class identitydecoder(Decoder):
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   784
    """Decoder for the "identity" stream encoding profile."""
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   785
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   786
    def __init__(self, ui, extraobjs) -> None:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   787
        if extraobjs:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   788
            raise error.Abort(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
   789
                _(b'identity decoder received unexpected additional values')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   790
            )
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   791
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   792
    def decode(self, data) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   793
        return data
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   794
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   795
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   796
class zlibencoder(Encoder):
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   797
    def __init__(self, ui) -> None:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   798
        import zlib
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   799
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   800
        self._zlib = zlib
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   801
        self._compressor = zlib.compressobj()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   802
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   803
    def encode(self, data) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   804
        return self._compressor.compress(data)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   805
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   806
    def flush(self) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   807
        # Z_SYNC_FLUSH doesn't reset compression context, which is
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   808
        # what we want.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   809
        return self._compressor.flush(self._zlib.Z_SYNC_FLUSH)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   810
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   811
    def finish(self) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   812
        res = self._compressor.flush(self._zlib.Z_FINISH)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   813
        self._compressor = None
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   814
        return res
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   815
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   816
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   817
class zlibdecoder(Decoder):
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   818
    def __init__(self, ui, extraobjs) -> None:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   819
        import zlib
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   820
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   821
        if extraobjs:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   822
            raise error.Abort(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
   823
                _(b'zlib decoder received unexpected additional values')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   824
            )
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   825
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   826
        self._decompressor = zlib.decompressobj()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   827
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   828
    def decode(self, data) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   829
        return self._decompressor.decompress(data)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   830
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   831
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   832
class zstdbaseencoder(Encoder):
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   833
    def __init__(self, level: int) -> None:
52124
0c260e7158e0 typing: suppress bogus pytype errors in `mercurial/wireprotoframing.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51859
diff changeset
   834
        from . import zstd  # pytype: disable=import-error
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   835
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   836
        self._zstd = zstd
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   837
        cctx = zstd.ZstdCompressor(level=level)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   838
        self._compressor = cctx.compressobj()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   839
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   840
    def encode(self, data) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   841
        return self._compressor.compress(data)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   842
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   843
    def flush(self) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   844
        # COMPRESSOBJ_FLUSH_BLOCK flushes all data previously fed into the
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   845
        # compressor and allows a decompressor to access all encoded data
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   846
        # up to this point.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   847
        return self._compressor.flush(self._zstd.COMPRESSOBJ_FLUSH_BLOCK)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   848
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   849
    def finish(self) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   850
        res = self._compressor.flush(self._zstd.COMPRESSOBJ_FLUSH_FINISH)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   851
        self._compressor = None
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   852
        return res
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   853
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   854
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   855
class zstd8mbencoder(zstdbaseencoder):
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   856
    def __init__(self, ui) -> None:
52643
5cc8deb96b48 pyupgrade: modernize calls to superclass methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 52124
diff changeset
   857
        super().__init__(3)
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   858
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   859
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   860
class zstdbasedecoder(Decoder):
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   861
    def __init__(self, maxwindowsize: int) -> None:
52124
0c260e7158e0 typing: suppress bogus pytype errors in `mercurial/wireprotoframing.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51859
diff changeset
   862
        from . import zstd  # pytype: disable=import-error
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   863
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   864
        dctx = zstd.ZstdDecompressor(max_window_size=maxwindowsize)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   865
        self._decompressor = dctx.decompressobj()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   866
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   867
    def decode(self, data) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   868
        return self._decompressor.decompress(data)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   869
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   870
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   871
class zstd8mbdecoder(zstdbasedecoder):
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   872
    def __init__(self, ui, extraobjs) -> None:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   873
        if extraobjs:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   874
            raise error.Abort(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
   875
                _(b'zstd8mb decoder received unexpected additional values')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   876
            )
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   877
52643
5cc8deb96b48 pyupgrade: modernize calls to superclass methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 52124
diff changeset
   878
        super().__init__(maxwindowsize=8 * 1048576)
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   879
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   880
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   881
# TypeVar('EncoderT', bound=Encoder) was flagged as "not in scope" when used
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   882
# on the STREAM_ENCODERS dict below.
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   883
if typing.TYPE_CHECKING:
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   884
    EncoderT = Type[identityencoder | zlibencoder | zstd8mbencoder]
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   885
    DecoderT = Type[identitydecoder | zlibdecoder | zstd8mbdecoder]
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   886
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   887
# We lazily populate this to avoid excessive module imports when importing
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   888
# this module.
52698
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   889
STREAM_ENCODERS: dict[bytes, tuple[EncoderT, DecoderT]] = {}
1a612f9ec2c4 typing: add type annotations for wireprotoframing encoder/decoder classes
Matt Harbison <matt_harbison@yahoo.com>
parents: 52644
diff changeset
   890
STREAM_ENCODERS_ORDER: list[bytes] = []
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   891
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   892
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   893
def populatestreamencoders() -> None:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   894
    if STREAM_ENCODERS:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   895
        return
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   896
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   897
    try:
52124
0c260e7158e0 typing: suppress bogus pytype errors in `mercurial/wireprotoframing.py`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51859
diff changeset
   898
        from . import zstd  # pytype: disable=import-error
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   899
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   900
        zstd.__version__
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   901
    except ImportError:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   902
        zstd = None
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   903
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   904
    # zstandard is fastest and is preferred.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   905
    if zstd:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   906
        STREAM_ENCODERS[b'zstd-8mb'] = (zstd8mbencoder, zstd8mbdecoder)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   907
        STREAM_ENCODERS_ORDER.append(b'zstd-8mb')
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   908
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   909
    STREAM_ENCODERS[b'zlib'] = (zlibencoder, zlibdecoder)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   910
    STREAM_ENCODERS_ORDER.append(b'zlib')
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   911
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   912
    STREAM_ENCODERS[b'identity'] = (identityencoder, identitydecoder)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   913
    STREAM_ENCODERS_ORDER.append(b'identity')
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   914
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   915
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   916
class stream:
37285
3ed344546d9e wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37084
diff changeset
   917
    """Represents a logical unidirectional series of frames."""
3ed344546d9e wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37084
diff changeset
   918
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   919
    streamid: int
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   920
    _active: bool
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   921
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   922
    def __init__(self, streamid: int, active: bool = False) -> None:
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   923
        self.streamid = streamid
37655
b9502b5f2066 wireprotoframing: use value passed into function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37544
diff changeset
   924
        self._active = active
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   925
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   926
    def makeframe(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   927
        self, requestid: int, typeid: int, flags: int, payload: bytes
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   928
    ) -> bytearray:
37285
3ed344546d9e wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37084
diff changeset
   929
        """Create a frame to be sent out over this stream.
3ed344546d9e wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37084
diff changeset
   930
3ed344546d9e wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37084
diff changeset
   931
        Only returns the frame instance. Does not actually send it.
3ed344546d9e wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37084
diff changeset
   932
        """
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   933
        streamflags = 0
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   934
        if not self._active:
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   935
            streamflags |= STREAM_FLAG_BEGIN_STREAM
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   936
            self._active = True
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   937
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   938
        return makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   939
            requestid, self.streamid, streamflags, typeid, flags, payload
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   940
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   941
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   942
40130
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
   943
class inputstream(stream):
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
   944
    """Represents a stream used for receiving data."""
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
   945
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   946
    _decoder: Decoder | None
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   947
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   948
    def __init__(self, streamid: int, active: bool = False) -> None:
52643
5cc8deb96b48 pyupgrade: modernize calls to superclass methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 52124
diff changeset
   949
        super().__init__(streamid, active=active)
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   950
        self._decoder = None
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   951
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   952
    def setdecoder(self, ui, name: bytes, extraobjs) -> None:
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
   953
        """Set the decoder for this stream.
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
   954
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
   955
        Receives the stream profile name and any additional CBOR objects
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
   956
        decoded from the stream encoding settings frame payloads.
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
   957
        """
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   958
        if name not in STREAM_ENCODERS:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   959
            raise error.Abort(_(b'unknown stream decoder: %s') % name)
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   960
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   961
        self._decoder = STREAM_ENCODERS[name][1](ui, extraobjs)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   962
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   963
    def decode(self, data) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   964
        # Default is identity decoder. We don't bother instantiating one
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   965
        # because it is trivial.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   966
        if not self._decoder:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   967
            return data
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   968
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   969
        return self._decoder.decode(data)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   970
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   971
    def flush(self) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   972
        if not self._decoder:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   973
            return b''
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   974
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   975
        # TODO: this looks like a bug- no decoder class defines flush(), so
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   976
        #  either no decoders are used, or no inputstream is flushed.
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   977
        return self._decoder.flush()
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
   978
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   979
40130
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
   980
class outputstream(stream):
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
   981
    """Represents a stream used for sending data."""
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
   982
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   983
    streamsettingssent: bool
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   984
    _encoder: Encoder | None
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   985
    _encodername: bytes | None
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   986
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   987
    def __init__(self, streamid: int, active: bool = False) -> None:
52643
5cc8deb96b48 pyupgrade: modernize calls to superclass methods
Matt Harbison <matt_harbison@yahoo.com>
parents: 52124
diff changeset
   988
        super().__init__(streamid, active=active)
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   989
        self.streamsettingssent = False
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   990
        self._encoder = None
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   991
        self._encodername = None
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   992
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
   993
    def setencoder(self, ui, name: bytes) -> None:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   994
        """Set the encoder for this stream.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   995
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   996
        Receives the stream profile name.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   997
        """
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   998
        if name not in STREAM_ENCODERS:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   999
            raise error.Abort(_(b'unknown stream encoder: %s') % name)
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1000
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1001
        self._encoder = STREAM_ENCODERS[name][0](ui)
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1002
        self._encodername = name
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1003
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1004
    def encode(self, data) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1005
        if not self._encoder:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1006
            return data
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1007
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1008
        return self._encoder.encode(data)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1009
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1010
    def flush(self) -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1011
        if not self._encoder:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1012
            return b''
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1013
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1014
        return self._encoder.flush()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1015
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1016
    # TODO: was this supposed to return the result of finish()?
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1017
    def finish(self):  # -> bytes:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1018
        if not self._encoder:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1019
            return b''
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1020
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1021
        self._encoder.finish()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1022
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1023
    def makeframe(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1024
        self,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1025
        requestid: int,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1026
        typeid: int,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1027
        flags: int,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1028
        payload: bytes,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1029
        encoded: bool = False,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1030
    ) -> bytearray:
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1031
        """Create a frame to be sent out over this stream.
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1032
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1033
        Only returns the frame instance. Does not actually send it.
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1034
        """
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1035
        streamflags = 0
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1036
        if not self._active:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1037
            streamflags |= STREAM_FLAG_BEGIN_STREAM
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1038
            self._active = True
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1039
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1040
        if encoded:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1041
            if not self.streamsettingssent:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1042
                raise error.ProgrammingError(
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1043
                    b'attempting to send encoded frame without sending stream '
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1044
                    b'settings'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1045
                )
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1046
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1047
            streamflags |= STREAM_FLAG_ENCODING_APPLIED
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1048
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1049
        if (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1050
            typeid == FRAME_TYPE_STREAM_SETTINGS
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1051
            and flags & FLAG_STREAM_ENCODING_SETTINGS_EOS
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1052
        ):
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1053
            self.streamsettingssent = True
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1054
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1055
        return makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1056
            requestid, self.streamid, streamflags, typeid, flags, payload
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1057
        )
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1058
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1059
    def makestreamsettingsframe(self, requestid: int) -> bytearray | None:
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1060
        """Create a stream settings frame for this stream.
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1061
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1062
        Returns frame data or None if no stream settings frame is needed or has
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1063
        already been sent.
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1064
        """
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1065
        if not self._encoder or self.streamsettingssent:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1066
            return None
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1067
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1068
        payload = b''.join(cborutil.streamencode(self._encodername))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1069
        return self.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1070
            requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1071
            FRAME_TYPE_STREAM_SETTINGS,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1072
            FLAG_STREAM_ENCODING_SETTINGS_EOS,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1073
            payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1074
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1075
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1076
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1077
def ensureserverstream(stream: stream) -> None:
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1078
    if stream.streamid % 2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1079
        raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1080
            b'server should only write to even '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1081
            b'numbered streams; %d is not even' % stream.streamid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1082
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1083
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
  1084
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1085
DEFAULT_PROTOCOL_SETTINGS: dict[bytes, list[bytes]] = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1086
    b'contentencodings': [b'identity'],
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1087
}
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1088
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1089
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
  1090
class serverreactor:
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1091
    """Holds state of a server handling frame-based protocol requests.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1092
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1093
    This class is the "brain" of the unified frame-based protocol server
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1094
    component. While the protocol is stateless from the perspective of
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1095
    requests/commands, something needs to track which frames have been
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1096
    received, what frames to expect, etc. This class is that thing.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1097
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1098
    Instances are modeled as a state machine of sorts. Instances are also
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1099
    reactionary to external events. The point of this class is to encapsulate
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1100
    the state of the connection and the exchange of frames, not to perform
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1101
    work. Instead, callers tell this class when something occurs, like a
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1102
    frame arriving. If that activity is worthy of a follow-up action (say
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1103
    *run a command*), the return value of that handler will say so.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1104
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1105
    I/O and CPU intensive operations are purposefully delegated outside of
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1106
    this class.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1107
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1108
    Consumers are expected to tell instances when events occur. They do so by
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1109
    calling the various ``on*`` methods. These methods return a 2-tuple
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1110
    describing any follow-up action(s) to take. The first element is the
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1111
    name of an action to perform. The second is a data structure (usually
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1112
    a dict) specific to that action that contains more information. e.g.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1113
    if the server wants to send frames back to the client, the data structure
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1114
    will contain a reference to those frames.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1115
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1116
    Valid actions that consumers can be instructed to take are:
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1117
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
  1118
    sendframes
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
  1119
       Indicates that frames should be sent to the client. The ``framegen``
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
  1120
       key contains a generator of frames that should be sent. The server
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
  1121
       assumes that all frames are sent to the client.
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
  1122
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1123
    error
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1124
       Indicates that an error occurred. Consumer should probably abort.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1125
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1126
    runcommand
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1127
       Indicates that the consumer should run a wire protocol command. Details
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1128
       of the command to run are given in the data structure.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1129
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1130
    wantframe
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1131
       Indicates that nothing of interest happened and the server is waiting on
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1132
       more frames from the client before anything interesting can be done.
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1133
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1134
    noop
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1135
       Indicates no additional action is required.
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1136
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1137
    Known Issues
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1138
    ------------
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1139
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1140
    There are no limits to the number of partially received commands or their
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1141
    size. A malicious client could stream command request data and exhaust the
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1142
    server's memory.
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1143
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1144
    Partially received commands are not acted upon when end of input is
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1145
    reached. Should the server error if it receives a partial request?
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1146
    Should the client send a message to abort a partially transmitted request
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1147
    to facilitate graceful shutdown?
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1148
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1149
    Active requests that haven't been responded to aren't tracked. This means
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1150
    that if we receive a command and instruct its dispatch, another command
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1151
    with its request ID can come in over the wire and there will be a race
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1152
    between who responds to what.
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1153
    """
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1154
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1155
    _bufferedframegens: list[Iterator[bytearray]]
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1156
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1157
    def __init__(self, ui, deferoutput: bool = False) -> None:
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1158
        """Construct a new server reactor.
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1159
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1160
        ``deferoutput`` can be used to indicate that no output frames should be
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1161
        instructed to be sent until input has been exhausted. In this mode,
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1162
        events that would normally generate output frames (such as a command
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1163
        response being ready) will instead defer instructing the consumer to
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1164
        send those frames. This is useful for half-duplex transports where the
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1165
        sender cannot receive until all data has been transmitted.
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1166
        """
40129
293835e0fff7 wireprotov2: pass ui into clientreactor and serverreactor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40128
diff changeset
  1167
        self._ui = ui
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1168
        self._deferoutput = deferoutput
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1169
        self._state = b'initial'
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1170
        self._nextoutgoingstreamid = 2
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1171
        self._bufferedframegens = []
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1172
        # stream id -> stream instance for all active streams from the client.
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1173
        self._incomingstreams = {}
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1174
        self._outgoingstreams = {}
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1175
        # request id -> dict of commands that are actively being received.
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1176
        self._receivingcommands = {}
37063
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1177
        # Request IDs that have been received and are actively being processed.
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1178
        # Once all output for a request has been sent, it is removed from this
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1179
        # set.
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1180
        self._activecommands = set()
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1181
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1182
        self._protocolsettingsdecoder = None
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1183
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1184
        # Sender protocol settings are optional. Set implied default values.
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1185
        self._sendersettings = dict(DEFAULT_PROTOCOL_SETTINGS)
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1186
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1187
        populatestreamencoders()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1188
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1189
    def onframerecv(self, frame: frame):
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1190
        """Process a frame that has been received off the wire.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1191
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1192
        Returns a dict with an ``action`` key that details what action,
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1193
        if any, the consumer should take next.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1194
        """
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1195
        if not frame.streamid % 2:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1196
            self._state = b'errored'
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1197
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1198
                _(b'received frame with even numbered stream ID: %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1199
                % frame.streamid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1200
            )
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1201
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1202
        if frame.streamid not in self._incomingstreams:
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1203
            if not frame.streamflags & STREAM_FLAG_BEGIN_STREAM:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1204
                self._state = b'errored'
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1205
                return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1206
                    _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1207
                        b'received frame on unknown inactive stream without '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1208
                        b'beginning of stream flag set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1209
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1210
                )
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1211
40130
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
  1212
            self._incomingstreams[frame.streamid] = inputstream(frame.streamid)
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1213
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1214
        if frame.streamflags & STREAM_FLAG_ENCODING_APPLIED:
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1215
            # TODO handle decoding frames
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1216
            self._state = b'errored'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1217
            raise error.ProgrammingError(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
  1218
                b'support for decoding stream payloads not yet implemented'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1219
            )
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1220
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1221
        if frame.streamflags & STREAM_FLAG_END_STREAM:
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1222
            del self._incomingstreams[frame.streamid]
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1223
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1224
        handlers = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1225
            b'initial': self._onframeinitial,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1226
            b'protocol-settings-receiving': self._onframeprotocolsettings,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1227
            b'idle': self._onframeidle,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1228
            b'command-receiving': self._onframecommandreceiving,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1229
            b'errored': self._onframeerrored,
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1230
        }
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1231
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1232
        meth = handlers.get(self._state)
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1233
        if not meth:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1234
            raise error.ProgrammingError(b'unhandled state: %s' % self._state)
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1235
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1236
        return meth(frame)
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1237
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1238
    def oncommandresponsereadyobjects(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1239
        self, stream, requestid: int, objs
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1240
    ) -> HandleSendFramesReturnT:
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1241
        """Signal that objects are ready to be sent to the client.
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1242
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1243
        ``objs`` is an iterable of objects (typically a generator) that will
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1244
        be encoded via CBOR and added to frames, which will be sent to the
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1245
        client.
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1246
        """
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1247
        ensureserverstream(stream)
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1248
40135
966b5f7fd30b wireprotov2: remove functions for creating response frames from bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40133
diff changeset
  1249
        # A more robust solution would be to check for objs.{next,__next__}.
966b5f7fd30b wireprotov2: remove functions for creating response frames from bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40133
diff changeset
  1250
        if isinstance(objs, list):
966b5f7fd30b wireprotov2: remove functions for creating response frames from bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40133
diff changeset
  1251
            objs = iter(objs)
966b5f7fd30b wireprotov2: remove functions for creating response frames from bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40133
diff changeset
  1252
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1253
        # We need to take care over exception handling. Uncaught exceptions
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1254
        # when generating frames could lead to premature end of the frame
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1255
        # stream and the possibility of the server or client process getting
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1256
        # in a bad state.
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1257
        #
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1258
        # Keep in mind that if ``objs`` is a generator, advancing it could
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1259
        # raise exceptions that originated in e.g. wire protocol command
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1260
        # functions. That is why we differentiate between exceptions raised
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1261
        # when iterating versus other exceptions that occur.
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1262
        #
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1263
        # In all cases, when the function finishes, the request is fully
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1264
        # handled and no new frames for it should be seen.
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1265
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1266
        def sendframes():
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1267
            emitted = False
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1268
            alternatelocationsent = False
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
  1269
            emitter = bufferingcommandresponseemitter(stream, requestid)
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1270
            while True:
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1271
                try:
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1272
                    o = next(objs)
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1273
                except StopIteration:
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
  1274
                    for frame in emitter.send(None):
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
  1275
                        yield frame
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
  1276
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1277
                    if emitted:
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1278
                        for frame in createcommandresponseeosframes(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1279
                            stream, requestid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1280
                        ):
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1281
                            yield frame
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1282
                    break
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1283
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1284
                except error.WireprotoCommandError as e:
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1285
                    for frame in createcommanderrorresponse(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1286
                        stream, requestid, e.message, e.messageargs
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1287
                    ):
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1288
                        yield frame
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1289
                    break
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1290
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1291
                except Exception as e:
39838
bce1c1af7518 py3: cast exception to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39560
diff changeset
  1292
                    for frame in createerrorframe(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1293
                        stream,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1294
                        requestid,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1295
                        b'%s' % stringutil.forcebytestr(e),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1296
                        errtype=b'server',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1297
                    ):
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1298
                        yield frame
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1299
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1300
                    break
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1301
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1302
                try:
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1303
                    # Alternate location responses can only be the first and
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1304
                    # only object in the output stream.
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1305
                    if isinstance(o, wireprototypes.alternatelocationresponse):
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1306
                        if emitted:
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1307
                            raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1308
                                b'alternatelocationresponse seen after initial '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1309
                                b'output object'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1310
                            )
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1311
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1312
                        frame = stream.makestreamsettingsframe(requestid)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1313
                        if frame:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1314
                            yield frame
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1315
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1316
                        yield createalternatelocationresponseframe(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1317
                            stream, requestid, o
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1318
                        )
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1319
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1320
                        alternatelocationsent = True
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1321
                        emitted = True
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1322
                        continue
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1323
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1324
                    if alternatelocationsent:
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1325
                        raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1326
                            b'object follows alternatelocationresponse'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1327
                        )
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1328
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1329
                    if not emitted:
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1330
                        # Frame is optional.
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1331
                        frame = stream.makestreamsettingsframe(requestid)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1332
                        if frame:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1333
                            yield frame
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1334
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1335
                        # May be None if empty frame (due to encoding).
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1336
                        frame = createcommandresponseokframe(stream, requestid)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1337
                        if frame:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1338
                            yield frame
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1339
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1340
                        emitted = True
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1341
40020
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1342
                    # Objects emitted by command functions can be serializable
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1343
                    # data structures or special types.
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1344
                    # TODO consider extracting the content normalization to a
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1345
                    # standalone function, as it may be useful for e.g. cachers.
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1346
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1347
                    # A pre-encoded object is sent directly to the emitter.
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1348
                    if isinstance(o, wireprototypes.encodedresponse):
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1349
                        for frame in emitter.send(o.data):
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
  1350
                            yield frame
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
  1351
40328
2c55716f8a1c wireprotov2: add response type that serializes to indefinite length bytestring
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40138
diff changeset
  1352
                    elif isinstance(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1353
                        o, wireprototypes.indefinitebytestringresponse
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1354
                    ):
40328
2c55716f8a1c wireprotov2: add response type that serializes to indefinite length bytestring
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40138
diff changeset
  1355
                        for chunk in cborutil.streamencodebytestringfromiter(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1356
                            o.chunks
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1357
                        ):
40328
2c55716f8a1c wireprotov2: add response type that serializes to indefinite length bytestring
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40138
diff changeset
  1358
                            for frame in emitter.send(chunk):
2c55716f8a1c wireprotov2: add response type that serializes to indefinite length bytestring
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40138
diff changeset
  1359
                                yield frame
2c55716f8a1c wireprotov2: add response type that serializes to indefinite length bytestring
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40138
diff changeset
  1360
40020
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1361
                    # A regular object is CBOR encoded.
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1362
                    else:
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1363
                        for chunk in cborutil.streamencode(o):
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1364
                            for frame in emitter.send(chunk):
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1365
                                yield frame
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1366
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1367
                except Exception as e:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1368
                    for frame in createerrorframe(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1369
                        stream, requestid, b'%s' % e, errtype=b'server'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1370
                    ):
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1371
                        yield frame
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1372
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1373
                    break
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1374
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1375
            self._activecommands.remove(requestid)
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1376
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1377
        return self._handlesendframes(sendframes())
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1378
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1379
    def oninputeof(self) -> tuple[bytes, dict[bytes, Iterator[bytearray]]]:
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1380
        """Signals that end of input has been received.
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1381
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1382
        No more frames will be received. All pending activity should be
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1383
        completed.
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1384
        """
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1385
        # TODO should we do anything about in-flight commands?
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1386
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1387
        if not self._deferoutput or not self._bufferedframegens:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1388
            return b'noop', {}
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1389
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1390
        # If we buffered all our responses, emit those.
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1391
        def makegen():
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1392
            for gen in self._bufferedframegens:
52644
e627cc25b6f3 pyupgrade: rewrite `yield` statements in a loop to `yield from`
Matt Harbison <matt_harbison@yahoo.com>
parents: 52643
diff changeset
  1393
                yield from gen
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1394
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1395
        return b'sendframes', {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1396
            b'framegen': makegen(),
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1397
        }
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
  1398
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1399
    def _handlesendframes(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1400
        self, framegen: Iterator[bytearray]
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1401
    ) -> HandleSendFramesReturnT:
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1402
        if self._deferoutput:
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1403
            self._bufferedframegens.append(framegen)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1404
            return b'noop', {}
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1405
        else:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1406
            return b'sendframes', {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1407
                b'framegen': framegen,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1408
            }
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1409
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1410
    def onservererror(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1411
        self, stream: stream, requestid: int, msg: bytes
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1412
    ) -> HandleSendFramesReturnT:
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1413
        ensureserverstream(stream)
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1414
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1415
        def sendframes():
52644
e627cc25b6f3 pyupgrade: rewrite `yield` statements in a loop to `yield from`
Matt Harbison <matt_harbison@yahoo.com>
parents: 52643
diff changeset
  1416
            yield from createerrorframe(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1417
                stream, requestid, msg, errtype=b'server'
52644
e627cc25b6f3 pyupgrade: rewrite `yield` statements in a loop to `yield from`
Matt Harbison <matt_harbison@yahoo.com>
parents: 52643
diff changeset
  1418
            )
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1419
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1420
            self._activecommands.remove(requestid)
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1421
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1422
        return self._handlesendframes(sendframes())
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1423
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1424
    def oncommanderror(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1425
        self, stream: stream, requestid: int, message: bytes, args=None
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1426
    ) -> HandleSendFramesReturnT:
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1427
        """Called when a command encountered an error before sending output."""
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1428
        ensureserverstream(stream)
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1429
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1430
        def sendframes():
52644
e627cc25b6f3 pyupgrade: rewrite `yield` statements in a loop to `yield from`
Matt Harbison <matt_harbison@yahoo.com>
parents: 52643
diff changeset
  1431
            yield from createcommanderrorresponse(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1432
                stream, requestid, message, args
52644
e627cc25b6f3 pyupgrade: rewrite `yield` statements in a loop to `yield from`
Matt Harbison <matt_harbison@yahoo.com>
parents: 52643
diff changeset
  1433
            )
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1434
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1435
            self._activecommands.remove(requestid)
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1436
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1437
        return self._handlesendframes(sendframes())
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
  1438
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1439
    def makeoutputstream(self) -> outputstream:
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1440
        """Create a stream to be used for sending data to the client.
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1441
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1442
        If this is called before protocol settings frames are received, we
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1443
        don't know what stream encodings are supported by the client and
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1444
        we will default to identity.
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1445
        """
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1446
        streamid = self._nextoutgoingstreamid
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1447
        self._nextoutgoingstreamid += 2
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1448
40130
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
  1449
        s = outputstream(streamid)
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1450
        self._outgoingstreams[streamid] = s
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1451
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1452
        # Always use the *server's* preferred encoder over the client's,
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1453
        # as servers have more to lose from sub-optimal encoders being used.
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1454
        for name in STREAM_ENCODERS_ORDER:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1455
            if name in self._sendersettings[b'contentencodings']:
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1456
                s.setencoder(self._ui, name)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1457
                break
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1458
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1459
        return s
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1460
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1461
    def _makeerrorresult(self, msg: bytes) -> tuple[bytes, dict[bytes, bytes]]:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1462
        return b'error', {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1463
            b'message': msg,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1464
        }
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1465
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1466
    def _makeruncommandresult(self, requestid: int):
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1467
        entry = self._receivingcommands[requestid]
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1468
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1469
        if not entry[b'requestdone']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1470
            self._state = b'errored'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1471
            raise error.ProgrammingError(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
  1472
                b'should not be called without requestdone set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1473
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1474
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1475
        del self._receivingcommands[requestid]
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1476
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1477
        if self._receivingcommands:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1478
            self._state = b'command-receiving'
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1479
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1480
            self._state = b'idle'
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1481
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1482
        # Decode the payloads as CBOR.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1483
        entry[b'payload'].seek(0)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1484
        request = cborutil.decodeall(entry[b'payload'].getvalue())[0]
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1485
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1486
        if b'name' not in request:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1487
            self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1488
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1489
                _(b'command request missing "name" field')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1490
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1491
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1492
        if b'args' not in request:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1493
            request[b'args'] = {}
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1494
37063
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1495
        assert requestid not in self._activecommands
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1496
        self._activecommands.add(requestid)
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1497
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1498
        return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1499
            b'runcommand',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1500
            {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1501
                b'requestid': requestid,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1502
                b'command': request[b'name'],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1503
                b'args': request[b'args'],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1504
                b'redirect': request.get(b'redirect'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1505
                b'data': entry[b'data'].getvalue() if entry[b'data'] else None,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1506
            },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1507
        )
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1508
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1509
    def _makewantframeresult(self) -> tuple[bytes, dict[bytes, bytes]]:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1510
        return b'wantframe', {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1511
            b'state': self._state,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1512
        }
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1513
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1514
    def _validatecommandrequestframe(self, frame: frame):
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1515
        new = frame.flags & FLAG_COMMAND_REQUEST_NEW
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1516
        continuation = frame.flags & FLAG_COMMAND_REQUEST_CONTINUATION
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1517
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1518
        if new and continuation:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1519
            self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1520
            return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1521
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1522
                    b'received command request frame with both new and '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1523
                    b'continuation flags set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1524
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1525
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1526
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1527
        if not new and not continuation:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1528
            self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1529
            return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1530
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1531
                    b'received command request frame with neither new nor '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1532
                    b'continuation flags set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1533
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1534
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1535
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1536
    def _onframeinitial(self, frame: frame):
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1537
        # Called when we receive a frame when in the "initial" state.
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1538
        if frame.typeid == FRAME_TYPE_SENDER_PROTOCOL_SETTINGS:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1539
            self._state = b'protocol-settings-receiving'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1540
            self._protocolsettingsdecoder = cborutil.bufferingdecoder()
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1541
            return self._onframeprotocolsettings(frame)
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1542
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1543
        elif frame.typeid == FRAME_TYPE_COMMAND_REQUEST:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1544
            self._state = b'idle'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1545
            return self._onframeidle(frame)
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1546
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1547
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1548
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1549
            return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1550
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1551
                    b'expected sender protocol settings or command request '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1552
                    b'frame; got %d'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1553
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1554
                % frame.typeid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1555
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1556
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1557
    def _onframeprotocolsettings(self, frame: frame):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1558
        assert self._state == b'protocol-settings-receiving'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1559
        assert self._protocolsettingsdecoder is not None
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1560
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1561
        if frame.typeid != FRAME_TYPE_SENDER_PROTOCOL_SETTINGS:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1562
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1563
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1564
                _(b'expected sender protocol settings frame; got %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1565
                % frame.typeid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1566
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1567
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1568
        more = frame.flags & FLAG_SENDER_PROTOCOL_SETTINGS_CONTINUATION
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1569
        eos = frame.flags & FLAG_SENDER_PROTOCOL_SETTINGS_EOS
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1570
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1571
        if more and eos:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1572
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1573
            return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1574
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1575
                    b'sender protocol settings frame cannot have both '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1576
                    b'continuation and end of stream flags set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1577
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1578
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1579
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1580
        if not more and not eos:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1581
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1582
            return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1583
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1584
                    b'sender protocol settings frame must have continuation or '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1585
                    b'end of stream flag set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1586
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1587
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1588
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1589
        # TODO establish limits for maximum amount of data that can be
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1590
        # buffered.
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1591
        try:
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1592
            self._protocolsettingsdecoder.decode(frame.payload)
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1593
        except Exception as e:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1594
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1595
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1596
                _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1597
                    b'error decoding CBOR from sender protocol settings frame: %s'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1598
                )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1599
                % stringutil.forcebytestr(e)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1600
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1601
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1602
        if more:
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1603
            return self._makewantframeresult()
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1604
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1605
        assert eos
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1606
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1607
        decoded = self._protocolsettingsdecoder.getavailable()
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1608
        self._protocolsettingsdecoder = None
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1609
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1610
        if not decoded:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1611
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1612
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1613
                _(b'sender protocol settings frame did not contain CBOR data')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1614
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1615
        elif len(decoded) > 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1616
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1617
            return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1618
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1619
                    b'sender protocol settings frame contained multiple CBOR '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1620
                    b'values'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1621
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1622
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1623
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1624
        d = decoded[0]
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1625
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1626
        if b'contentencodings' in d:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1627
            self._sendersettings[b'contentencodings'] = d[b'contentencodings']
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1628
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1629
        self._state = b'idle'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1630
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1631
        return self._makewantframeresult()
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1632
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1633
    def _onframeidle(self, frame: frame):
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1634
        # The only frame type that should be received in this state is a
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1635
        # command request.
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1636
        if frame.typeid != FRAME_TYPE_COMMAND_REQUEST:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1637
            self._state = b'errored'
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1638
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1639
                _(b'expected command request frame; got %d') % frame.typeid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1640
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1641
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1642
        res = self._validatecommandrequestframe(frame)
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1643
        if res:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1644
            return res
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1645
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1646
        if frame.requestid in self._receivingcommands:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1647
            self._state = b'errored'
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1648
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1649
                _(b'request with ID %d already received') % frame.requestid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1650
            )
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1651
37063
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1652
        if frame.requestid in self._activecommands:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1653
            self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1654
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1655
                _(b'request with ID %d is already active') % frame.requestid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1656
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1657
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1658
        new = frame.flags & FLAG_COMMAND_REQUEST_NEW
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1659
        moreframes = frame.flags & FLAG_COMMAND_REQUEST_MORE_FRAMES
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1660
        expectingdata = frame.flags & FLAG_COMMAND_REQUEST_EXPECT_DATA
37063
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1661
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1662
        if not new:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1663
            self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1664
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1665
                _(b'received command request frame without new flag set')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1666
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1667
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1668
        payload = util.bytesio()
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1669
        payload.write(frame.payload)
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1670
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1671
        self._receivingcommands[frame.requestid] = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1672
            b'payload': payload,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1673
            b'data': None,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1674
            b'requestdone': not moreframes,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1675
            b'expectingdata': bool(expectingdata),
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1676
        }
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1677
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1678
        # This is the final frame for this request. Dispatch it.
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1679
        if not moreframes and not expectingdata:
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1680
            return self._makeruncommandresult(frame.requestid)
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1681
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1682
        assert moreframes or expectingdata
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1683
        self._state = b'command-receiving'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1684
        return self._makewantframeresult()
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1685
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1686
    def _onframecommandreceiving(self, frame: frame):
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1687
        if frame.typeid == FRAME_TYPE_COMMAND_REQUEST:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1688
            # Process new command requests as such.
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1689
            if frame.flags & FLAG_COMMAND_REQUEST_NEW:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1690
                return self._onframeidle(frame)
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1691
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1692
            res = self._validatecommandrequestframe(frame)
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1693
            if res:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1694
                return res
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1695
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1696
        # All other frames should be related to a command that is currently
37063
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1697
        # receiving but is not active.
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1698
        if frame.requestid in self._activecommands:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1699
            self._state = b'errored'
37063
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1700
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1701
                _(b'received frame for request that is still active: %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1702
                % frame.requestid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1703
            )
37063
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1704
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1705
        if frame.requestid not in self._receivingcommands:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1706
            self._state = b'errored'
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1707
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1708
                _(b'received frame for request that is not receiving: %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1709
                % frame.requestid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1710
            )
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1711
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1712
        entry = self._receivingcommands[frame.requestid]
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1713
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1714
        if frame.typeid == FRAME_TYPE_COMMAND_REQUEST:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1715
            moreframes = frame.flags & FLAG_COMMAND_REQUEST_MORE_FRAMES
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1716
            expectingdata = bool(frame.flags & FLAG_COMMAND_REQUEST_EXPECT_DATA)
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1717
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1718
            if entry[b'requestdone']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1719
                self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1720
                return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1721
                    _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1722
                        b'received command request frame when request frames '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1723
                        b'were supposedly done'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1724
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1725
                )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1726
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1727
            if expectingdata != entry[b'expectingdata']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1728
                self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1729
                return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1730
                    _(b'mismatch between expect data flag and previous frame')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1731
                )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1732
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1733
            entry[b'payload'].write(frame.payload)
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1734
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1735
            if not moreframes:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1736
                entry[b'requestdone'] = True
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1737
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1738
            if not moreframes and not expectingdata:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1739
                return self._makeruncommandresult(frame.requestid)
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1740
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1741
            return self._makewantframeresult()
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1742
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1743
        elif frame.typeid == FRAME_TYPE_COMMAND_DATA:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1744
            if not entry[b'expectingdata']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1745
                self._state = b'errored'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1746
                return self._makeerrorresult(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1747
                    _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1748
                        b'received command data frame for request that is not '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1749
                        b'expecting data: %d'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1750
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1751
                    % frame.requestid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1752
                )
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1753
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1754
            if entry[b'data'] is None:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1755
                entry[b'data'] = util.bytesio()
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1756
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1757
            return self._handlecommanddataframe(frame, entry)
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1758
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1759
            self._state = b'errored'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1760
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1761
                _(b'received unexpected frame type: %d') % frame.typeid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1762
            )
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1763
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1764
    def _handlecommanddataframe(self, frame: frame, entry):
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1765
        assert frame.typeid == FRAME_TYPE_COMMAND_DATA
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1766
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1767
        # TODO support streaming data instead of buffering it.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1768
        entry[b'data'].write(frame.payload)
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1769
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1770
        if frame.flags & FLAG_COMMAND_DATA_CONTINUATION:
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1771
            return self._makewantframeresult()
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1772
        elif frame.flags & FLAG_COMMAND_DATA_EOS:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1773
            entry[b'data'].seek(0)
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1774
            return self._makeruncommandresult(frame.requestid)
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1775
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1776
            self._state = b'errored'
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
  1777
            return self._makeerrorresult(_(b'command data frame without flags'))
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1778
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1779
    def _onframeerrored(self, frame: frame):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1780
        return self._makeerrorresult(_(b'server already errored'))
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1781
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1782
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
  1783
class commandrequest:
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1784
    """Represents a request to run a command."""
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1785
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1786
    state: bytes
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1787
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1788
    def __init__(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1789
        self, requestid: int, name, args, datafh=None, redirect=None
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1790
    ) -> None:
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1791
        self.requestid = requestid
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1792
        self.name = name
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1793
        self.args = args
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1794
        self.datafh = datafh
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40020
diff changeset
  1795
        self.redirect = redirect
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1796
        self.state = b'pending'
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1797
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1798
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
  1799
class clientreactor:
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1800
    """Holds state of a client issuing frame-based protocol requests.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1801
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1802
    This is like ``serverreactor`` but for client-side state.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1803
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1804
    Each instance is bound to the lifetime of a connection. For persistent
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1805
    connection transports using e.g. TCP sockets and speaking the raw
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1806
    framing protocol, there will be a single instance for the lifetime of
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1807
    the TCP socket. For transports where there are multiple discrete
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1808
    interactions (say tunneled within in HTTP request), there will be a
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1809
    separate instance for each distinct interaction.
40127
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1810
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1811
    Consumers are expected to tell instances when events occur by calling
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1812
    various methods. These methods return a 2-tuple describing any follow-up
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1813
    action(s) to take. The first element is the name of an action to
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1814
    perform. The second is a data structure (usually a dict) specific to
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1815
    that action that contains more information. e.g. if the reactor wants
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1816
    to send frames to the server, the data structure will contain a reference
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1817
    to those frames.
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1818
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1819
    Valid actions that consumers can be instructed to take are:
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1820
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1821
    noop
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1822
       Indicates no additional action is required.
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1823
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1824
    sendframes
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1825
       Indicates that frames should be sent to the server. The ``framegen``
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1826
       key contains a generator of frames that should be sent. The reactor
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1827
       assumes that all frames in this generator are sent to the server.
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1828
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1829
    error
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1830
       Indicates that an error occurred. The ``message`` key contains an
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1831
       error message describing the failure.
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1832
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1833
    responsedata
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1834
       Indicates a response to a previously-issued command was received.
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1835
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1836
       The ``request`` key contains the ``commandrequest`` instance that
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1837
       represents the request this data is for.
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1838
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1839
       The ``data`` key contains the decoded data from the server.
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1840
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1841
       ``expectmore`` and ``eos`` evaluate to True when more response data
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1842
       is expected to follow or we're at the end of the response stream,
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1843
       respectively.
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1844
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1845
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1846
    _hasmultiplesend: bool
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1847
    _buffersends: bool
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1848
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1849
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1850
        self,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1851
        ui,
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1852
        hasmultiplesend: bool = False,
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1853
        buffersends: bool = True,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1854
        clientcontentencoders=None,
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1855
    ) -> None:
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1856
        """Create a new instance.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1857
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1858
        ``hasmultiplesend`` indicates whether multiple sends are supported
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1859
        by the transport. When True, it is possible to send commands immediately
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1860
        instead of buffering until the caller signals an intent to finish a
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1861
        send operation.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1862
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1863
        ``buffercommands`` indicates whether sends should be buffered until the
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1864
        last request has been issued.
40133
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1865
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1866
        ``clientcontentencoders`` is an iterable of content encoders the client
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1867
        will advertise to the server and that the server can use for encoding
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1868
        data. If not defined, the client will not advertise content encoders
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1869
        to the server.
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1870
        """
40129
293835e0fff7 wireprotov2: pass ui into clientreactor and serverreactor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40128
diff changeset
  1871
        self._ui = ui
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1872
        self._hasmultiplesend = hasmultiplesend
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1873
        self._buffersends = buffersends
40133
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1874
        self._clientcontentencoders = clientcontentencoders
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1875
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1876
        self._canissuecommands = True
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1877
        self._cansend = True
40133
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1878
        self._protocolsettingssent = False
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1879
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1880
        self._nextrequestid = 1
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1881
        # We only support a single outgoing stream for now.
40130
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
  1882
        self._outgoingstream = outputstream(1)
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1883
        self._pendingrequests = collections.deque()
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1884
        self._activerequests = {}
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1885
        self._incomingstreams = {}
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  1886
        self._streamsettingsdecoders = {}
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1887
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1888
        populatestreamencoders()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1889
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40020
diff changeset
  1890
    def callcommand(self, name, args, datafh=None, redirect=None):
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1891
        """Request that a command be executed.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1892
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1893
        Receives the command name, a dict of arguments to pass to the command,
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1894
        and an optional file object containing the raw data for the command.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1895
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1896
        Returns a 3-tuple of (request, action, action data).
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1897
        """
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1898
        if not self._canissuecommands:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1899
            raise error.ProgrammingError(b'cannot issue new commands')
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1900
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1901
        requestid = self._nextrequestid
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1902
        self._nextrequestid += 2
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1903
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1904
        request = commandrequest(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1905
            requestid, name, args, datafh=datafh, redirect=redirect
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1906
        )
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1907
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1908
        if self._buffersends:
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1909
            self._pendingrequests.append(request)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1910
            return request, b'noop', {}
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1911
        else:
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1912
            if not self._cansend:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1913
                raise error.ProgrammingError(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
  1914
                    b'sends cannot be performed on this instance'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1915
                )
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1916
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1917
            if not self._hasmultiplesend:
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1918
                self._cansend = False
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1919
                self._canissuecommands = False
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1920
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1921
            return (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1922
                request,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1923
                b'sendframes',
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1924
                {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1925
                    b'framegen': self._makecommandframes(request),
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1926
                },
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1927
            )
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1928
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1929
    def flushcommands(self) -> tuple[bytes, dict[bytes, Iterator[bytearray]]]:
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1930
        """Request that all queued commands be sent.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1931
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1932
        If any commands are buffered, this will instruct the caller to send
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1933
        them over the wire. If no commands are buffered it instructs the client
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1934
        to no-op.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1935
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1936
        If instances aren't configured for multiple sends, no new command
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1937
        requests are allowed after this is called.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1938
        """
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1939
        if not self._pendingrequests:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1940
            return b'noop', {}
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1941
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1942
        if not self._cansend:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1943
            raise error.ProgrammingError(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
  1944
                b'sends cannot be performed on this instance'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1945
            )
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1946
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1947
        # If the instance only allows sending once, mark that we have fired
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1948
        # our one shot.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1949
        if not self._hasmultiplesend:
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1950
            self._canissuecommands = False
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1951
            self._cansend = False
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1952
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1953
        def makeframes():
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1954
            while self._pendingrequests:
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1955
                request = self._pendingrequests.popleft()
52644
e627cc25b6f3 pyupgrade: rewrite `yield` statements in a loop to `yield from`
Matt Harbison <matt_harbison@yahoo.com>
parents: 52643
diff changeset
  1956
                yield from self._makecommandframes(request)
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1957
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1958
        return b'sendframes', {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1959
            b'framegen': makeframes(),
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1960
        }
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1961
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1962
    def _makecommandframes(
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1963
        self, request: commandrequest
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  1964
    ) -> Iterator[bytearray]:
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1965
        """Emit frames to issue a command request.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1966
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1967
        As a side-effect, update request accounting to reflect its changed
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1968
        state.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1969
        """
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1970
        self._activerequests[request.requestid] = request
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1971
        request.state = b'sending'
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1972
40133
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1973
        if not self._protocolsettingssent and self._clientcontentencoders:
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1974
            self._protocolsettingssent = True
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1975
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1976
            payload = b''.join(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1977
                cborutil.streamencode(
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1978
                    {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1979
                        b'contentencodings': self._clientcontentencoders,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1980
                    }
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1981
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1982
            )
40133
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1983
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1984
            yield self._outgoingstream.makeframe(
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1985
                requestid=request.requestid,
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1986
                typeid=FRAME_TYPE_SENDER_PROTOCOL_SETTINGS,
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1987
                flags=FLAG_SENDER_PROTOCOL_SETTINGS_EOS,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1988
                payload=payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1989
            )
40133
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1990
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1991
        res = createcommandframes(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1992
            self._outgoingstream,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1993
            request.requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1994
            request.name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1995
            request.args,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1996
            datafh=request.datafh,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1997
            redirect=request.redirect,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1998
        )
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1999
52644
e627cc25b6f3 pyupgrade: rewrite `yield` statements in a loop to `yield from`
Matt Harbison <matt_harbison@yahoo.com>
parents: 52643
diff changeset
  2000
        yield from res
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  2001
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2002
        request.state = b'sent'
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2003
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  2004
    def onframerecv(self, frame: frame):
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2005
        """Process a frame that has been received off the wire.
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2006
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2007
        Returns a 2-tuple of (action, meta) describing further action the
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2008
        caller needs to take as a result of receiving this frame.
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2009
        """
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2010
        if frame.streamid % 2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2011
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2012
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2013
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2014
                    b'message': (
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2015
                        _(b'received frame with odd numbered stream ID: %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2016
                        % frame.streamid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2017
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2018
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2019
            )
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2020
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2021
        if frame.streamid not in self._incomingstreams:
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2022
            if not frame.streamflags & STREAM_FLAG_BEGIN_STREAM:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2023
                return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2024
                    b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2025
                    {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2026
                        b'message': _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2027
                            b'received frame on unknown stream '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2028
                            b'without beginning of stream flag set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2029
                        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2030
                    },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2031
                )
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2032
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2033
            self._incomingstreams[frame.streamid] = inputstream(frame.streamid)
37656
e6870bca1f47 wireprotoframing: record when new stream is encountered
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37655
diff changeset
  2034
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  2035
        stream = self._incomingstreams[frame.streamid]
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  2036
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  2037
        # If the payload is encoded, ask the stream to decode it. We
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  2038
        # merely substitute the decoded result into the frame payload as
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  2039
        # if it had been transferred all along.
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2040
        if frame.streamflags & STREAM_FLAG_ENCODING_APPLIED:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  2041
            frame.payload = stream.decode(frame.payload)
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2042
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2043
        if frame.streamflags & STREAM_FLAG_END_STREAM:
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2044
            del self._incomingstreams[frame.streamid]
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2045
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2046
        if frame.typeid == FRAME_TYPE_STREAM_SETTINGS:
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2047
            return self._onstreamsettingsframe(frame)
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2048
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2049
        if frame.requestid not in self._activerequests:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2050
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2051
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2052
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2053
                    b'message': (
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2054
                        _(b'received frame for inactive request ID: %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2055
                        % frame.requestid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2056
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2057
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2058
            )
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2059
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2060
        request = self._activerequests[frame.requestid]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2061
        request.state = b'receiving'
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2062
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2063
        handlers = {
37724
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
  2064
            FRAME_TYPE_COMMAND_RESPONSE: self._oncommandresponseframe,
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  2065
            FRAME_TYPE_ERROR_RESPONSE: self._onerrorresponseframe,
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2066
        }
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2067
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2068
        meth = handlers.get(frame.typeid)
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2069
        if not meth:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2070
            raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2071
                b'unhandled frame type: %d' % frame.typeid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2072
            )
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2073
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2074
        return meth(request, frame)
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2075
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  2076
    def _onstreamsettingsframe(self, frame: frame):
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2077
        assert frame.typeid == FRAME_TYPE_STREAM_SETTINGS
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2078
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2079
        more = frame.flags & FLAG_STREAM_ENCODING_SETTINGS_CONTINUATION
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2080
        eos = frame.flags & FLAG_STREAM_ENCODING_SETTINGS_EOS
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2081
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2082
        if more and eos:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2083
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2084
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2085
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2086
                    b'message': (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2087
                        _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2088
                            b'stream encoding settings frame cannot have both '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2089
                            b'continuation and end of stream flags set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2090
                        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2091
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2092
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2093
            )
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2094
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2095
        if not more and not eos:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2096
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2097
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2098
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2099
                    b'message': _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2100
                        b'stream encoding settings frame must have '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2101
                        b'continuation or end of stream flag set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2102
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2103
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2104
            )
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2105
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2106
        if frame.streamid not in self._streamsettingsdecoders:
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2107
            decoder = cborutil.bufferingdecoder()
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2108
            self._streamsettingsdecoders[frame.streamid] = decoder
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2109
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2110
        decoder = self._streamsettingsdecoders[frame.streamid]
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2111
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2112
        try:
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2113
            decoder.decode(frame.payload)
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2114
        except Exception as e:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2115
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2116
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2117
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2118
                    b'message': (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2119
                        _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2120
                            b'error decoding CBOR from stream encoding '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2121
                            b'settings frame: %s'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2122
                        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2123
                        % stringutil.forcebytestr(e)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2124
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2125
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2126
            )
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2127
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2128
        if more:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2129
            return b'noop', {}
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2130
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2131
        assert eos
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2132
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2133
        decoded = decoder.getavailable()
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2134
        del self._streamsettingsdecoders[frame.streamid]
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2135
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2136
        if not decoded:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2137
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2138
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2139
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2140
                    b'message': _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2141
                        b'stream encoding settings frame did not contain '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2142
                        b'CBOR data'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2143
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2144
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2145
            )
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2146
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2147
        try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2148
            self._incomingstreams[frame.streamid].setdecoder(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2149
                self._ui, decoded[0], decoded[1:]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2150
            )
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2151
        except Exception as e:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2152
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2153
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2154
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2155
                    b'message': (
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2156
                        _(b'error setting stream decoder: %s')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2157
                        % stringutil.forcebytestr(e)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2158
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2159
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2160
            )
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2161
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2162
        return b'noop', {}
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2163
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  2164
    def _oncommandresponseframe(self, request: commandrequest, frame: frame):
37724
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
  2165
        if frame.flags & FLAG_COMMAND_RESPONSE_EOS:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2166
            request.state = b'received'
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2167
            del self._activerequests[request.requestid]
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2168
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2169
        return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2170
            b'responsedata',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2171
            {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2172
                b'request': request,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2173
                b'expectmore': frame.flags & FLAG_COMMAND_RESPONSE_CONTINUATION,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2174
                b'eos': frame.flags & FLAG_COMMAND_RESPONSE_EOS,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2175
                b'data': frame.payload,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2176
            },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2177
        )
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  2178
52699
068398a8c9cb typing: add some type annotations to the `wireprotoframing` module
Matt Harbison <matt_harbison@yahoo.com>
parents: 52698
diff changeset
  2179
    def _onerrorresponseframe(self, request: commandrequest, frame: frame):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2180
        request.state = b'errored'
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  2181
        del self._activerequests[request.requestid]
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  2182
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  2183
        # The payload should be a CBOR map.
39446
36f487a332ad wireprotoframing: use our CBOR module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
  2184
        m = cborutil.decodeall(frame.payload)[0]
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  2185
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2186
        return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2187
            b'error',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2188
            {
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2189
                b'request': request,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2190
                b'type': m[b'type'],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2191
                b'message': m[b'message'],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2192
            },
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2193
        )