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