Skip to content

Commit ff5aed4

Browse files
Kriechipgjones
authored andcommitted
coverage++
1 parent 8bbc84c commit ff5aed4

File tree

9 files changed

+73
-31
lines changed

9 files changed

+73
-31
lines changed

src/wsproto/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,9 @@ def state(self) -> ConnectionState:
3636
:returns: Connection state
3737
:rtype: wsproto.connection.ConnectionState
3838
"""
39-
if self.connection is None: # noqa
39+
if self.connection is None:
4040
return self.handshake.state
41-
else:
42-
return self.connection.state
41+
return self.connection.state
4342

4443
def initiate_upgrade_connection(self, headers: Headers, path: str) -> None:
4544
self.handshake.initiate_upgrade_connection(headers, path)

src/wsproto/connection.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ def receive_data(self, data: Optional[bytes]) -> None:
132132
self._proto.receive_bytes(data)
133133
elif self.state is ConnectionState.CLOSED:
134134
raise LocalProtocolError("Connection already closed.")
135+
else:
136+
pass # pragma: no cover
135137

136138
def events(self) -> Generator[Event, None, None]:
137139
"""
@@ -179,5 +181,8 @@ def events(self) -> Generator[Event, None, None]:
179181
frame_finished=frame.frame_finished,
180182
message_finished=frame.message_finished,
181183
)
184+
185+
else:
186+
pass # pragma: no cover
182187
except ParseFailed as exc:
183188
yield CloseConnection(code=exc.code, reason=str(exc))

src/wsproto/frame_protocol.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from typing import Generator, List, NamedTuple, Optional, Tuple, TYPE_CHECKING, Union
1313

1414
if TYPE_CHECKING:
15-
from .extensions import Extension # noqa
15+
from .extensions import Extension # pragma: no cover
1616

1717

1818
_XOR_TABLE = [bytes(a ^ b for a in range(256)) for b in range(256)]
@@ -23,24 +23,23 @@ def __init__(self, masking_key: bytes) -> None:
2323
self._masking_key = masking_key
2424

2525
def process(self, data: bytes) -> bytes:
26-
if data: # pylint:disable=no-else-return
26+
if data:
2727
data_array = bytearray(data)
2828
a, b, c, d = (_XOR_TABLE[n] for n in self._masking_key)
2929
data_array[::4] = data_array[::4].translate(a)
3030
data_array[1::4] = data_array[1::4].translate(b)
3131
data_array[2::4] = data_array[2::4].translate(c)
3232
data_array[3::4] = data_array[3::4].translate(d)
3333

34-
# Rotate the maksing key so that the next usage continues
34+
# Rotate the masking key so that the next usage continues
3535
# with the next key element, rather than restarting.
3636
key_rotation = len(data) % 4
3737
self._masking_key = (
3838
self._masking_key[key_rotation:] + self._masking_key[:key_rotation]
3939
)
4040

4141
return bytes(data_array)
42-
else:
43-
return data
42+
return data
4443

4544

4645
class XorMaskerNull:
@@ -75,7 +74,7 @@ class Opcode(IntEnum):
7574
RFC 6455, Section 5.2 - Base Framing Protocol
7675
"""
7776

78-
#: Contiuation frame
77+
#: Continuation frame
7978
CONTINUATION = 0x0
8079

8180
#: Text message

src/wsproto/handshake.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ def _process_connection_request( # noqa: MC0001
224224
"Missing header, 'Sec-WebSocket-Version'",
225225
event_hint=RejectConnection(
226226
headers=[(b"Sec-WebSocket-Version", WEBSOCKET_VERSION)],
227-
status_code=426,
227+
status_code=426 if version else 400,
228228
),
229229
)
230230
if key is None:
@@ -235,10 +235,6 @@ def _process_connection_request( # noqa: MC0001
235235
raise RemoteProtocolError(
236236
"Missing header, 'Upgrade: WebSocket'", event_hint=RejectConnection()
237237
)
238-
if version is None:
239-
raise RemoteProtocolError(
240-
"Missing header, 'Sec-WebSocket-Version'", event_hint=RejectConnection()
241-
)
242238
if host is None:
243239
raise RemoteProtocolError(
244240
"Missing header, 'Host'", event_hint=RejectConnection()

test/test_client.py

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
# These tests test the behaviours expected of wsproto in when the
2-
# connection is a client.
31
from typing import List, Optional
42

53
import h11
64
import pytest
75

86
from wsproto import WSConnection
9-
from wsproto.connection import CLIENT
7+
from wsproto.connection import CLIENT, ConnectionState
108
from wsproto.events import (
119
AcceptConnection,
1210
Event,
@@ -18,6 +16,7 @@
1816
from wsproto.typing import Headers
1917
from wsproto.utilities import (
2018
generate_accept_token,
19+
LocalProtocolError,
2120
normed_header_dict,
2221
RemoteProtocolError,
2322
)
@@ -102,6 +101,42 @@ def test_connection_request_subprotocols() -> None:
102101
assert headers[b"sec-websocket-protocol"] == b"one, two"
103102

104103

104+
def test_connection_send_state() -> None:
105+
client = WSConnection(CLIENT)
106+
assert client.state is ConnectionState.CONNECTING
107+
108+
server = h11.Connection(h11.SERVER)
109+
server.receive_data(
110+
client.send(
111+
Request(
112+
host="localhost",
113+
target="/",
114+
)
115+
)
116+
)
117+
headers = normed_header_dict(server.next_event().headers)
118+
response = h11.InformationalResponse(
119+
status_code=101,
120+
headers=[
121+
(b"connection", b"Upgrade"),
122+
(b"upgrade", b"WebSocket"),
123+
(
124+
b"Sec-WebSocket-Accept",
125+
generate_accept_token(headers[b"sec-websocket-key"]),
126+
),
127+
],
128+
)
129+
client.receive_data(server.send(response))
130+
assert len(list(client.events())) == 1
131+
assert client.state is ConnectionState.OPEN # type: ignore # https://github.com/python/mypy/issues/9005
132+
133+
with pytest.raises(LocalProtocolError) as excinfo:
134+
client.send(Request(host="localhost", target="/"))
135+
136+
client.receive_data(b"foobar")
137+
assert len(list(client.events())) == 1
138+
139+
105140
def _make_handshake(
106141
response_status: int,
107142
response_headers: Headers,
@@ -110,6 +145,8 @@ def _make_handshake(
110145
auto_accept_key: bool = True,
111146
) -> List[Event]:
112147
client = WSConnection(CLIENT)
148+
assert client.state is ConnectionState.CONNECTING
149+
113150
server = h11.Connection(h11.SERVER)
114151
server.receive_data(
115152
client.send(
@@ -134,6 +171,7 @@ def _make_handshake(
134171
status_code=response_status, headers=response_headers
135172
)
136173
client.receive_data(server.send(response))
174+
assert client.state is not ConnectionState.CONNECTING
137175

138176
return list(client.events())
139177

test/test_connection.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ def test_closure(client_sends: bool, code: CloseReason, reason: str) -> None:
6868
assert remote.state is ConnectionState.CLOSED # type: ignore[comparison-overlap]
6969
assert local.state is ConnectionState.CLOSED
7070

71+
with pytest.raises(LocalProtocolError):
72+
local.receive_data(b"foobar")
73+
7174

7275
def test_abnormal_closure() -> None:
7376
client = Connection(CLIENT)

test/test_frame_protocol.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,7 @@ def test_data_we_have_no_idea_what_to_do_with(self) -> None:
11931193

11941194
def test_xor_mask_simple() -> None:
11951195
masker = fp.XorMaskerSimple(b"1234")
1196+
assert masker.process(b"") == b""
11961197
assert masker.process(b"some very long data for masking by websocket") == (
11971198
b"B]^Q\x11DVFH\x12_[_U\x13PPFR\x14W]A\x14\\S@_X\\T\x14SK\x13CTP@[RYV@"
11981199
)

test/test_handshake.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from wsproto.connection import CLIENT, ConnectionState, SERVER
44
from wsproto.events import AcceptConnection, Ping, RejectConnection, Request
55
from wsproto.handshake import H11Handshake
6-
from wsproto.utilities import LocalProtocolError
6+
from wsproto.utilities import LocalProtocolError, RemoteProtocolError
77

88

99
def test_successful_handshake() -> None:
@@ -19,19 +19,22 @@ def test_successful_handshake() -> None:
1919
assert client.state is ConnectionState.OPEN
2020
assert server.state is ConnectionState.OPEN
2121

22+
assert repr(client) == "H11Handshake(client=True, state=ConnectionState.OPEN)"
23+
assert repr(server) == "H11Handshake(client=False, state=ConnectionState.OPEN)"
2224

23-
def test_rejected_handshake() -> None:
24-
client = H11Handshake(CLIENT)
25-
server = H11Handshake(SERVER)
2625

27-
server.receive_data(client.send(Request(host="localhost", target="/")))
28-
assert isinstance(next(server.events()), Request)
29-
30-
client.receive_data(server.send(RejectConnection()))
31-
assert isinstance(next(client.events()), RejectConnection)
32-
33-
assert client.state is ConnectionState.CLOSED
34-
assert server.state is ConnectionState.CLOSED
26+
@pytest.mark.parametrize("http", [b"HTTP/1.0", b"HTTP/1.1"])
27+
def test_rejected_handshake(http: bytes) -> None:
28+
server = H11Handshake(SERVER)
29+
with pytest.raises(RemoteProtocolError):
30+
server.receive_data(
31+
b"GET / " + http + b"\r\n"
32+
b"Upgrade: WebSocket\r\n"
33+
b"Connection: Upgrade\r\n"
34+
b"Sec-WebSocket-Key: VQr8cvwwZ1fEk62PDq8J3A==\r\n"
35+
b"Sec-WebSocket-Version: 13\r\n"
36+
b"\r\n"
37+
)
3538

3639

3740
def test_initiate_upgrade_as_client() -> None:

test/test_server.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# These tests test the behaviours expected of wsproto in when the
2-
# connection is a server.
31
from typing import cast, List, Optional, Tuple
42

53
import h11

0 commit comments

Comments
 (0)