author | Gregory Szorc <gregory.szorc@gmail.com> |
Wed, 28 Mar 2018 14:55:13 -0700 | |
changeset 37485 | 0b7475ea38cf |
parent 37476 | e9dea82ea1f3 |
child 37543 | 01361be9e2dc |
permissions | -rw-r--r-- |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
1 |
# wireprotoframing.py - unified framing protocol for wire protocol |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
2 |
# |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
3 |
# Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com> |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
4 |
# |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
5 |
# This software may be used and distributed according to the terms of the |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
6 |
# GNU General Public License version 2 or any later version. |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
7 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
8 |
# This file contains functionality to support the unified frame-based wire |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
9 |
# protocol. For details about the protocol, see |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
10 |
# `hg help internals.wireprotocol`. |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
11 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
12 |
from __future__ import absolute_import |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
13 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
14 |
import struct |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
15 |
|
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
16 |
from .i18n import _ |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
17 |
from .thirdparty import ( |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
18 |
attr, |
37290
cc5a040fe150
wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37289
diff
changeset
|
19 |
cbor, |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
20 |
) |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
21 |
from . import ( |
37474
d33997123ea5
py3: system-stringify repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents:
37473
diff
changeset
|
22 |
encoding, |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
23 |
error, |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
24 |
util, |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
25 |
) |
37084
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37063
diff
changeset
|
26 |
from .utils import ( |
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37063
diff
changeset
|
27 |
stringutil, |
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37063
diff
changeset
|
28 |
) |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
29 |
|
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
30 |
FRAME_HEADER_SIZE = 8 |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
31 |
DEFAULT_MAX_FRAME_SIZE = 32768 |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
32 |
|
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
33 |
STREAM_FLAG_BEGIN_STREAM = 0x01 |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
34 |
STREAM_FLAG_END_STREAM = 0x02 |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
35 |
STREAM_FLAG_ENCODING_APPLIED = 0x04 |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
36 |
|
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
37 |
STREAM_FLAGS = { |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
38 |
b'stream-begin': STREAM_FLAG_BEGIN_STREAM, |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
39 |
b'stream-end': STREAM_FLAG_END_STREAM, |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
40 |
b'encoded': STREAM_FLAG_ENCODING_APPLIED, |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
41 |
} |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
42 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
43 |
FRAME_TYPE_COMMAND_REQUEST = 0x01 |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
44 |
FRAME_TYPE_COMMAND_DATA = 0x03 |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
45 |
FRAME_TYPE_BYTES_RESPONSE = 0x04 |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
46 |
FRAME_TYPE_ERROR_RESPONSE = 0x05 |
37060
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
47 |
FRAME_TYPE_TEXT_OUTPUT = 0x06 |
37291
b0041036214e
wireproto: define frame to represent progress updates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37290
diff
changeset
|
48 |
FRAME_TYPE_PROGRESS = 0x07 |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
49 |
FRAME_TYPE_STREAM_SETTINGS = 0x08 |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
50 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
51 |
FRAME_TYPES = { |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
52 |
b'command-request': FRAME_TYPE_COMMAND_REQUEST, |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
53 |
b'command-data': FRAME_TYPE_COMMAND_DATA, |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
54 |
b'bytes-response': FRAME_TYPE_BYTES_RESPONSE, |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
55 |
b'error-response': FRAME_TYPE_ERROR_RESPONSE, |
37060
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
56 |
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
|
57 |
b'progress': FRAME_TYPE_PROGRESS, |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
58 |
b'stream-settings': FRAME_TYPE_STREAM_SETTINGS, |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
59 |
} |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
60 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
61 |
FLAG_COMMAND_REQUEST_NEW = 0x01 |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
62 |
FLAG_COMMAND_REQUEST_CONTINUATION = 0x02 |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
63 |
FLAG_COMMAND_REQUEST_MORE_FRAMES = 0x04 |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
64 |
FLAG_COMMAND_REQUEST_EXPECT_DATA = 0x08 |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
65 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
66 |
FLAGS_COMMAND_REQUEST = { |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
67 |
b'new': FLAG_COMMAND_REQUEST_NEW, |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
68 |
b'continuation': FLAG_COMMAND_REQUEST_CONTINUATION, |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
69 |
b'more': FLAG_COMMAND_REQUEST_MORE_FRAMES, |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
70 |
b'have-data': FLAG_COMMAND_REQUEST_EXPECT_DATA, |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
71 |
} |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
72 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
73 |
FLAG_COMMAND_DATA_CONTINUATION = 0x01 |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
74 |
FLAG_COMMAND_DATA_EOS = 0x02 |
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 |
FLAGS_COMMAND_DATA = { |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
77 |
b'continuation': FLAG_COMMAND_DATA_CONTINUATION, |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
78 |
b'eos': FLAG_COMMAND_DATA_EOS, |
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 |
|
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
81 |
FLAG_BYTES_RESPONSE_CONTINUATION = 0x01 |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
82 |
FLAG_BYTES_RESPONSE_EOS = 0x02 |
37299
e9aadee698cf
wireproto: add frame flag to denote payloads as CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37298
diff
changeset
|
83 |
FLAG_BYTES_RESPONSE_CBOR = 0x04 |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
84 |
|
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
85 |
FLAGS_BYTES_RESPONSE = { |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
86 |
b'continuation': FLAG_BYTES_RESPONSE_CONTINUATION, |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
87 |
b'eos': FLAG_BYTES_RESPONSE_EOS, |
37299
e9aadee698cf
wireproto: add frame flag to denote payloads as CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37298
diff
changeset
|
88 |
b'cbor': FLAG_BYTES_RESPONSE_CBOR, |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
89 |
} |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
90 |
|
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
91 |
FLAG_ERROR_RESPONSE_PROTOCOL = 0x01 |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
92 |
FLAG_ERROR_RESPONSE_APPLICATION = 0x02 |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
93 |
|
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
94 |
FLAGS_ERROR_RESPONSE = { |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
95 |
b'protocol': FLAG_ERROR_RESPONSE_PROTOCOL, |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
96 |
b'application': FLAG_ERROR_RESPONSE_APPLICATION, |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
97 |
} |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
98 |
|
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
99 |
# 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
|
100 |
FRAME_TYPE_FLAGS = { |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
101 |
FRAME_TYPE_COMMAND_REQUEST: FLAGS_COMMAND_REQUEST, |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
102 |
FRAME_TYPE_COMMAND_DATA: FLAGS_COMMAND_DATA, |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
103 |
FRAME_TYPE_BYTES_RESPONSE: FLAGS_BYTES_RESPONSE, |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
104 |
FRAME_TYPE_ERROR_RESPONSE: FLAGS_ERROR_RESPONSE, |
37060
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
105 |
FRAME_TYPE_TEXT_OUTPUT: {}, |
37291
b0041036214e
wireproto: define frame to represent progress updates
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37290
diff
changeset
|
106 |
FRAME_TYPE_PROGRESS: {}, |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
107 |
FRAME_TYPE_STREAM_SETTINGS: {}, |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
108 |
} |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
109 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
110 |
ARGUMENT_RECORD_HEADER = struct.Struct(r'<HH') |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
111 |
|
37298
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
112 |
def humanflags(mapping, value): |
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
113 |
"""Convert a numeric flags value to a human value, using a mapping table.""" |
37473
7c2c7c749411
wireproto: show unknown id and flags in repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents:
37472
diff
changeset
|
114 |
namemap = {v: k for k, v in mapping.iteritems()} |
37298
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
115 |
flags = [] |
37473
7c2c7c749411
wireproto: show unknown id and flags in repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents:
37472
diff
changeset
|
116 |
val = 1 |
7c2c7c749411
wireproto: show unknown id and flags in repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents:
37472
diff
changeset
|
117 |
while value >= val: |
37298
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
118 |
if value & val: |
37473
7c2c7c749411
wireproto: show unknown id and flags in repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents:
37472
diff
changeset
|
119 |
flags.append(namemap.get(val, '<unknown 0x%02x>' % val)) |
7c2c7c749411
wireproto: show unknown id and flags in repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents:
37472
diff
changeset
|
120 |
val <<= 1 |
37298
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
121 |
|
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
122 |
return b'|'.join(flags) |
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
123 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
124 |
@attr.s(slots=True) |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
125 |
class frameheader(object): |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
126 |
"""Represents the data in a frame header.""" |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
127 |
|
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
128 |
length = attr.ib() |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
129 |
requestid = attr.ib() |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
130 |
streamid = attr.ib() |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
131 |
streamflags = attr.ib() |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
132 |
typeid = attr.ib() |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
133 |
flags = attr.ib() |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
134 |
|
37298
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
135 |
@attr.s(slots=True, repr=False) |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
136 |
class frame(object): |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
137 |
"""Represents a parsed frame.""" |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
138 |
|
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
139 |
requestid = attr.ib() |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
140 |
streamid = attr.ib() |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
141 |
streamflags = attr.ib() |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
142 |
typeid = attr.ib() |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
143 |
flags = attr.ib() |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
144 |
payload = attr.ib() |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
145 |
|
37474
d33997123ea5
py3: system-stringify repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents:
37473
diff
changeset
|
146 |
@encoding.strmethod |
37298
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
147 |
def __repr__(self): |
37473
7c2c7c749411
wireproto: show unknown id and flags in repr(frame)
Yuya Nishihara <yuya@tcha.org>
parents:
37472
diff
changeset
|
148 |
typename = '<unknown 0x%02x>' % self.typeid |
37298
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
149 |
for name, value in FRAME_TYPES.iteritems(): |
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
150 |
if value == self.typeid: |
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
151 |
typename = name |
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
152 |
break |
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
153 |
|
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
154 |
return ('frame(size=%d; request=%d; stream=%d; streamflags=%s; ' |
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
155 |
'type=%s; flags=%s)' % ( |
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
156 |
len(self.payload), self.requestid, self.streamid, |
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
157 |
humanflags(STREAM_FLAGS, self.streamflags), typename, |
37472
2f81926c7f89
wireproto: fix repr(frame) to not crash by unknown type id
Yuya Nishihara <yuya@tcha.org>
parents:
37319
diff
changeset
|
158 |
humanflags(FRAME_TYPE_FLAGS.get(self.typeid, {}), self.flags))) |
37298
5ef2da00e935
wireproto: implement custom __repr__ for frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37292
diff
changeset
|
159 |
|
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
160 |
def makeframe(requestid, streamid, streamflags, typeid, flags, payload): |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
161 |
"""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
|
162 |
# TODO assert size of payload. |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
163 |
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
|
164 |
|
37057
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
165 |
# 24 bits length |
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
166 |
# 16 bits request id |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
167 |
# 8 bits stream id |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
168 |
# 8 bits stream flags |
37057
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
169 |
# 4 bits type |
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
170 |
# 4 bits flags |
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
171 |
|
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
172 |
l = struct.pack(r'<I', len(payload)) |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
173 |
frame[0:3] = l[0:3] |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
174 |
struct.pack_into(r'<HBB', frame, 3, requestid, streamid, streamflags) |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
175 |
frame[7] = (typeid << 4) | flags |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
176 |
frame[8:] = payload |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
177 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
178 |
return frame |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
179 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
180 |
def makeframefromhumanstring(s): |
37057
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
181 |
"""Create a frame from a human readable string |
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
182 |
|
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
183 |
Strings have the form: |
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
184 |
|
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
185 |
<request-id> <stream-id> <stream-flags> <type> <flags> <payload> |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
186 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
187 |
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
|
188 |
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
|
189 |
|
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
190 |
Request ID and stream IDs are integers. |
37057
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
191 |
|
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
192 |
Stream flags, frame type, and flags can be specified by integer or |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
193 |
named constant. |
37057
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
194 |
|
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
195 |
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
|
196 |
|
cc5a040fe150
wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37289
diff
changeset
|
197 |
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
|
198 |
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
|
199 |
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
|
200 |
byte string literal. |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
201 |
""" |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
202 |
fields = s.split(b' ', 5) |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
203 |
requestid, streamid, streamflags, frametype, frameflags, payload = fields |
37057
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
204 |
|
2ec1fb9de638
wireproto: add request IDs to frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37056
diff
changeset
|
205 |
requestid = int(requestid) |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
206 |
streamid = int(streamid) |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
207 |
|
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
208 |
finalstreamflags = 0 |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
209 |
for flag in streamflags.split(b'|'): |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
210 |
if flag in STREAM_FLAGS: |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
211 |
finalstreamflags |= STREAM_FLAGS[flag] |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
212 |
else: |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
213 |
finalstreamflags |= int(flag) |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
214 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
215 |
if frametype in FRAME_TYPES: |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
216 |
frametype = FRAME_TYPES[frametype] |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
217 |
else: |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
218 |
frametype = int(frametype) |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
219 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
220 |
finalflags = 0 |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
221 |
validflags = FRAME_TYPE_FLAGS[frametype] |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
222 |
for flag in frameflags.split(b'|'): |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
223 |
if flag in validflags: |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
224 |
finalflags |= validflags[flag] |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
225 |
else: |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
226 |
finalflags |= int(flag) |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
227 |
|
37290
cc5a040fe150
wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37289
diff
changeset
|
228 |
if payload.startswith(b'cbor:'): |
37476
e9dea82ea1f3
wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents:
37474
diff
changeset
|
229 |
payload = cbor.dumps(stringutil.evalpythonliteral(payload[5:]), |
e9dea82ea1f3
wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents:
37474
diff
changeset
|
230 |
canonical=True) |
37290
cc5a040fe150
wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37289
diff
changeset
|
231 |
|
cc5a040fe150
wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37289
diff
changeset
|
232 |
else: |
cc5a040fe150
wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37289
diff
changeset
|
233 |
payload = stringutil.unescapestr(payload) |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
234 |
|
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
235 |
return makeframe(requestid=requestid, streamid=streamid, |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
236 |
streamflags=finalstreamflags, typeid=frametype, |
37062
fe4c944f95bb
wireproto: use named arguments when passing around frame data
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37061
diff
changeset
|
237 |
flags=finalflags, payload=payload) |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
238 |
|
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
239 |
def parseheader(data): |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
240 |
"""Parse a unified framing protocol frame header from a buffer. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
241 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
242 |
The header is expected to be in the buffer at offset 0 and the |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
243 |
buffer is expected to be large enough to hold a full header. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
244 |
""" |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
245 |
# 24 bits payload length (little endian) |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
246 |
# 16 bits request ID |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
247 |
# 8 bits stream ID |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
248 |
# 8 bits stream flags |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
249 |
# 4 bits frame type |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
250 |
# 4 bits frame flags |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
251 |
# ... payload |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
252 |
framelength = data[0] + 256 * data[1] + 16384 * data[2] |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
253 |
requestid, streamid, streamflags = struct.unpack_from(r'<HBB', data, 3) |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
254 |
typeflags = data[7] |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
255 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
256 |
frametype = (typeflags & 0xf0) >> 4 |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
257 |
frameflags = typeflags & 0x0f |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
258 |
|
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
259 |
return frameheader(framelength, requestid, streamid, streamflags, |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
260 |
frametype, frameflags) |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
261 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
262 |
def readframe(fh): |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
263 |
"""Read a unified framing protocol frame from a file object. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
264 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
265 |
Returns a 3-tuple of (type, flags, payload) for the decoded frame or |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
266 |
None if no frame is available. May raise if a malformed frame is |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
267 |
seen. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
268 |
""" |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
269 |
header = bytearray(FRAME_HEADER_SIZE) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
270 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
271 |
readcount = fh.readinto(header) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
272 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
273 |
if readcount == 0: |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
274 |
return None |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
275 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
276 |
if readcount != FRAME_HEADER_SIZE: |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
277 |
raise error.Abort(_('received incomplete frame: got %d bytes: %s') % |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
278 |
(readcount, header)) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
279 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
280 |
h = parseheader(header) |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
281 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
282 |
payload = fh.read(h.length) |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
283 |
if len(payload) != h.length: |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
284 |
raise error.Abort(_('frame length error: expected %d; got %d') % |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
285 |
(h.length, len(payload))) |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
286 |
|
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
287 |
return frame(h.requestid, h.streamid, h.streamflags, h.typeid, h.flags, |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
288 |
payload) |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
289 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
290 |
def createcommandframes(stream, requestid, cmd, args, datafh=None, |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
291 |
maxframesize=DEFAULT_MAX_FRAME_SIZE): |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
292 |
"""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
|
293 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
294 |
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
|
295 |
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
|
296 |
""" |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
297 |
data = {b'name': cmd} |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
298 |
if args: |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
299 |
data[b'args'] = args |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
300 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
301 |
data = cbor.dumps(data, canonical=True) |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
302 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
303 |
offset = 0 |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
304 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
305 |
while True: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
306 |
flags = 0 |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
307 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
308 |
# Must set new or continuation flag. |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
309 |
if not offset: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
310 |
flags |= FLAG_COMMAND_REQUEST_NEW |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
311 |
else: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
312 |
flags |= FLAG_COMMAND_REQUEST_CONTINUATION |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
313 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
314 |
# Data frames is set on all frames. |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
315 |
if datafh: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
316 |
flags |= FLAG_COMMAND_REQUEST_EXPECT_DATA |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
317 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
318 |
payload = data[offset:offset + maxframesize] |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
319 |
offset += len(payload) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
320 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
321 |
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
|
322 |
flags |= FLAG_COMMAND_REQUEST_MORE_FRAMES |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
323 |
|
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
324 |
yield stream.makeframe(requestid=requestid, |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
325 |
typeid=FRAME_TYPE_COMMAND_REQUEST, |
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
326 |
flags=flags, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
327 |
payload=payload) |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
328 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
329 |
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
|
330 |
break |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
331 |
|
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
332 |
if datafh: |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
333 |
while True: |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
334 |
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
|
335 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
336 |
done = False |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
337 |
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
|
338 |
flags = FLAG_COMMAND_DATA_CONTINUATION |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
339 |
else: |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
340 |
flags = FLAG_COMMAND_DATA_EOS |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
341 |
assert datafh.read(1) == b'' |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
342 |
done = True |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
343 |
|
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
344 |
yield stream.makeframe(requestid=requestid, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
345 |
typeid=FRAME_TYPE_COMMAND_DATA, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
346 |
flags=flags, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
347 |
payload=data) |
37051
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
348 |
|
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
349 |
if done: |
40206e227412
wireproto: define and implement protocol for issuing requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
350 |
break |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
351 |
|
37485
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
352 |
def createbytesresponseframesfrombytes(stream, requestid, data, iscbor=False, |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
353 |
maxframesize=DEFAULT_MAX_FRAME_SIZE): |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
354 |
"""Create a raw frame to send a bytes response from static bytes input. |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
355 |
|
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
356 |
Returns a generator of bytearrays. |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
357 |
""" |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
358 |
|
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
359 |
# Simple case of a single frame. |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
360 |
if len(data) <= maxframesize: |
37485
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
361 |
flags = FLAG_BYTES_RESPONSE_EOS |
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
362 |
if iscbor: |
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
363 |
flags |= FLAG_BYTES_RESPONSE_CBOR |
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
364 |
|
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
365 |
yield stream.makeframe(requestid=requestid, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
366 |
typeid=FRAME_TYPE_BYTES_RESPONSE, |
37485
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
367 |
flags=flags, |
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
368 |
payload=data) |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
369 |
return |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
370 |
|
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
371 |
offset = 0 |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
372 |
while True: |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
373 |
chunk = data[offset:offset + maxframesize] |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
374 |
offset += len(chunk) |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
375 |
done = offset == len(data) |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
376 |
|
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
377 |
if done: |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
378 |
flags = FLAG_BYTES_RESPONSE_EOS |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
379 |
else: |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
380 |
flags = FLAG_BYTES_RESPONSE_CONTINUATION |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
381 |
|
37485
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
382 |
if iscbor: |
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
383 |
flags |= FLAG_BYTES_RESPONSE_CBOR |
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
384 |
|
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
385 |
yield stream.makeframe(requestid=requestid, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
386 |
typeid=FRAME_TYPE_BYTES_RESPONSE, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
387 |
flags=flags, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
388 |
payload=chunk) |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
389 |
|
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
390 |
if done: |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
391 |
break |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
392 |
|
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
393 |
def createerrorframe(stream, requestid, msg, protocol=False, application=False): |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
394 |
# TODO properly handle frame size limits. |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
395 |
assert len(msg) <= DEFAULT_MAX_FRAME_SIZE |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
396 |
|
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
397 |
flags = 0 |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
398 |
if protocol: |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
399 |
flags |= FLAG_ERROR_RESPONSE_PROTOCOL |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
400 |
if application: |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
401 |
flags |= FLAG_ERROR_RESPONSE_APPLICATION |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
402 |
|
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
403 |
yield stream.makeframe(requestid=requestid, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
404 |
typeid=FRAME_TYPE_ERROR_RESPONSE, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
405 |
flags=flags, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
406 |
payload=msg) |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
407 |
|
37319
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
408 |
def createtextoutputframe(stream, requestid, atoms, |
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
409 |
maxframesize=DEFAULT_MAX_FRAME_SIZE): |
37060
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
410 |
"""Create a text output frame to render text to people. |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
411 |
|
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
412 |
``atoms`` is a 3-tuple of (formatting string, args, labels). |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
413 |
|
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
414 |
The formatting string contains ``%s`` tokens to be replaced by the |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
415 |
corresponding indexed entry in ``args``. ``labels`` is an iterable of |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
416 |
formatters to be applied at rendering time. In terms of the ``ui`` |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
417 |
class, each atom corresponds to a ``ui.write()``. |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
418 |
""" |
37319
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
419 |
atomdicts = [] |
37060
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
420 |
|
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
421 |
for (formatting, args, labels) in atoms: |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
422 |
# TODO look for localstr, other types here? |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
423 |
|
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
424 |
if not isinstance(formatting, bytes): |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
425 |
raise ValueError('must use bytes formatting strings') |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
426 |
for arg in args: |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
427 |
if not isinstance(arg, bytes): |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
428 |
raise ValueError('must use bytes for arguments') |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
429 |
for label in labels: |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
430 |
if not isinstance(label, bytes): |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
431 |
raise ValueError('must use bytes for labels') |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
432 |
|
37319
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
433 |
# Formatting string must be ASCII. |
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
434 |
formatting = formatting.decode(r'ascii', r'replace').encode(r'ascii') |
37060
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
435 |
|
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
436 |
# Arguments must be UTF-8. |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
437 |
args = [a.decode(r'utf-8', r'replace').encode(r'utf-8') for a in args] |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
438 |
|
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
439 |
# Labels must be ASCII. |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
440 |
labels = [l.decode(r'ascii', r'strict').encode(r'ascii') |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
441 |
for l in labels] |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
442 |
|
37319
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
443 |
atom = {b'msg': formatting} |
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
444 |
if args: |
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
445 |
atom[b'args'] = args |
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
446 |
if labels: |
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
447 |
atom[b'labels'] = labels |
37060
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
448 |
|
37319
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
449 |
atomdicts.append(atom) |
37060
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
450 |
|
37319
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
451 |
payload = cbor.dumps(atomdicts, canonical=True) |
37060
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
452 |
|
37319
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
453 |
if len(payload) > maxframesize: |
37060
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
454 |
raise ValueError('cannot encode data in a single frame') |
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
455 |
|
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
456 |
yield stream.makeframe(requestid=requestid, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
457 |
typeid=FRAME_TYPE_TEXT_OUTPUT, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
458 |
flags=0, |
37319
36d17f37db91
wireproto: convert human output frames to CBOR
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37299
diff
changeset
|
459 |
payload=payload) |
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
460 |
|
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
461 |
class stream(object): |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
462 |
"""Represents a logical unidirectional series of frames.""" |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
463 |
|
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
464 |
def __init__(self, streamid, active=False): |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
465 |
self.streamid = streamid |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
466 |
self._active = False |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
467 |
|
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
468 |
def makeframe(self, requestid, typeid, flags, payload): |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
469 |
"""Create a frame to be sent out over this stream. |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
470 |
|
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
471 |
Only returns the frame instance. Does not actually send it. |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
472 |
""" |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
473 |
streamflags = 0 |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
474 |
if not self._active: |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
475 |
streamflags |= STREAM_FLAG_BEGIN_STREAM |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
476 |
self._active = True |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
477 |
|
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
478 |
return makeframe(requestid, self.streamid, streamflags, typeid, flags, |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
479 |
payload) |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
480 |
|
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
481 |
def ensureserverstream(stream): |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
482 |
if stream.streamid % 2: |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
483 |
raise error.ProgrammingError('server should only write to even ' |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
484 |
'numbered streams; %d is not even' % |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
485 |
stream.streamid) |
37060
0a6c5cc09a88
wireproto: define human output side channel frame
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37058
diff
changeset
|
486 |
|
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
487 |
class serverreactor(object): |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
488 |
"""Holds state of a server handling frame-based protocol requests. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
489 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
490 |
This class is the "brain" of the unified frame-based protocol server |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
491 |
component. While the protocol is stateless from the perspective of |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
492 |
requests/commands, something needs to track which frames have been |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
493 |
received, what frames to expect, etc. This class is that thing. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
494 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
495 |
Instances are modeled as a state machine of sorts. Instances are also |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
496 |
reactionary to external events. The point of this class is to encapsulate |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
497 |
the state of the connection and the exchange of frames, not to perform |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
498 |
work. Instead, callers tell this class when something occurs, like a |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
499 |
frame arriving. If that activity is worthy of a follow-up action (say |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
500 |
*run a command*), the return value of that handler will say so. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
501 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
502 |
I/O and CPU intensive operations are purposefully delegated outside of |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
503 |
this class. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
504 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
505 |
Consumers are expected to tell instances when events occur. They do so by |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
506 |
calling the various ``on*`` methods. These methods return a 2-tuple |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
507 |
describing any follow-up action(s) to take. The first element is the |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
508 |
name of an action to perform. The second is a data structure (usually |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
509 |
a dict) specific to that action that contains more information. e.g. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
510 |
if the server wants to send frames back to the client, the data structure |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
511 |
will contain a reference to those frames. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
512 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
513 |
Valid actions that consumers can be instructed to take are: |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
514 |
|
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
515 |
sendframes |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
516 |
Indicates that frames should be sent to the client. The ``framegen`` |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
517 |
key contains a generator of frames that should be sent. The server |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
518 |
assumes that all frames are sent to the client. |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
519 |
|
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
520 |
error |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
521 |
Indicates that an error occurred. Consumer should probably abort. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
522 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
523 |
runcommand |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
524 |
Indicates that the consumer should run a wire protocol command. Details |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
525 |
of the command to run are given in the data structure. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
526 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
527 |
wantframe |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
528 |
Indicates that nothing of interest happened and the server is waiting on |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
529 |
more frames from the client before anything interesting can be done. |
37056
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
530 |
|
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
531 |
noop |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
532 |
Indicates no additional action is required. |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
533 |
|
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
534 |
Known Issues |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
535 |
------------ |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
536 |
|
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
537 |
There are no limits to the number of partially received commands or their |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
538 |
size. A malicious client could stream command request data and exhaust the |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
539 |
server's memory. |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
540 |
|
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
541 |
Partially received commands are not acted upon when end of input is |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
542 |
reached. Should the server error if it receives a partial request? |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
543 |
Should the client send a message to abort a partially transmitted request |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
544 |
to facilitate graceful shutdown? |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
545 |
|
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
546 |
Active requests that haven't been responded to aren't tracked. This means |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
547 |
that if we receive a command and instruct its dispatch, another command |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
548 |
with its request ID can come in over the wire and there will be a race |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
549 |
between who responds to what. |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
550 |
""" |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
551 |
|
37056
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
552 |
def __init__(self, deferoutput=False): |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
553 |
"""Construct a new server reactor. |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
554 |
|
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
555 |
``deferoutput`` can be used to indicate that no output frames should be |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
556 |
instructed to be sent until input has been exhausted. In this mode, |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
557 |
events that would normally generate output frames (such as a command |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
558 |
response being ready) will instead defer instructing the consumer to |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
559 |
send those frames. This is useful for half-duplex transports where the |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
560 |
sender cannot receive until all data has been transmitted. |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
561 |
""" |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
562 |
self._deferoutput = deferoutput |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
563 |
self._state = 'idle' |
37289
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
564 |
self._nextoutgoingstreamid = 2 |
37056
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
565 |
self._bufferedframegens = [] |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
566 |
# stream id -> stream instance for all active streams from the client. |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
567 |
self._incomingstreams = {} |
37289
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
568 |
self._outgoingstreams = {} |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
569 |
# request id -> dict of commands that are actively being received. |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
570 |
self._receivingcommands = {} |
37063
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
571 |
# Request IDs that have been received and are actively being processed. |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
572 |
# Once all output for a request has been sent, it is removed from this |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
573 |
# set. |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
574 |
self._activecommands = set() |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
575 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
576 |
def onframerecv(self, frame): |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
577 |
"""Process a frame that has been received off the wire. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
578 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
579 |
Returns a dict with an ``action`` key that details what action, |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
580 |
if any, the consumer should take next. |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
581 |
""" |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
582 |
if not frame.streamid % 2: |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
583 |
self._state = 'errored' |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
584 |
return self._makeerrorresult( |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
585 |
_('received frame with even numbered stream ID: %d') % |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
586 |
frame.streamid) |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
587 |
|
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
588 |
if frame.streamid not in self._incomingstreams: |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
589 |
if not frame.streamflags & STREAM_FLAG_BEGIN_STREAM: |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
590 |
self._state = 'errored' |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
591 |
return self._makeerrorresult( |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
592 |
_('received frame on unknown inactive stream without ' |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
593 |
'beginning of stream flag set')) |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
594 |
|
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
595 |
self._incomingstreams[frame.streamid] = stream(frame.streamid) |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
596 |
|
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
597 |
if frame.streamflags & STREAM_FLAG_ENCODING_APPLIED: |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
598 |
# TODO handle decoding frames |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
599 |
self._state = 'errored' |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
600 |
raise error.ProgrammingError('support for decoding stream payloads ' |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
601 |
'not yet implemented') |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
602 |
|
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
603 |
if frame.streamflags & STREAM_FLAG_END_STREAM: |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
604 |
del self._incomingstreams[frame.streamid] |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
605 |
|
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
606 |
handlers = { |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
607 |
'idle': self._onframeidle, |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
608 |
'command-receiving': self._onframecommandreceiving, |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
609 |
'errored': self._onframeerrored, |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
610 |
} |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
611 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
612 |
meth = handlers.get(self._state) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
613 |
if not meth: |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
614 |
raise error.ProgrammingError('unhandled state: %s' % self._state) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
615 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
616 |
return meth(frame) |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
617 |
|
37485
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
618 |
def onbytesresponseready(self, stream, requestid, data, iscbor=False): |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
619 |
"""Signal that a bytes response is ready to be sent to the client. |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
620 |
|
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
621 |
The raw bytes response is passed as an argument. |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
622 |
""" |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
623 |
ensureserverstream(stream) |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
624 |
|
37063
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
625 |
def sendframes(): |
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
626 |
for frame in createbytesresponseframesfrombytes(stream, requestid, |
37485
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
627 |
data, |
0b7475ea38cf
wireproto: port heads command to wire protocol v2
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
628 |
iscbor=iscbor): |
37063
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
629 |
yield frame |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
630 |
|
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
631 |
self._activecommands.remove(requestid) |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
632 |
|
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
633 |
result = sendframes() |
37056
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
634 |
|
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
635 |
if self._deferoutput: |
37063
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
636 |
self._bufferedframegens.append(result) |
37056
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
637 |
return 'noop', {} |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
638 |
else: |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
639 |
return 'sendframes', { |
37063
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
640 |
'framegen': result, |
37056
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
641 |
} |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
642 |
|
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
643 |
def oninputeof(self): |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
644 |
"""Signals that end of input has been received. |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
645 |
|
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
646 |
No more frames will be received. All pending activity should be |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
647 |
completed. |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
648 |
""" |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
649 |
# TODO should we do anything about in-flight commands? |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
650 |
|
37056
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
651 |
if not self._deferoutput or not self._bufferedframegens: |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
652 |
return 'noop', {} |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
653 |
|
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
654 |
# If we buffered all our responses, emit those. |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
655 |
def makegen(): |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
656 |
for gen in self._bufferedframegens: |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
657 |
for frame in gen: |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
658 |
yield frame |
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
659 |
|
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
660 |
return 'sendframes', { |
37056
861e9d37e56e
wireproto: buffer output frames when in half duplex mode
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37055
diff
changeset
|
661 |
'framegen': makegen(), |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
662 |
} |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
663 |
|
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
664 |
def onapplicationerror(self, stream, requestid, msg): |
37288
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
665 |
ensureserverstream(stream) |
9bfcbe4f4745
wireproto: add streams to frame-based protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37285
diff
changeset
|
666 |
|
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
667 |
return 'sendframes', { |
37285
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
668 |
'framegen': createerrorframe(stream, requestid, msg, |
3ed344546d9e
wireproto: start to associate frame generation with a stream
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37084
diff
changeset
|
669 |
application=True), |
37055
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
670 |
} |
61393f888dfe
wireproto: define and implement responses in framing protocol
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37052
diff
changeset
|
671 |
|
37289
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
672 |
def makeoutputstream(self): |
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
673 |
"""Create a stream to be used for sending data to the client.""" |
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
674 |
streamid = self._nextoutgoingstreamid |
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
675 |
self._nextoutgoingstreamid += 2 |
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
676 |
|
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
677 |
s = stream(streamid) |
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
678 |
self._outgoingstreams[streamid] = s |
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
679 |
|
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
680 |
return s |
5fadc63ac99f
wireproto: explicit API to create outgoing streams
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37288
diff
changeset
|
681 |
|
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
682 |
def _makeerrorresult(self, msg): |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
683 |
return 'error', { |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
684 |
'message': msg, |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
685 |
} |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
686 |
|
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
687 |
def _makeruncommandresult(self, requestid): |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
688 |
entry = self._receivingcommands[requestid] |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
689 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
690 |
if not entry['requestdone']: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
691 |
self._state = 'errored' |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
692 |
raise error.ProgrammingError('should not be called without ' |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
693 |
'requestdone set') |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
694 |
|
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
695 |
del self._receivingcommands[requestid] |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
696 |
|
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
697 |
if self._receivingcommands: |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
698 |
self._state = 'command-receiving' |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
699 |
else: |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
700 |
self._state = 'idle' |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
701 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
702 |
# Decode the payloads as CBOR. |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
703 |
entry['payload'].seek(0) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
704 |
request = cbor.load(entry['payload']) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
705 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
706 |
if b'name' not in request: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
707 |
self._state = 'errored' |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
708 |
return self._makeerrorresult( |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
709 |
_('command request missing "name" field')) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
710 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
711 |
if b'args' not in request: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
712 |
request[b'args'] = {} |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
713 |
|
37063
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
714 |
assert requestid not in self._activecommands |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
715 |
self._activecommands.add(requestid) |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
716 |
|
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
717 |
return 'runcommand', { |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
718 |
'requestid': requestid, |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
719 |
'command': request[b'name'], |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
720 |
'args': request[b'args'], |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
721 |
'data': entry['data'].getvalue() if entry['data'] else None, |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
722 |
} |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
723 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
724 |
def _makewantframeresult(self): |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
725 |
return 'wantframe', { |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
726 |
'state': self._state, |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
727 |
} |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
728 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
729 |
def _validatecommandrequestframe(self, frame): |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
730 |
new = frame.flags & FLAG_COMMAND_REQUEST_NEW |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
731 |
continuation = frame.flags & FLAG_COMMAND_REQUEST_CONTINUATION |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
732 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
733 |
if new and continuation: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
734 |
self._state = 'errored' |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
735 |
return self._makeerrorresult( |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
736 |
_('received command request frame with both new and ' |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
737 |
'continuation flags set')) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
738 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
739 |
if not new and not continuation: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
740 |
self._state = 'errored' |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
741 |
return self._makeerrorresult( |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
742 |
_('received command request frame with neither new nor ' |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
743 |
'continuation flags set')) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
744 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
745 |
def _onframeidle(self, frame): |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
746 |
# The only frame type that should be received in this state is a |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
747 |
# command request. |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
748 |
if frame.typeid != FRAME_TYPE_COMMAND_REQUEST: |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
749 |
self._state = 'errored' |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
750 |
return self._makeerrorresult( |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
751 |
_('expected command request frame; got %d') % frame.typeid) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
752 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
753 |
res = self._validatecommandrequestframe(frame) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
754 |
if res: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
755 |
return res |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
756 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
757 |
if frame.requestid in self._receivingcommands: |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
758 |
self._state = 'errored' |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
759 |
return self._makeerrorresult( |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
760 |
_('request with ID %d already received') % frame.requestid) |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
761 |
|
37063
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
762 |
if frame.requestid in self._activecommands: |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
763 |
self._state = 'errored' |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
764 |
return self._makeerrorresult( |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
765 |
_('request with ID %d is already active') % frame.requestid) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
766 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
767 |
new = frame.flags & FLAG_COMMAND_REQUEST_NEW |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
768 |
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
|
769 |
expectingdata = frame.flags & FLAG_COMMAND_REQUEST_EXPECT_DATA |
37063
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
770 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
771 |
if not new: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
772 |
self._state = 'errored' |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
773 |
return self._makeerrorresult( |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
774 |
_('received command request frame without new flag set')) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
775 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
776 |
payload = util.bytesio() |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
777 |
payload.write(frame.payload) |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
778 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
779 |
self._receivingcommands[frame.requestid] = { |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
780 |
'payload': payload, |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
781 |
'data': None, |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
782 |
'requestdone': not moreframes, |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
783 |
'expectingdata': bool(expectingdata), |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
784 |
} |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
785 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
786 |
# 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
|
787 |
if not moreframes and not expectingdata: |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
788 |
return self._makeruncommandresult(frame.requestid) |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
789 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
790 |
assert moreframes or expectingdata |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
791 |
self._state = 'command-receiving' |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
792 |
return self._makewantframeresult() |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
793 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
794 |
def _onframecommandreceiving(self, frame): |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
795 |
if frame.typeid == FRAME_TYPE_COMMAND_REQUEST: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
796 |
# Process new command requests as such. |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
797 |
if frame.flags & FLAG_COMMAND_REQUEST_NEW: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
798 |
return self._onframeidle(frame) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
799 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
800 |
res = self._validatecommandrequestframe(frame) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
801 |
if res: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
802 |
return res |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
803 |
|
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
804 |
# All other frames should be related to a command that is currently |
37063
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
805 |
# receiving but is not active. |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
806 |
if frame.requestid in self._activecommands: |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
807 |
self._state = 'errored' |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
808 |
return self._makeerrorresult( |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
809 |
_('received frame for request that is still active: %d') % |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
810 |
frame.requestid) |
39304dd63589
wireproto: explicitly track which requests are active
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37062
diff
changeset
|
811 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
812 |
if frame.requestid not in self._receivingcommands: |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
813 |
self._state = 'errored' |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
814 |
return self._makeerrorresult( |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
815 |
_('received frame for request that is not receiving: %d') % |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
816 |
frame.requestid) |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
817 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
818 |
entry = self._receivingcommands[frame.requestid] |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
819 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
820 |
if frame.typeid == FRAME_TYPE_COMMAND_REQUEST: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
821 |
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
|
822 |
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
|
823 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
824 |
if entry['requestdone']: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
825 |
self._state = 'errored' |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
826 |
return self._makeerrorresult( |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
827 |
_('received command request frame when request frames ' |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
828 |
'were supposedly done')) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
829 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
830 |
if expectingdata != entry['expectingdata']: |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
831 |
self._state = 'errored' |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
832 |
return self._makeerrorresult( |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
833 |
_('mismatch between expect data flag and previous frame')) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
834 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
835 |
entry['payload'].write(frame.payload) |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
836 |
|
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
837 |
if not moreframes: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
838 |
entry['requestdone'] = True |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
839 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
840 |
if not moreframes and not expectingdata: |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
841 |
return self._makeruncommandresult(frame.requestid) |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
842 |
|
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
843 |
return self._makewantframeresult() |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
844 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
845 |
elif frame.typeid == FRAME_TYPE_COMMAND_DATA: |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
846 |
if not entry['expectingdata']: |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
847 |
self._state = 'errored' |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
848 |
return self._makeerrorresult(_( |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
849 |
'received command data frame for request that is not ' |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
850 |
'expecting data: %d') % frame.requestid) |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
851 |
|
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
852 |
if entry['data'] is None: |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
853 |
entry['data'] = util.bytesio() |
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
854 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
855 |
return self._handlecommanddataframe(frame, entry) |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
856 |
else: |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
857 |
self._state = 'errored' |
37292
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
858 |
return self._makeerrorresult(_( |
3d0e2cd86e05
wireproto: use CBOR for command requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37291
diff
changeset
|
859 |
'received unexpected frame type: %d') % frame.typeid) |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
860 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
861 |
def _handlecommanddataframe(self, frame, entry): |
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
862 |
assert frame.typeid == FRAME_TYPE_COMMAND_DATA |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
863 |
|
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
864 |
# TODO support streaming data instead of buffering it. |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
865 |
entry['data'].write(frame.payload) |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
866 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
867 |
if frame.flags & FLAG_COMMAND_DATA_CONTINUATION: |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
868 |
return self._makewantframeresult() |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
869 |
elif frame.flags & FLAG_COMMAND_DATA_EOS: |
37058
c5e9c3b47366
wireproto: support for receiving multiple requests
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37057
diff
changeset
|
870 |
entry['data'].seek(0) |
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
871 |
return self._makeruncommandresult(frame.requestid) |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
872 |
else: |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
873 |
self._state = 'errored' |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
874 |
return self._makeerrorresult(_('command data frame without ' |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
875 |
'flags')) |
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
876 |
|
37061
884a0c1604ad
wireproto: define attr-based classes for representing frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37060
diff
changeset
|
877 |
def _onframeerrored(self, frame): |
37052
8c3c47362934
wireproto: implement basic frame reading and processing
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37051
diff
changeset
|
878 |
return self._makeerrorresult(_('server already errored')) |