Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
4f580d89
Commit
4f580d89
authored
May 29, 2023
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix handling of fragmented WebSocket frames
(cherry picked from commit
0082cea1
)
parent
571c4d19
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
37 additions
and
7 deletions
+37
-7
libcaf_net/caf/detail/rfc6455.hpp
libcaf_net/caf/detail/rfc6455.hpp
+4
-1
libcaf_net/caf/net/web_socket/framing.hpp
libcaf_net/caf/net/web_socket/framing.hpp
+6
-1
libcaf_net/src/detail/rfc6455.cpp
libcaf_net/src/detail/rfc6455.cpp
+4
-3
libcaf_net/test/net/web_socket/server.cpp
libcaf_net/test/net/web_socket/server.cpp
+23
-2
No files found.
libcaf_net/caf/detail/rfc6455.hpp
View file @
4f580d89
...
...
@@ -39,6 +39,8 @@ struct CAF_NET_EXPORT rfc6455 {
static
constexpr
uint8_t
pong
=
0x0A
;
static
constexpr
uint8_t
fin_flag
=
0x80
;
// -- utility functions ------------------------------------------------------
static
void
mask_data
(
uint32_t
key
,
span
<
char
>
data
);
...
...
@@ -52,7 +54,8 @@ struct CAF_NET_EXPORT rfc6455 {
binary_buffer
&
out
);
static
void
assemble_frame
(
uint8_t
opcode
,
uint32_t
mask_key
,
span
<
const
byte
>
data
,
binary_buffer
&
out
);
span
<
const
byte
>
data
,
binary_buffer
&
out
,
uint8_t
flags
=
fin_flag
);
static
ptrdiff_t
decode_header
(
span
<
const
byte
>
data
,
header
&
hdr
);
};
...
...
libcaf_net/caf/net/web_socket/framing.hpp
View file @
4f580d89
...
...
@@ -238,7 +238,7 @@ public:
// End of fragmented input.
payload_buf_
.
insert
(
payload_buf_
.
end
(),
payload
.
begin
(),
payload
.
end
());
if
(
!
handle
(
down
,
hdr
.
opcode
,
payload_buf_
))
if
(
!
handle
(
down
,
opcode_
,
payload_buf_
))
return
-
1
;
opcode_
=
nil_code
;
payload_buf_
.
clear
();
...
...
@@ -254,6 +254,11 @@ public:
return
-
1
;
}
opcode_
=
hdr
.
opcode
;
}
else
if
(
hdr
.
opcode
!=
detail
::
rfc6455
::
continuation_frame
)
{
CAF_LOG_DEBUG
(
"expected a continuation frame"
);
down
->
abort_reason
(
make_error
(
sec
::
protocol_error
,
//
"expected a continuation frame"
));
return
-
1
;
}
else
if
(
payload_buf_
.
size
()
+
payload_len
>
max_frame_size
)
{
// Reject assembled payloads that exceed max_frame_size.
auto
err
=
make_error
(
sec
::
runtime_error
,
...
...
libcaf_net/src/detail/rfc6455.cpp
View file @
4f580d89
...
...
@@ -37,9 +37,10 @@ void rfc6455::assemble_frame(uint32_t mask_key, span<const byte> data,
}
void
rfc6455
::
assemble_frame
(
uint8_t
opcode
,
uint32_t
mask_key
,
span
<
const
byte
>
data
,
binary_buffer
&
out
)
{
// First 8 bits: FIN flag + opcode (we never fragment frames).
out
.
push_back
(
byte
{
static_cast
<
uint8_t
>
(
0x80
|
opcode
)});
span
<
const
byte
>
data
,
binary_buffer
&
out
,
uint8_t
flags
)
{
// First 8 bits: flags + opcode
out
.
push_back
(
byte
{
static_cast
<
uint8_t
>
(
flags
|
opcode
)});
// Mask flag + payload length (7 bits, 7+16 bits, or 7+64 bits)
auto
mask_bit
=
byte
{
static_cast
<
uint8_t
>
(
mask_key
==
0
?
0x00
:
0x80
)};
if
(
data
.
size
()
<
126
)
{
...
...
libcaf_net/test/net/web_socket/server.cpp
View file @
4f580d89
...
...
@@ -74,11 +74,17 @@ struct fixture : host_fixture {
}
void
rfc6455_append
(
uint8_t
opcode
,
span
<
const
byte
>
bytes
,
std
::
vector
<
byte
>&
out
)
{
std
::
vector
<
byte
>&
out
,
uint8_t
flags
=
detail
::
rfc6455
::
fin_flag
)
{
std
::
vector
<
byte
>
payload
{
bytes
.
begin
(),
bytes
.
end
()};
auto
key
=
static_cast
<
uint32_t
>
(
rng
());
detail
::
rfc6455
::
mask_data
(
key
,
payload
);
detail
::
rfc6455
::
assemble_frame
(
opcode
,
key
,
payload
,
out
);
detail
::
rfc6455
::
assemble_frame
(
opcode
,
key
,
payload
,
out
,
flags
);
}
void
rfc6455_append
(
uint8_t
opcode
,
std
::
string_view
text
,
byte_buffer
&
out
,
uint8_t
flags
=
detail
::
rfc6455
::
fin_flag
)
{
rfc6455_append
(
opcode
,
as_bytes
(
make_span
(
text
)),
out
,
flags
);
}
void
rfc6455_append
(
span
<
const
byte
>
bytes
,
std
::
vector
<
byte
>&
out
)
{
...
...
@@ -213,4 +219,19 @@ CAF_TEST(data may arrive later) {
CAF_CHECK_EQUAL
(
app
->
text_input
,
"Hello WebSocket!
\n
Bye WebSocket!
\n
"
);
}
CAF_TEST
(
data
may
arrive
fragmented
)
{
transport
->
push
(
opening_handshake
);
CHECK_EQ
(
transport
->
handle_input
(),
static_cast
<
ptrdiff_t
>
(
opening_handshake
.
size
()));
byte_buffer
buf
;
rfc6455_append
(
detail
::
rfc6455
::
text_frame
,
"Hello "
sv
,
buf
,
0
);
rfc6455_append
(
detail
::
rfc6455
::
continuation_frame
,
"WebSocket!
\n
"
sv
,
buf
);
rfc6455_append
(
detail
::
rfc6455
::
text_frame
,
"Bye "
sv
,
buf
,
0
);
rfc6455_append
(
detail
::
rfc6455
::
continuation_frame
,
"Web"
sv
,
buf
,
0
);
rfc6455_append
(
detail
::
rfc6455
::
continuation_frame
,
"Socket!
\n
"
sv
,
buf
);
transport
->
push
(
buf
);
CHECK_EQ
(
transport
->
handle_input
(),
static_cast
<
ptrdiff_t
>
(
buf
.
size
()));
CHECK_EQ
(
app
->
text_input
,
"Hello WebSocket!
\n
Bye WebSocket!
\n
"
);
}
CAF_TEST_FIXTURE_SCOPE_END
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment