mercurial/wireprotoframing.py
author Raphaël Gomès <rgomes@octobus.net>
Thu, 02 Nov 2023 11:19:54 +0100
changeset 51205 002b49905aac
parent 50929 18c8c18993f0
child 51690 493034cc3265
permissions -rw-r--r--
rust-index: implementation of __getitem__ Although the removed panic tends to prove if the full test suite did pass that the case when the input is a node id does not happen, it is best not to remove it right now. Raising IndexError is crucial for iteration on the index to stop, given the default CPython sequence iterator, see for instance https://github.com/zpoint/CPython-Internals/blobs/master/BasicObject/iter/iter.md This was spotted by `test-rust-ancestors.py`, which does simple interations on indexes (as preflight checks). In `revlog.c`, `index_getitem` defaults to `index_get` when called on revision numbers, which does raise `IndexError` with the same message as the one we are introducing here.
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
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    12
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
    13
import collections
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    14
import struct
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    15
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
    16
from .i18n import _
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
    17
from .thirdparty import attr
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    18
from . import (
37474
d33997123ea5 py3: system-stringify repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents: 37473
diff changeset
    19
    encoding,
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
    20
    error,
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
    21
    pycompat,
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    22
    util,
40020
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
    23
    wireprototypes,
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    24
)
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37063
diff changeset
    25
from .utils import (
39446
36f487a332ad wireprotoframing: use our CBOR module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
    26
    cborutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37063
diff changeset
    27
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37063
diff changeset
    28
)
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    29
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    30
FRAME_HEADER_SIZE = 8
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    31
DEFAULT_MAX_FRAME_SIZE = 32768
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    32
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    33
STREAM_FLAG_BEGIN_STREAM = 0x01
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    34
STREAM_FLAG_END_STREAM = 0x02
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    35
STREAM_FLAG_ENCODING_APPLIED = 0x04
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    36
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    37
STREAM_FLAGS = {
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    38
    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
    39
    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
    40
    b'encoded': STREAM_FLAG_ENCODING_APPLIED,
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    41
}
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
    42
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    43
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
    44
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
    45
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
    46
FRAME_TYPE_ERROR_RESPONSE = 0x05
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
    47
FRAME_TYPE_TEXT_OUTPUT = 0x06
37291
b0041036214e wireproto: define frame to represent progress updates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37290
diff changeset
    48
FRAME_TYPE_PROGRESS = 0x07
40125
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    49
FRAME_TYPE_SENDER_PROTOCOL_SETTINGS = 0x08
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    50
FRAME_TYPE_STREAM_SETTINGS = 0x09
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    51
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    52
FRAME_TYPES = {
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    53
    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
    54
    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
    55
    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
    56
    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
    57
    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
    58
    b'progress': FRAME_TYPE_PROGRESS,
40125
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    59
    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
    60
    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
    61
}
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    62
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    63
FLAG_COMMAND_REQUEST_NEW = 0x01
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    64
FLAG_COMMAND_REQUEST_CONTINUATION = 0x02
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    65
FLAG_COMMAND_REQUEST_MORE_FRAMES = 0x04
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    66
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
    67
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    68
FLAGS_COMMAND_REQUEST = {
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    69
    b'new': FLAG_COMMAND_REQUEST_NEW,
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    70
    b'continuation': FLAG_COMMAND_REQUEST_CONTINUATION,
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    71
    b'more': FLAG_COMMAND_REQUEST_MORE_FRAMES,
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
    72
    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
    73
}
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    74
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    75
FLAG_COMMAND_DATA_CONTINUATION = 0x01
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    76
FLAG_COMMAND_DATA_EOS = 0x02
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    77
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    78
FLAGS_COMMAND_DATA = {
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    79
    b'continuation': FLAG_COMMAND_DATA_CONTINUATION,
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    80
    b'eos': FLAG_COMMAND_DATA_EOS,
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    81
}
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    82
37724
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
    83
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
    84
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
    85
37724
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
    86
FLAGS_COMMAND_RESPONSE = {
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
    87
    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
    88
    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
    89
}
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
    90
40125
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    91
FLAG_SENDER_PROTOCOL_SETTINGS_CONTINUATION = 0x01
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    92
FLAG_SENDER_PROTOCOL_SETTINGS_EOS = 0x02
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    93
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    94
FLAGS_SENDER_PROTOCOL_SETTINGS = {
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    95
    b'continuation': FLAG_SENDER_PROTOCOL_SETTINGS_CONTINUATION,
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    96
    b'eos': FLAG_SENDER_PROTOCOL_SETTINGS_EOS,
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    97
}
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    98
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
    99
FLAG_STREAM_ENCODING_SETTINGS_CONTINUATION = 0x01
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   100
FLAG_STREAM_ENCODING_SETTINGS_EOS = 0x02
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   101
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   102
FLAGS_STREAM_ENCODING_SETTINGS = {
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   103
    b'continuation': FLAG_STREAM_ENCODING_SETTINGS_CONTINUATION,
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   104
    b'eos': FLAG_STREAM_ENCODING_SETTINGS_EOS,
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   105
}
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   106
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   107
# Maps frame types to their available flags.
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   108
FRAME_TYPE_FLAGS = {
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   109
    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
   110
    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
   111
    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
   112
    FRAME_TYPE_ERROR_RESPONSE: {},
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   113
    FRAME_TYPE_TEXT_OUTPUT: {},
37291
b0041036214e wireproto: define frame to represent progress updates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37290
diff changeset
   114
    FRAME_TYPE_PROGRESS: {},
40125
e2fe1074024c wireprotov2: update stream encoding specification
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40025
diff changeset
   115
    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
   116
    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
   117
}
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   118
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   119
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
   120
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   121
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   122
def humanflags(mapping, value):
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   123
    """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
   124
    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
   125
    flags = []
37473
7c2c7c749411 wireproto: show unknown id and flags in repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents: 37472
diff changeset
   126
    val = 1
7c2c7c749411 wireproto: show unknown id and flags in repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents: 37472
diff changeset
   127
    while value >= val:
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   128
        if value & val:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   129
            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
   130
        val <<= 1
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   131
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   132
    return b'|'.join(flags)
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   133
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   134
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   135
@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
   136
class frameheader:
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   137
    """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
   138
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   139
    length = attr.ib()
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   140
    requestid = attr.ib()
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   141
    streamid = attr.ib()
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   142
    streamflags = attr.ib()
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   143
    typeid = attr.ib()
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   144
    flags = attr.ib()
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   145
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   146
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   147
@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
   148
class frame:
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   149
    """Represents a parsed frame."""
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   150
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   151
    requestid = attr.ib()
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   152
    streamid = attr.ib()
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   153
    streamflags = attr.ib()
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   154
    typeid = attr.ib()
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   155
    flags = attr.ib()
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   156
    payload = attr.ib()
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   157
37474
d33997123ea5 py3: system-stringify repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents: 37473
diff changeset
   158
    @encoding.strmethod
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   159
    def __repr__(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   160
        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
   161
        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
   162
            if value == self.typeid:
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   163
                typename = name
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   164
                break
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   165
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   166
        return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   167
            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
   168
            b'type=%s; flags=%s)'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   169
            % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   170
                len(self.payload),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   171
                self.requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   172
                self.streamid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   173
                humanflags(STREAM_FLAGS, self.streamflags),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   174
                typename,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   175
                humanflags(FRAME_TYPE_FLAGS.get(self.typeid, {}), self.flags),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   176
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   177
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   178
37298
5ef2da00e935 wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37292
diff changeset
   179
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   180
def makeframe(requestid, streamid, streamflags, typeid, flags, payload):
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   181
    """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
   182
    # TODO assert size of payload.
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   183
    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
   184
37057
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   185
    # 24 bits length
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   186
    # 16 bits request id
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   187
    # 8 bits stream id
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   188
    # 8 bits stream flags
37057
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   189
    # 4 bits type
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   190
    # 4 bits flags
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   191
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   192
    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
   193
    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
   194
    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
   195
    frame[7] = (typeid << 4) | flags
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   196
    frame[8:] = payload
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   197
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   198
    return frame
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   199
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   200
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   201
def makeframefromhumanstring(s):
37057
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   202
    """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
   203
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   204
    Strings have the form:
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   205
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   206
        <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
   207
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   208
    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
   209
    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
   210
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   211
    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
   212
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   213
    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
   214
    named constant.
37057
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   215
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   216
    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
   217
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   218
    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
   219
    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
   220
    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
   221
    byte string literal.
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   222
    """
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   223
    fields = s.split(b' ', 5)
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   224
    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
   225
2ec1fb9de638 wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37056
diff changeset
   226
    requestid = int(requestid)
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   227
    streamid = int(streamid)
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   228
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   229
    finalstreamflags = 0
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   230
    for flag in streamflags.split(b'|'):
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   231
        if flag in STREAM_FLAGS:
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   232
            finalstreamflags |= STREAM_FLAGS[flag]
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   233
        else:
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   234
            finalstreamflags |= int(flag)
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
    if frametype in FRAME_TYPES:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   237
        frametype = FRAME_TYPES[frametype]
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   238
    else:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   239
        frametype = int(frametype)
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   240
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   241
    finalflags = 0
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   242
    validflags = FRAME_TYPE_FLAGS[frametype]
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   243
    for flag in frameflags.split(b'|'):
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   244
        if flag in validflags:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   245
            finalflags |= validflags[flag]
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   246
        else:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   247
            finalflags |= int(flag)
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   248
37290
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   249
    if payload.startswith(b'cbor:'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   250
        payload = b''.join(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   251
            cborutil.streamencode(stringutil.evalpythonliteral(payload[5:]))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   252
        )
37290
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   253
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   254
    else:
cc5a040fe150 wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37289
diff changeset
   255
        payload = stringutil.unescapestr(payload)
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   256
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   257
    return makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   258
        requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   259
        streamid=streamid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   260
        streamflags=finalstreamflags,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   261
        typeid=frametype,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   262
        flags=finalflags,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   263
        payload=payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   264
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   265
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   266
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   267
def parseheader(data):
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   268
    """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
   269
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   270
    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
   271
    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
   272
    """
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   273
    # 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
   274
    # 16 bits request ID
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   275
    # 8 bits stream ID
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   276
    # 8 bits stream flags
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   277
    # 4 bits frame type
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   278
    # 4 bits frame flags
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   279
    # ... payload
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   280
    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
   281
    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
   282
    typeflags = data[7]
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   283
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   284
    frametype = (typeflags & 0xF0) >> 4
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   285
    frameflags = typeflags & 0x0F
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   286
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   287
    return frameheader(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   288
        framelength, requestid, streamid, streamflags, frametype, frameflags
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   289
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   290
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   291
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   292
def readframe(fh):
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   293
    """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
   294
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   295
    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
   296
    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
   297
    seen.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   298
    """
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   299
    header = bytearray(FRAME_HEADER_SIZE)
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
    readcount = fh.readinto(header)
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   302
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   303
    if readcount == 0:
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   304
        return None
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   305
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   306
    if readcount != FRAME_HEADER_SIZE:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   307
        raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   308
            _(b'received incomplete frame: got %d bytes: %s')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   309
            % (readcount, header)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   310
        )
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   311
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   312
    h = parseheader(header)
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   313
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   314
    payload = fh.read(h.length)
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
   315
    if len(payload) != h.length:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   316
        raise error.Abort(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   317
            _(b'frame length error: expected %d; got %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   318
            % (h.length, len(payload))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   319
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   320
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   321
    return frame(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   322
        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
   323
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   324
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   325
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   326
def createcommandframes(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   327
    stream,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   328
    requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   329
    cmd,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   330
    args,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   331
    datafh=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   332
    maxframesize=DEFAULT_MAX_FRAME_SIZE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   333
    redirect=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   334
):
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   335
    """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
   336
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   337
    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
   338
    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
   339
    """
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   340
    data = {b'name': cmd}
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   341
    if args:
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   342
        data[b'args'] = args
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   343
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40020
diff changeset
   344
    if redirect:
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40020
diff changeset
   345
        data[b'redirect'] = redirect
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40020
diff changeset
   346
39446
36f487a332ad wireprotoframing: use our CBOR module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
   347
    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
   348
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   349
    offset = 0
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   350
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   351
    while True:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   352
        flags = 0
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   353
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   354
        # Must set new or continuation flag.
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   355
        if not offset:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   356
            flags |= FLAG_COMMAND_REQUEST_NEW
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   357
        else:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   358
            flags |= FLAG_COMMAND_REQUEST_CONTINUATION
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   359
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   360
        # Data frames is set on all frames.
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   361
        if datafh:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   362
            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
   363
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   364
        payload = data[offset : offset + maxframesize]
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   365
        offset += len(payload)
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   366
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   367
        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
   368
            flags |= FLAG_COMMAND_REQUEST_MORE_FRAMES
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   369
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   370
        yield stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   371
            requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   372
            typeid=FRAME_TYPE_COMMAND_REQUEST,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   373
            flags=flags,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   374
            payload=payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   375
        )
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
        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
   378
            break
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
   379
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   380
    if datafh:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   381
        while True:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   382
            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
   383
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   384
            done = False
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   385
            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
   386
                flags = FLAG_COMMAND_DATA_CONTINUATION
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   387
            else:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   388
                flags = FLAG_COMMAND_DATA_EOS
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   389
                assert datafh.read(1) == b''
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   390
                done = True
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
            yield stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   393
                requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   394
                typeid=FRAME_TYPE_COMMAND_DATA,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   395
                flags=flags,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   396
                payload=data,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   397
            )
37051
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   398
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   399
            if done:
40206e227412 wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   400
                break
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   401
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   402
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
   403
def createcommandresponseokframe(stream, requestid):
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
   404
    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
   405
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   406
    if stream.streamsettingssent:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   407
        overall = stream.encode(overall)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   408
        encoded = True
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   409
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   410
        if not overall:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   411
            return None
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   412
    else:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   413
        encoded = False
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   414
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   415
    return stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   416
        requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   417
        typeid=FRAME_TYPE_COMMAND_RESPONSE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   418
        flags=FLAG_COMMAND_RESPONSE_CONTINUATION,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   419
        payload=overall,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   420
        encoded=encoded,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   421
    )
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
   422
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   423
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   424
def createcommandresponseeosframes(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   425
    stream, requestid, maxframesize=DEFAULT_MAX_FRAME_SIZE
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   426
):
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
   427
    """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
   428
    payload = stream.flush()
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   429
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   430
    offset = 0
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   431
    while True:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   432
        chunk = payload[offset : offset + maxframesize]
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   433
        offset += len(chunk)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   434
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   435
        done = offset == len(payload)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   436
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   437
        if done:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   438
            flags = FLAG_COMMAND_RESPONSE_EOS
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   439
        else:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   440
            flags = FLAG_COMMAND_RESPONSE_CONTINUATION
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   441
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   442
        yield stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   443
            requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   444
            typeid=FRAME_TYPE_COMMAND_RESPONSE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   445
            flags=flags,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   446
            payload=chunk,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   447
            encoded=payload != b'',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   448
        )
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   449
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   450
        if done:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   451
            break
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   452
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   453
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   454
def createalternatelocationresponseframe(stream, requestid, location):
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   455
    data = {
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   456
        b'status': b'redirect',
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   457
        b'location': {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   458
            b'url': location.url,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   459
            b'mediatype': location.mediatype,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   460
        },
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   461
    }
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   462
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   463
    for a in (
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   464
        'size',
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   465
        'fullhashes',
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   466
        'fullhashseed',
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   467
        'serverdercerts',
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   468
        'servercadercerts',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   469
    ):
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   470
        value = getattr(location, a)
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   471
        if value is not None:
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   472
            data[b'location'][pycompat.bytestr(a)] = value
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   473
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   474
    payload = b''.join(cborutil.streamencode(data))
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   475
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   476
    if stream.streamsettingssent:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   477
        payload = stream.encode(payload)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   478
        encoded = True
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   479
    else:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   480
        encoded = False
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   481
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   482
    return stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   483
        requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   484
        typeid=FRAME_TYPE_COMMAND_RESPONSE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   485
        flags=FLAG_COMMAND_RESPONSE_CONTINUATION,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   486
        payload=payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   487
        encoded=encoded,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   488
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   489
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
   490
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   491
def createcommanderrorresponse(stream, requestid, message, args=None):
39486
43d92d68ac88 wireprotov2peer: properly format errors
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39446
diff changeset
   492
    # 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
   493
    # formatting works consistently?
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   494
    m = {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   495
        b'status': b'error',
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   496
        b'error': {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   497
            b'message': message,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   498
        },
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   499
    }
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   500
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   501
    if args:
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   502
        m[b'error'][b'args'] = args
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   503
39446
36f487a332ad wireprotoframing: use our CBOR module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
   504
    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
   505
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   506
    yield stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   507
        requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   508
        typeid=FRAME_TYPE_COMMAND_RESPONSE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   509
        flags=FLAG_COMMAND_RESPONSE_EOS,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   510
        payload=overall,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   511
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   512
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
   513
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
   514
def createerrorframe(stream, requestid, msg, errtype):
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
   515
    # 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
   516
    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
   517
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   518
    payload = b''.join(
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   519
        cborutil.streamencode(
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   520
            {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   521
                b'type': errtype,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   522
                b'message': [{b'msg': msg}],
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   523
            }
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
   524
        )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   525
    )
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
   526
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   527
    yield stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   528
        requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   529
        typeid=FRAME_TYPE_ERROR_RESPONSE,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   530
        flags=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   531
        payload=payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   532
    )
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
   533
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   534
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   535
def createtextoutputframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   536
    stream, requestid, atoms, maxframesize=DEFAULT_MAX_FRAME_SIZE
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   537
):
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   538
    """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
   539
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   540
    ``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
   541
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   542
    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
   543
    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
   544
    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
   545
    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
   546
    """
37319
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   547
    atomdicts = []
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   548
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   549
    for (formatting, args, labels) in atoms:
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   550
        # 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
   551
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   552
        if not isinstance(formatting, bytes):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   553
            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
   554
        for arg in args:
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   555
            if not isinstance(arg, bytes):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   556
                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
   557
        for label in labels:
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   558
            if not isinstance(label, bytes):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   559
                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
   560
37319
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   561
        # 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
   562
        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
   563
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   564
        # 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
   565
        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
   566
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   567
        # Labels must be ASCII.
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
   568
        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
   569
37319
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   570
        atom = {b'msg': formatting}
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   571
        if args:
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   572
            atom[b'args'] = args
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   573
        if labels:
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   574
            atom[b'labels'] = labels
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   575
37319
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   576
        atomdicts.append(atom)
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   577
39446
36f487a332ad wireprotoframing: use our CBOR module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
   578
    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
   579
37319
36d17f37db91 wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37299
diff changeset
   580
    if len(payload) > maxframesize:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   581
        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
   582
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   583
    yield stream.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   584
        requestid=requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   585
        typeid=FRAME_TYPE_TEXT_OUTPUT,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   586
        flags=0,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   587
        payload=payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   588
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   589
37285
3ed344546d9e wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37084
diff changeset
   590
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   591
class bufferingcommandresponseemitter:
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   592
    """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
   593
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   594
    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
   595
    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
   596
    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
   597
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   598
    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
   599
    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
   600
    level.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   601
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   602
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   603
    def __init__(self, stream, requestid, maxframesize=DEFAULT_MAX_FRAME_SIZE):
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   604
        self._stream = stream
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   605
        self._requestid = requestid
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   606
        self._maxsize = maxframesize
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   607
        self._chunks = []
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   608
        self._chunkssize = 0
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   609
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   610
    def send(self, data):
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   611
        """Send new data for emission.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   612
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   613
        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
   614
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   615
        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
   616
        data to frames.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   617
        """
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   618
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   619
        if data is None:
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   620
            for frame in self._flush():
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   621
                yield frame
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   622
            return
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   623
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   624
        data = self._stream.encode(data)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   625
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   626
        # 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
   627
        # 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
   628
        # 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
   629
        # a simple implementation:
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   630
        #
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   631
        # * 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
   632
        #   for the new chunk.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   633
        # * 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
   634
        #   being exceeded, we do that.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   635
        # * 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
   636
        #   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
   637
40136
3a6d6c54bd81 wireprotov2: don't emit empty frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40135
diff changeset
   638
        if not data:
3a6d6c54bd81 wireprotov2: don't emit empty frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40135
diff changeset
   639
            return
3a6d6c54bd81 wireprotov2: don't emit empty frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40135
diff changeset
   640
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   641
        if len(data) > self._maxsize:
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   642
            for frame in self._flush():
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   643
                yield frame
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   644
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   645
            # 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
   646
            offset = 0
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   647
            while True:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   648
                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
   649
                offset += len(chunk)
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   650
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   651
                yield self._stream.makeframe(
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   652
                    self._requestid,
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   653
                    typeid=FRAME_TYPE_COMMAND_RESPONSE,
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   654
                    flags=FLAG_COMMAND_RESPONSE_CONTINUATION,
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   655
                    payload=chunk,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   656
                    encoded=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   657
                )
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   658
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   659
                if offset == len(data):
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   660
                    return
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   661
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   662
        # 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
   663
        # return.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   664
        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
   665
            self._chunks.append(data)
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   666
            self._chunkssize += len(data)
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   667
            return
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   668
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   669
        # 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
   670
        # 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
   671
        # keep things simple for now.
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   672
        for frame in self._flush():
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   673
            yield frame
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
        self._chunks.append(data)
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   676
        self._chunkssize = len(data)
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   677
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   678
    def _flush(self):
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   679
        payload = b''.join(self._chunks)
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   680
        assert len(payload) <= self._maxsize
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   681
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   682
        self._chunks[:] = []
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   683
        self._chunkssize = 0
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   684
40136
3a6d6c54bd81 wireprotov2: don't emit empty frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40135
diff changeset
   685
        if not payload:
3a6d6c54bd81 wireprotov2: don't emit empty frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40135
diff changeset
   686
            return
3a6d6c54bd81 wireprotov2: don't emit empty frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40135
diff changeset
   687
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   688
        yield self._stream.makeframe(
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   689
            self._requestid,
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   690
            typeid=FRAME_TYPE_COMMAND_RESPONSE,
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   691
            flags=FLAG_COMMAND_RESPONSE_CONTINUATION,
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   692
            payload=payload,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   693
            encoded=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   694
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   695
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
   696
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   697
# 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
   698
# mechanism.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   699
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   700
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   701
class identityencoder:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   702
    """Encoder for the "identity" stream encoding profile."""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   703
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   704
    def __init__(self, ui):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   705
        pass
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   706
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   707
    def encode(self, data):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   708
        return data
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   709
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   710
    def flush(self):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   711
        return b''
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   712
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   713
    def finish(self):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   714
        return b''
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   715
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   716
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   717
class identitydecoder:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   718
    """Decoder for the "identity" stream encoding profile."""
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   719
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   720
    def __init__(self, ui, extraobjs):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   721
        if extraobjs:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   722
            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
   723
                _(b'identity decoder received unexpected additional values')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   724
            )
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   725
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   726
    def decode(self, data):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   727
        return data
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   728
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   729
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   730
class zlibencoder:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   731
    def __init__(self, ui):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   732
        import zlib
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   733
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   734
        self._zlib = zlib
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   735
        self._compressor = zlib.compressobj()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   736
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   737
    def encode(self, data):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   738
        return self._compressor.compress(data)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   739
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   740
    def flush(self):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   741
        # 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
   742
        # what we want.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   743
        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
   744
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   745
    def finish(self):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   746
        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
   747
        self._compressor = None
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   748
        return res
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   749
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   750
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   751
class zlibdecoder:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   752
    def __init__(self, ui, extraobjs):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   753
        import zlib
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   754
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   755
        if extraobjs:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   756
            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
   757
                _(b'zlib decoder received unexpected additional values')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   758
            )
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   759
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   760
        self._decompressor = zlib.decompressobj()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   761
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   762
    def decode(self, data):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   763
        return self._decompressor.decompress(data)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   764
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   765
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   766
class zstdbaseencoder:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   767
    def __init__(self, level):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   768
        from . import zstd
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   769
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   770
        self._zstd = zstd
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   771
        cctx = zstd.ZstdCompressor(level=level)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   772
        self._compressor = cctx.compressobj()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   773
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   774
    def encode(self, data):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   775
        return self._compressor.compress(data)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   776
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   777
    def flush(self):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   778
        # 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
   779
        # 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
   780
        # up to this point.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   781
        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
   782
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   783
    def finish(self):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   784
        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
   785
        self._compressor = None
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   786
        return res
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   787
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   788
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   789
class zstd8mbencoder(zstdbaseencoder):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   790
    def __init__(self, ui):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   791
        super(zstd8mbencoder, self).__init__(3)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   792
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   793
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   794
class zstdbasedecoder:
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   795
    def __init__(self, maxwindowsize):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   796
        from . import zstd
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   797
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   798
        dctx = zstd.ZstdDecompressor(max_window_size=maxwindowsize)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   799
        self._decompressor = dctx.decompressobj()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   800
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   801
    def decode(self, data):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   802
        return self._decompressor.decompress(data)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   803
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   804
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   805
class zstd8mbdecoder(zstdbasedecoder):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   806
    def __init__(self, ui, extraobjs):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   807
        if extraobjs:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   808
            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
   809
                _(b'zstd8mb decoder received unexpected additional values')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   810
            )
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   811
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   812
        super(zstd8mbdecoder, self).__init__(maxwindowsize=8 * 1048576)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   813
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   814
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   815
# 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
   816
# this module.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   817
STREAM_ENCODERS = {}
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   818
STREAM_ENCODERS_ORDER = []
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   819
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   820
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   821
def populatestreamencoders():
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   822
    if STREAM_ENCODERS:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   823
        return
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   824
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   825
    try:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   826
        from . import zstd
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   827
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   828
        zstd.__version__
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   829
    except ImportError:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   830
        zstd = None
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   831
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   832
    # zstandard is fastest and is preferred.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   833
    if zstd:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   834
        STREAM_ENCODERS[b'zstd-8mb'] = (zstd8mbencoder, zstd8mbdecoder)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   835
        STREAM_ENCODERS_ORDER.append(b'zstd-8mb')
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   836
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   837
    STREAM_ENCODERS[b'zlib'] = (zlibencoder, zlibdecoder)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   838
    STREAM_ENCODERS_ORDER.append(b'zlib')
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   839
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   840
    STREAM_ENCODERS[b'identity'] = (identityencoder, identitydecoder)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   841
    STREAM_ENCODERS_ORDER.append(b'identity')
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   842
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   843
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   844
class stream:
37285
3ed344546d9e wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37084
diff changeset
   845
    """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
   846
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   847
    def __init__(self, streamid, active=False):
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   848
        self.streamid = streamid
37655
b9502b5f2066 wireprotoframing: use value passed into function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37544
diff changeset
   849
        self._active = active
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   850
37285
3ed344546d9e wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37084
diff changeset
   851
    def makeframe(self, requestid, typeid, flags, payload):
3ed344546d9e wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37084
diff changeset
   852
        """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
   853
3ed344546d9e wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37084
diff changeset
   854
        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
   855
        """
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   856
        streamflags = 0
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   857
        if not self._active:
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   858
            streamflags |= STREAM_FLAG_BEGIN_STREAM
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   859
            self._active = True
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   860
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   861
        return makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   862
            requestid, self.streamid, streamflags, typeid, flags, payload
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   863
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   864
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   865
40130
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
   866
class inputstream(stream):
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
   867
    """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
   868
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   869
    def __init__(self, streamid, active=False):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   870
        super(inputstream, self).__init__(streamid, active=active)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   871
        self._decoder = None
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   872
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   873
    def setdecoder(self, ui, name, extraobjs):
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
   874
        """Set the decoder for this stream.
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
   875
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
   876
        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
   877
        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
   878
        """
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   879
        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
   880
            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
   881
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   882
        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
   883
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   884
    def decode(self, data):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   885
        # 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
   886
        # because it is trivial.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   887
        if not self._decoder:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   888
            return data
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   889
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   890
        return self._decoder.decode(data)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   891
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   892
    def flush(self):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   893
        if not self._decoder:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   894
            return b''
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   895
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   896
        return self._decoder.flush()
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
   897
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   898
40130
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
   899
class outputstream(stream):
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
   900
    """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
   901
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   902
    def __init__(self, streamid, active=False):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   903
        super(outputstream, self).__init__(streamid, active=active)
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   904
        self.streamsettingssent = False
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   905
        self._encoder = None
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   906
        self._encodername = None
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   907
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   908
    def setencoder(self, ui, name):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   909
        """Set the encoder for this stream.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   910
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   911
        Receives the stream profile name.
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   912
        """
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   913
        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
   914
            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
   915
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   916
        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
   917
        self._encodername = name
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   918
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   919
    def encode(self, data):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   920
        if not self._encoder:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   921
            return data
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   922
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   923
        return self._encoder.encode(data)
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   924
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   925
    def flush(self):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   926
        if not self._encoder:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   927
            return b''
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   928
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   929
        return self._encoder.flush()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   930
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   931
    def finish(self):
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   932
        if not self._encoder:
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   933
            return b''
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   934
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   935
        self._encoder.finish()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
   936
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   937
    def makeframe(self, requestid, typeid, flags, payload, encoded=False):
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   938
        """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
   939
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   940
        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
   941
        """
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   942
        streamflags = 0
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   943
        if not self._active:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   944
            streamflags |= STREAM_FLAG_BEGIN_STREAM
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   945
            self._active = True
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   946
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   947
        if encoded:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   948
            if not self.streamsettingssent:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   949
                raise error.ProgrammingError(
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   950
                    b'attempting to send encoded frame without sending stream '
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   951
                    b'settings'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   952
                )
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   953
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   954
            streamflags |= STREAM_FLAG_ENCODING_APPLIED
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   955
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   956
        if (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   957
            typeid == FRAME_TYPE_STREAM_SETTINGS
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   958
            and flags & FLAG_STREAM_ENCODING_SETTINGS_EOS
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   959
        ):
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   960
            self.streamsettingssent = True
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   961
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   962
        return makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   963
            requestid, self.streamid, streamflags, typeid, flags, payload
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   964
        )
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   965
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   966
    def makestreamsettingsframe(self, requestid):
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   967
        """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
   968
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   969
        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
   970
        already been sent.
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   971
        """
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   972
        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
   973
            return None
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   974
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   975
        payload = b''.join(cborutil.streamencode(self._encodername))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   976
        return self.makeframe(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   977
            requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   978
            FRAME_TYPE_STREAM_SETTINGS,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   979
            FLAG_STREAM_ENCODING_SETTINGS_EOS,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   980
            payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   981
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   982
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
   983
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   984
def ensureserverstream(stream):
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
   985
    if stream.streamid % 2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   986
        raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   987
            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
   988
            b'numbered streams; %d is not even' % stream.streamid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   989
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   990
37060
0a6c5cc09a88 wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37058
diff changeset
   991
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
   992
DEFAULT_PROTOCOL_SETTINGS = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   993
    b'contentencodings': [b'identity'],
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
   994
}
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
   995
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
   996
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   997
class serverreactor:
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
   998
    """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
   999
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1000
    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
  1001
    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
  1002
    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
  1003
    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
  1004
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1005
    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
  1006
    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
  1007
    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
  1008
    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
  1009
    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
  1010
    *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
  1011
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1012
    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
  1013
    this class.
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1014
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1015
    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
  1016
    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
  1017
    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
  1018
    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
  1019
    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
  1020
    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
  1021
    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
  1022
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1023
    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
  1024
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
  1025
    sendframes
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
  1026
       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
  1027
       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
  1028
       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
  1029
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1030
    error
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1031
       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
  1032
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1033
    runcommand
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1034
       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
  1035
       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
  1036
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1037
    wantframe
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1038
       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
  1039
       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
  1040
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1041
    noop
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1042
       Indicates no additional action is required.
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1043
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1044
    Known Issues
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1045
    ------------
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1046
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1047
    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
  1048
    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
  1049
    server's memory.
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1050
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1051
    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
  1052
    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
  1053
    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
  1054
    to facilitate graceful shutdown?
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1055
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1056
    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
  1057
    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
  1058
    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
  1059
    between who responds to what.
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1060
    """
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1061
40129
293835e0fff7 wireprotov2: pass ui into clientreactor and serverreactor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40128
diff changeset
  1062
    def __init__(self, ui, deferoutput=False):
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1063
        """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
  1064
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1065
        ``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
  1066
        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
  1067
        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
  1068
        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
  1069
        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
  1070
        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
  1071
        """
40129
293835e0fff7 wireprotov2: pass ui into clientreactor and serverreactor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40128
diff changeset
  1072
        self._ui = ui
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1073
        self._deferoutput = deferoutput
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1074
        self._state = b'initial'
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1075
        self._nextoutgoingstreamid = 2
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1076
        self._bufferedframegens = []
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1077
        # 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
  1078
        self._incomingstreams = {}
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1079
        self._outgoingstreams = {}
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1080
        # 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
  1081
        self._receivingcommands = {}
37063
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1082
        # 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
  1083
        # 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
  1084
        # set.
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1085
        self._activecommands = set()
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1086
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1087
        self._protocolsettingsdecoder = None
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1088
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1089
        # 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
  1090
        self._sendersettings = dict(DEFAULT_PROTOCOL_SETTINGS)
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1091
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1092
        populatestreamencoders()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1093
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1094
    def onframerecv(self, frame):
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1095
        """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
  1096
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1097
        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
  1098
        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
  1099
        """
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1100
        if not frame.streamid % 2:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1101
            self._state = b'errored'
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1102
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1103
                _(b'received frame with even numbered stream ID: %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1104
                % frame.streamid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1105
            )
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1106
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1107
        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
  1108
            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
  1109
                self._state = b'errored'
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1110
                return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1111
                    _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1112
                        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
  1113
                        b'beginning of stream flag set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1114
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1115
                )
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1116
40130
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
  1117
            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
  1118
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1119
        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
  1120
            # TODO handle decoding frames
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1121
            self._state = b'errored'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1122
            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
  1123
                b'support for decoding stream payloads not yet implemented'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1124
            )
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1125
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1126
        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
  1127
            del self._incomingstreams[frame.streamid]
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1128
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1129
        handlers = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1130
            b'initial': self._onframeinitial,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1131
            b'protocol-settings-receiving': self._onframeprotocolsettings,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1132
            b'idle': self._onframeidle,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1133
            b'command-receiving': self._onframecommandreceiving,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1134
            b'errored': self._onframeerrored,
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1135
        }
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1136
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1137
        meth = handlers.get(self._state)
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1138
        if not meth:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1139
            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
  1140
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1141
        return meth(frame)
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1142
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1143
    def oncommandresponsereadyobjects(self, stream, requestid, objs):
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1144
        """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
  1145
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1146
        ``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
  1147
        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
  1148
        client.
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1149
        """
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1150
        ensureserverstream(stream)
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1151
40135
966b5f7fd30b wireprotov2: remove functions for creating response frames from bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40133
diff changeset
  1152
        # 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
  1153
        if isinstance(objs, list):
966b5f7fd30b wireprotov2: remove functions for creating response frames from bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40133
diff changeset
  1154
            objs = iter(objs)
966b5f7fd30b wireprotov2: remove functions for creating response frames from bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40133
diff changeset
  1155
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1156
        # 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
  1157
        # 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
  1158
        # 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
  1159
        # in a bad state.
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1160
        #
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1161
        # 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
  1162
        # 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
  1163
        # 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
  1164
        # 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
  1165
        #
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1166
        # 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
  1167
        # 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
  1168
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1169
        def sendframes():
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1170
            emitted = False
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1171
            alternatelocationsent = False
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
  1172
            emitter = bufferingcommandresponseemitter(stream, requestid)
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1173
            while True:
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1174
                try:
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1175
                    o = next(objs)
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1176
                except StopIteration:
39560
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
  1177
                    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
  1178
                        yield frame
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
  1179
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1180
                    if emitted:
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1181
                        for frame in createcommandresponseeosframes(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1182
                            stream, requestid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1183
                        ):
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1184
                            yield frame
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1185
                    break
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1186
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1187
                except error.WireprotoCommandError as e:
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1188
                    for frame in createcommanderrorresponse(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1189
                        stream, requestid, e.message, e.messageargs
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1190
                    ):
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1191
                        yield frame
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1192
                    break
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1193
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1194
                except Exception as e:
39838
bce1c1af7518 py3: cast exception to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39560
diff changeset
  1195
                    for frame in createerrorframe(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1196
                        stream,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1197
                        requestid,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1198
                        b'%s' % stringutil.forcebytestr(e),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1199
                        errtype=b'server',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1200
                    ):
39838
bce1c1af7518 py3: cast exception to bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39560
diff changeset
  1201
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1202
                        yield frame
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1203
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1204
                    break
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1205
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1206
                try:
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1207
                    # 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
  1208
                    # only object in the output stream.
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1209
                    if isinstance(o, wireprototypes.alternatelocationresponse):
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1210
                        if emitted:
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1211
                            raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1212
                                b'alternatelocationresponse seen after initial '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1213
                                b'output object'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1214
                            )
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1215
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1216
                        frame = stream.makestreamsettingsframe(requestid)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1217
                        if frame:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1218
                            yield frame
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1219
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1220
                        yield createalternatelocationresponseframe(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1221
                            stream, requestid, o
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1222
                        )
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1223
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1224
                        alternatelocationsent = True
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1225
                        emitted = True
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1226
                        continue
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1227
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1228
                    if alternatelocationsent:
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1229
                        raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1230
                            b'object follows alternatelocationresponse'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1231
                        )
40025
b099e6032f38 wireprotov2: server support for sending content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40024
diff changeset
  1232
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1233
                    if not emitted:
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1234
                        # Frame is optional.
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1235
                        frame = stream.makestreamsettingsframe(requestid)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1236
                        if frame:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1237
                            yield frame
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1238
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1239
                        # 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
  1240
                        frame = createcommandresponseokframe(stream, requestid)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1241
                        if frame:
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1242
                            yield frame
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1243
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1244
                        emitted = True
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1245
40020
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1246
                    # 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
  1247
                    # data structures or special types.
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1248
                    # 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
  1249
                    # 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
  1250
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1251
                    # 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
  1252
                    if isinstance(o, wireprototypes.encodedresponse):
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1253
                        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
  1254
                            yield frame
84bf6ded9317 wireprotoframing: buffer emitted data to reduce frame count
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39559
diff changeset
  1255
40328
2c55716f8a1c wireprotov2: add response type that serializes to indefinite length bytestring
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40138
diff changeset
  1256
                    elif isinstance(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1257
                        o, wireprototypes.indefinitebytestringresponse
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1258
                    ):
40328
2c55716f8a1c wireprotov2: add response type that serializes to indefinite length bytestring
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40138
diff changeset
  1259
                        for chunk in cborutil.streamencodebytestringfromiter(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1260
                            o.chunks
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1261
                        ):
40328
2c55716f8a1c wireprotov2: add response type that serializes to indefinite length bytestring
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40138
diff changeset
  1262
2c55716f8a1c wireprotov2: add response type that serializes to indefinite length bytestring
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40138
diff changeset
  1263
                            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
  1264
                                yield frame
2c55716f8a1c wireprotov2: add response type that serializes to indefinite length bytestring
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40138
diff changeset
  1265
40020
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1266
                    # 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
  1267
                    else:
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1268
                        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
  1269
                            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
  1270
                                yield frame
ed919b90acda wireprotov2: define type to represent pre-encoded object
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39838
diff changeset
  1271
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1272
                except Exception as e:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1273
                    for frame in createerrorframe(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1274
                        stream, requestid, b'%s' % e, errtype=b'server'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1275
                    ):
39559
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1276
                        yield frame
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1277
07b58266bce3 wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39486
diff changeset
  1278
                    break
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1279
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1280
            self._activecommands.remove(requestid)
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1281
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1282
        return self._handlesendframes(sendframes())
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1283
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1284
    def oninputeof(self):
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1285
        """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
  1286
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1287
        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
  1288
        completed.
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1289
        """
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1290
        # 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
  1291
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1292
        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
  1293
            return b'noop', {}
37056
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1294
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1295
        # 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
  1296
        def makegen():
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1297
            for gen in self._bufferedframegens:
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1298
                for frame in gen:
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1299
                    yield frame
861e9d37e56e wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37055
diff changeset
  1300
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1301
        return b'sendframes', {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1302
            b'framegen': makegen(),
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1303
        }
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
  1304
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1305
    def _handlesendframes(self, framegen):
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1306
        if self._deferoutput:
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1307
            self._bufferedframegens.append(framegen)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1308
            return b'noop', {}
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1309
        else:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1310
            return b'sendframes', {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1311
                b'framegen': framegen,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1312
            }
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1313
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  1314
    def onservererror(self, stream, requestid, msg):
37288
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1315
        ensureserverstream(stream)
9bfcbe4f4745 wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37285
diff changeset
  1316
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1317
        def sendframes():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1318
            for frame in createerrorframe(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1319
                stream, requestid, msg, errtype=b'server'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1320
            ):
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1321
                yield frame
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1322
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1323
            self._activecommands.remove(requestid)
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1324
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1325
        return self._handlesendframes(sendframes())
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1326
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1327
    def oncommanderror(self, stream, requestid, message, args=None):
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1328
        """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
  1329
        ensureserverstream(stream)
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1330
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1331
        def sendframes():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1332
            for frame in createcommanderrorresponse(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1333
                stream, requestid, message, args
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1334
            ):
37728
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1335
                yield frame
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1336
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1337
            self._activecommands.remove(requestid)
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1338
564a3eec6e63 wireprotov2: add support for more response types
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37726
diff changeset
  1339
        return self._handlesendframes(sendframes())
37055
61393f888dfe wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37052
diff changeset
  1340
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1341
    def makeoutputstream(self):
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1342
        """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
  1343
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1344
        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
  1345
        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
  1346
        we will default to identity.
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1347
        """
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1348
        streamid = self._nextoutgoingstreamid
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1349
        self._nextoutgoingstreamid += 2
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1350
40130
5d44c4d1d516 wireprotov2: establish dedicated classes for input and output streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40129
diff changeset
  1351
        s = outputstream(streamid)
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1352
        self._outgoingstreams[streamid] = s
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1353
40138
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1354
        # 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
  1355
        # 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
  1356
        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
  1357
            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
  1358
                s.setencoder(self._ui, name)
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1359
                break
b5bf3dd6ec5b wireprotov2: send content encoded frames from server
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40136
diff changeset
  1360
37289
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1361
        return s
5fadc63ac99f wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37288
diff changeset
  1362
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1363
    def _makeerrorresult(self, msg):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1364
        return b'error', {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1365
            b'message': msg,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1366
        }
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1367
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1368
    def _makeruncommandresult(self, requestid):
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1369
        entry = self._receivingcommands[requestid]
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1370
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1371
        if not entry[b'requestdone']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1372
            self._state = b'errored'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1373
            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
  1374
                b'should not be called without requestdone set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1375
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1376
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1377
        del self._receivingcommands[requestid]
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1378
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1379
        if self._receivingcommands:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1380
            self._state = b'command-receiving'
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1381
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1382
            self._state = b'idle'
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1383
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1384
        # Decode the payloads as CBOR.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1385
        entry[b'payload'].seek(0)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1386
        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
  1387
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1388
        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
  1389
            self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1390
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1391
                _(b'command request missing "name" field')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1392
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1393
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1394
        if b'args' not in request:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1395
            request[b'args'] = {}
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1396
37063
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1397
        assert requestid not in self._activecommands
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1398
        self._activecommands.add(requestid)
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1399
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1400
        return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1401
            b'runcommand',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1402
            {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1403
                b'requestid': requestid,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1404
                b'command': request[b'name'],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1405
                b'args': request[b'args'],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1406
                b'redirect': request.get(b'redirect'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1407
                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
  1408
            },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1409
        )
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1410
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1411
    def _makewantframeresult(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1412
        return b'wantframe', {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1413
            b'state': self._state,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1414
        }
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1415
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1416
    def _validatecommandrequestframe(self, frame):
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1417
        new = frame.flags & FLAG_COMMAND_REQUEST_NEW
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1418
        continuation = frame.flags & FLAG_COMMAND_REQUEST_CONTINUATION
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1419
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1420
        if new and continuation:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1421
            self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1422
            return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1423
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1424
                    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
  1425
                    b'continuation flags set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1426
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1427
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1428
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1429
        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
  1430
            self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1431
            return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1432
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1433
                    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
  1434
                    b'continuation flags set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1435
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1436
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1437
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1438
    def _onframeinitial(self, frame):
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1439
        # 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
  1440
        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
  1441
            self._state = b'protocol-settings-receiving'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1442
            self._protocolsettingsdecoder = cborutil.bufferingdecoder()
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1443
            return self._onframeprotocolsettings(frame)
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1444
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1445
        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
  1446
            self._state = b'idle'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1447
            return self._onframeidle(frame)
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1448
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1449
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1450
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1451
            return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1452
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1453
                    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
  1454
                    b'frame; got %d'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1455
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1456
                % frame.typeid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1457
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1458
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1459
    def _onframeprotocolsettings(self, frame):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1460
        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
  1461
        assert self._protocolsettingsdecoder is not None
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1462
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1463
        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
  1464
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1465
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1466
                _(b'expected sender protocol settings frame; got %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1467
                % frame.typeid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1468
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1469
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1470
        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
  1471
        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
  1472
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1473
        if more and eos:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1474
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1475
            return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1476
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1477
                    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
  1478
                    b'continuation and end of stream flags set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1479
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1480
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1481
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1482
        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
  1483
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1484
            return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1485
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1486
                    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
  1487
                    b'end of stream flag set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1488
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1489
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1490
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1491
        # 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
  1492
        # buffered.
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1493
        try:
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1494
            self._protocolsettingsdecoder.decode(frame.payload)
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1495
        except Exception as e:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1496
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1497
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1498
                _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1499
                    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
  1500
                )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1501
                % stringutil.forcebytestr(e)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1502
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1503
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1504
        if more:
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1505
            return self._makewantframeresult()
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1506
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1507
        assert eos
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1508
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1509
        decoded = self._protocolsettingsdecoder.getavailable()
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1510
        self._protocolsettingsdecoder = None
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1511
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1512
        if not decoded:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1513
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1514
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1515
                _(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
  1516
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1517
        elif len(decoded) > 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1518
            self._state = b'errored'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1519
            return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1520
                _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1521
                    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
  1522
                    b'values'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1523
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1524
            )
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1525
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1526
        d = decoded[0]
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1527
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1528
        if b'contentencodings' in d:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1529
            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
  1530
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1531
        self._state = b'idle'
40126
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1532
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1533
        return self._makewantframeresult()
327d40b94bed wireprotov2: handle sender protocol settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40125
diff changeset
  1534
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1535
    def _onframeidle(self, frame):
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1536
        # 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
  1537
        # command request.
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1538
        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
  1539
            self._state = b'errored'
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1540
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1541
                _(b'expected command request frame; got %d') % frame.typeid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1542
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1543
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1544
        res = self._validatecommandrequestframe(frame)
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1545
        if res:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1546
            return res
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1547
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1548
        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
  1549
            self._state = b'errored'
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1550
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1551
                _(b'request with ID %d already received') % frame.requestid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1552
            )
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1553
37063
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1554
        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
  1555
            self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1556
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1557
                _(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
  1558
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1559
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1560
        new = frame.flags & FLAG_COMMAND_REQUEST_NEW
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1561
        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
  1562
        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
  1563
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1564
        if not new:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1565
            self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1566
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1567
                _(b'received command request frame without new flag set')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1568
            )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1569
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1570
        payload = util.bytesio()
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1571
        payload.write(frame.payload)
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1572
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1573
        self._receivingcommands[frame.requestid] = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1574
            b'payload': payload,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1575
            b'data': None,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1576
            b'requestdone': not moreframes,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1577
            b'expectingdata': bool(expectingdata),
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1578
        }
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1579
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1580
        # 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
  1581
        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
  1582
            return self._makeruncommandresult(frame.requestid)
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1583
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1584
        assert moreframes or expectingdata
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1585
        self._state = b'command-receiving'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1586
        return self._makewantframeresult()
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1587
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1588
    def _onframecommandreceiving(self, frame):
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1589
        if frame.typeid == FRAME_TYPE_COMMAND_REQUEST:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1590
            # Process new command requests as such.
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1591
            if frame.flags & FLAG_COMMAND_REQUEST_NEW:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1592
                return self._onframeidle(frame)
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1593
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1594
            res = self._validatecommandrequestframe(frame)
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1595
            if res:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1596
                return res
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1597
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1598
        # 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
  1599
        # receiving but is not active.
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1600
        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
  1601
            self._state = b'errored'
37063
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1602
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1603
                _(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
  1604
                % frame.requestid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1605
            )
37063
39304dd63589 wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37062
diff changeset
  1606
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1607
        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
  1608
            self._state = b'errored'
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1609
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1610
                _(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
  1611
                % frame.requestid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1612
            )
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1613
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1614
        entry = self._receivingcommands[frame.requestid]
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1615
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1616
        if frame.typeid == FRAME_TYPE_COMMAND_REQUEST:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1617
            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
  1618
            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
  1619
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1620
            if entry[b'requestdone']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1621
                self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1622
                return self._makeerrorresult(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1623
                    _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1624
                        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
  1625
                        b'were supposedly done'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1626
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1627
                )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1628
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1629
            if expectingdata != entry[b'expectingdata']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1630
                self._state = b'errored'
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1631
                return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1632
                    _(b'mismatch between expect data flag and previous frame')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1633
                )
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1634
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1635
            entry[b'payload'].write(frame.payload)
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1636
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1637
            if not moreframes:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1638
                entry[b'requestdone'] = True
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1639
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1640
            if not moreframes and not expectingdata:
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1641
                return self._makeruncommandresult(frame.requestid)
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1642
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1643
            return self._makewantframeresult()
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1644
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1645
        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
  1646
            if not entry[b'expectingdata']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1647
                self._state = b'errored'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1648
                return self._makeerrorresult(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1649
                    _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1650
                        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
  1651
                        b'expecting data: %d'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1652
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1653
                    % frame.requestid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1654
                )
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1655
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1656
            if entry[b'data'] is None:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1657
                entry[b'data'] = util.bytesio()
37058
c5e9c3b47366 wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37057
diff changeset
  1658
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1659
            return self._handlecommanddataframe(frame, entry)
37292
3d0e2cd86e05 wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37291
diff changeset
  1660
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1661
            self._state = b'errored'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1662
            return self._makeerrorresult(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1663
                _(b'received unexpected frame type: %d') % frame.typeid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1664
            )
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1665
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1666
    def _handlecommanddataframe(self, frame, entry):
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1667
        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
  1668
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1669
        # 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
  1670
        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
  1671
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1672
        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
  1673
            return self._makewantframeresult()
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1674
        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
  1675
            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
  1676
            return self._makeruncommandresult(frame.requestid)
37052
8c3c47362934 wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37051
diff changeset
  1677
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1678
            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
  1679
            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
  1680
37061
884a0c1604ad wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37060
diff changeset
  1681
    def _onframeerrored(self, frame):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1682
        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
  1683
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1684
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
  1685
class commandrequest:
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1686
    """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
  1687
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40020
diff changeset
  1688
    def __init__(self, requestid, 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
  1689
        self.requestid = requestid
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1690
        self.name = name
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1691
        self.args = args
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1692
        self.datafh = datafh
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40020
diff changeset
  1693
        self.redirect = redirect
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1694
        self.state = b'pending'
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1695
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1696
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
  1697
class clientreactor:
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1698
    """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
  1699
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1700
    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
  1701
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1702
    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
  1703
    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
  1704
    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
  1705
    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
  1706
    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
  1707
    separate instance for each distinct interaction.
40127
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1708
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1709
    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
  1710
    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
  1711
    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
  1712
    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
  1713
    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
  1714
    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
  1715
    to those frames.
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1716
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1717
    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
  1718
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1719
    noop
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1720
       Indicates no additional action is required.
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1721
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1722
    sendframes
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1723
       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
  1724
       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
  1725
       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
  1726
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1727
    error
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1728
       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
  1729
       error message describing the failure.
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1730
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1731
    responsedata
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1732
       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
  1733
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1734
       The ``request`` key contains the ``commandrequest`` instance that
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1735
       represents the request this data is for.
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1736
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1737
       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
  1738
080419fa4fe4 wireprotov2: document client reactor actions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40126
diff changeset
  1739
       ``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
  1740
       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
  1741
       respectively.
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1742
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1743
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1744
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1745
        self,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1746
        ui,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1747
        hasmultiplesend=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1748
        buffersends=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1749
        clientcontentencoders=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1750
    ):
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1751
        """Create a new instance.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1752
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1753
        ``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
  1754
        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
  1755
        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
  1756
        send operation.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1757
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1758
        ``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
  1759
        last request has been issued.
40133
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1760
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1761
        ``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
  1762
        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
  1763
        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
  1764
        to the server.
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1765
        """
40129
293835e0fff7 wireprotov2: pass ui into clientreactor and serverreactor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40128
diff changeset
  1766
        self._ui = ui
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1767
        self._hasmultiplesend = hasmultiplesend
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1768
        self._buffersends = buffersends
40133
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1769
        self._clientcontentencoders = clientcontentencoders
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1770
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1771
        self._canissuecommands = True
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1772
        self._cansend = True
40133
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1773
        self._protocolsettingssent = False
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1774
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1775
        self._nextrequestid = 1
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1776
        # 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
  1777
        self._outgoingstream = outputstream(1)
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1778
        self._pendingrequests = collections.deque()
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1779
        self._activerequests = {}
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1780
        self._incomingstreams = {}
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  1781
        self._streamsettingsdecoders = {}
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1782
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1783
        populatestreamencoders()
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1784
40024
86b22a4cfab1 wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40020
diff changeset
  1785
    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
  1786
        """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
  1787
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1788
        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
  1789
        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
  1790
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1791
        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
  1792
        """
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1793
        if not self._canissuecommands:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1794
            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
  1795
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1796
        requestid = self._nextrequestid
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1797
        self._nextrequestid += 2
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1798
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1799
        request = commandrequest(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1800
            requestid, name, args, datafh=datafh, redirect=redirect
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1801
        )
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1802
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1803
        if self._buffersends:
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1804
            self._pendingrequests.append(request)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1805
            return request, b'noop', {}
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1806
        else:
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1807
            if not self._cansend:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1808
                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
  1809
                    b'sends cannot be performed on this instance'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1810
                )
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1811
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1812
            if not self._hasmultiplesend:
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1813
                self._cansend = False
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1814
                self._canissuecommands = False
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1815
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1816
            return (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1817
                request,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1818
                b'sendframes',
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1819
                {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1820
                    b'framegen': self._makecommandframes(request),
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1821
                },
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1822
            )
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1823
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1824
    def flushcommands(self):
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1825
        """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
  1826
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1827
        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
  1828
        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
  1829
        to no-op.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1830
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1831
        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
  1832
        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
  1833
        """
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1834
        if not self._pendingrequests:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1835
            return b'noop', {}
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1836
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1837
        if not self._cansend:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1838
            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
  1839
                b'sends cannot be performed on this instance'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1840
            )
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1841
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1842
        # 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
  1843
        # our one shot.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1844
        if not self._hasmultiplesend:
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1845
            self._canissuecommands = False
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1846
            self._cansend = False
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1847
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1848
        def makeframes():
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1849
            while self._pendingrequests:
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1850
                request = self._pendingrequests.popleft()
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1851
                for frame in self._makecommandframes(request):
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1852
                    yield frame
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1853
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1854
        return b'sendframes', {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1855
            b'framegen': makeframes(),
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1856
        }
37543
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
    def _makecommandframes(self, request):
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1859
        """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
  1860
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1861
        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
  1862
        state.
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1863
        """
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1864
        self._activerequests[request.requestid] = request
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1865
        request.state = b'sending'
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1866
40133
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1867
        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
  1868
            self._protocolsettingssent = True
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1869
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1870
            payload = b''.join(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1871
                cborutil.streamencode(
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1872
                    {
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1873
                        b'contentencodings': self._clientcontentencoders,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43506
diff changeset
  1874
                    }
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1875
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1876
            )
40133
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1877
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1878
            yield self._outgoingstream.makeframe(
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1879
                requestid=request.requestid,
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1880
                typeid=FRAME_TYPE_SENDER_PROTOCOL_SETTINGS,
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1881
                flags=FLAG_SENDER_PROTOCOL_SETTINGS_EOS,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1882
                payload=payload,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1883
            )
40133
762ef19a07e3 wireprotov2: send protocol settings frame from client
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40132
diff changeset
  1884
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1885
        res = createcommandframes(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1886
            self._outgoingstream,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1887
            request.requestid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1888
            request.name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1889
            request.args,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1890
            datafh=request.datafh,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1891
            redirect=request.redirect,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1892
        )
37543
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1893
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1894
        for frame in res:
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1895
            yield frame
01361be9e2dc wireproto: introduce a reactor for client-side state
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37485
diff changeset
  1896
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1897
        request.state = b'sent'
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1898
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1899
    def onframerecv(self, frame):
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1900
        """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
  1901
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1902
        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
  1903
        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
  1904
        """
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1905
        if frame.streamid % 2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1906
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1907
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1908
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1909
                    b'message': (
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1910
                        _(b'received frame with odd numbered stream ID: %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1911
                        % frame.streamid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1912
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1913
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1914
            )
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1915
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1916
        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
  1917
            if not frame.streamflags & STREAM_FLAG_BEGIN_STREAM:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1918
                return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1919
                    b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1920
                    {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1921
                        b'message': _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1922
                            b'received frame on unknown stream '
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1923
                            b'without beginning of stream flag set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1924
                        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1925
                    },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1926
                )
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1927
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1928
            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
  1929
40132
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1930
        stream = self._incomingstreams[frame.streamid]
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1931
e67522413ca8 wireprotov2: define and use stream encoders
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40130
diff changeset
  1932
        # 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
  1933
        # 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
  1934
        # 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
  1935
        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
  1936
            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
  1937
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1938
        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
  1939
            del self._incomingstreams[frame.streamid]
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1940
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  1941
        if frame.typeid == FRAME_TYPE_STREAM_SETTINGS:
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  1942
            return self._onstreamsettingsframe(frame)
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  1943
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1944
        if frame.requestid not in self._activerequests:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1945
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1946
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1947
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1948
                    b'message': (
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1949
                        _(b'received frame for inactive request ID: %d')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1950
                        % frame.requestid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1951
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1952
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1953
            )
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1954
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1955
        request = self._activerequests[frame.requestid]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1956
        request.state = b'receiving'
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1957
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1958
        handlers = {
37724
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
  1959
            FRAME_TYPE_COMMAND_RESPONSE: self._oncommandresponseframe,
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  1960
            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
  1961
        }
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1962
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1963
        meth = handlers.get(frame.typeid)
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1964
        if not meth:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1965
            raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1966
                b'unhandled frame type: %d' % frame.typeid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1967
            )
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1968
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1969
        return meth(request, frame)
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  1970
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  1971
    def _onstreamsettingsframe(self, frame):
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  1972
        assert frame.typeid == FRAME_TYPE_STREAM_SETTINGS
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  1973
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  1974
        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
  1975
        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
  1976
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  1977
        if more and eos:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1978
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1979
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1980
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1981
                    b'message': (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1982
                        _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1983
                            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
  1984
                            b'continuation and end of stream flags set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1985
                        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1986
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1987
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1988
            )
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  1989
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  1990
        if not more and not eos:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1991
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1992
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1993
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1994
                    b'message': _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1995
                        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
  1996
                        b'continuation or end of stream flag set'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1997
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1998
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  1999
            )
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2000
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2001
        if frame.streamid not in self._streamsettingsdecoders:
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2002
            decoder = cborutil.bufferingdecoder()
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2003
            self._streamsettingsdecoders[frame.streamid] = decoder
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2004
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2005
        decoder = self._streamsettingsdecoders[frame.streamid]
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2006
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2007
        try:
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2008
            decoder.decode(frame.payload)
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2009
        except Exception as e:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2010
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2011
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2012
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2013
                    b'message': (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2014
                        _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2015
                            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
  2016
                            b'settings frame: %s'
43076
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
                        % stringutil.forcebytestr(e)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2019
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2020
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2021
            )
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2022
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2023
        if more:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2024
            return b'noop', {}
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2025
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2026
        assert eos
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2027
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2028
        decoded = decoder.getavailable()
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2029
        del self._streamsettingsdecoders[frame.streamid]
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2030
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2031
        if not decoded:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2032
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2033
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2034
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2035
                    b'message': _(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2036
                        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
  2037
                        b'CBOR data'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2038
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2039
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2040
            )
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2041
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2042
        try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2043
            self._incomingstreams[frame.streamid].setdecoder(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2044
                self._ui, decoded[0], decoded[1:]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2045
            )
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2046
        except Exception as e:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2047
            return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2048
                b'error',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2049
                {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2050
                    b'message': (
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2051
                        _(b'error setting stream decoder: %s')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2052
                        % stringutil.forcebytestr(e)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2053
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2054
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2055
            )
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2056
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2057
        return b'noop', {}
40128
57782791b7e9 wireprotov2: handle stream encoding settings frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40127
diff changeset
  2058
37724
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
  2059
    def _oncommandresponseframe(self, request, frame):
deff7cf7eefd wireprotov2: change frame type and name for command response
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37723
diff changeset
  2060
        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
  2061
            request.state = b'received'
37544
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2062
            del self._activerequests[request.requestid]
55b5ba8d4e68 wireproto: client reactor support for receiving frames
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37543
diff changeset
  2063
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2064
        return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2065
            b'responsedata',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2066
            {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2067
                b'request': request,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2068
                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
  2069
                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
  2070
                b'data': frame.payload,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2071
            },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2072
        )
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  2073
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  2074
    def _onerrorresponseframe(self, request, frame):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2075
        request.state = b'errored'
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  2076
        del self._activerequests[request.requestid]
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  2077
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  2078
        # The payload should be a CBOR map.
39446
36f487a332ad wireprotoframing: use our CBOR module
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37728
diff changeset
  2079
        m = cborutil.decodeall(frame.payload)[0]
37726
0c184ca594bb wireprotov2: change behavior of error frame
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37725
diff changeset
  2080
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2081
        return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2082
            b'error',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2083
            {
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2084
                b'request': request,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2085
                b'type': m[b'type'],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2086
                b'message': m[b'message'],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  2087
            },
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40328
diff changeset
  2088
        )