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
c0663ea7
Commit
c0663ea7
authored
Mar 15, 2023
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplify client_config scaffolding
parent
5310b68e
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
356 additions
and
430 deletions
+356
-430
libcaf_core/caf/defaults.hpp
libcaf_core/caf/defaults.hpp
+6
-0
libcaf_net/caf/net/dsl/client_config.hpp
libcaf_net/caf/net/dsl/client_config.hpp
+144
-253
libcaf_net/caf/net/dsl/client_factory_base.hpp
libcaf_net/caf/net/dsl/client_factory_base.hpp
+8
-12
libcaf_net/caf/net/dsl/fwd.hpp
libcaf_net/caf/net/dsl/fwd.hpp
+0
-26
libcaf_net/caf/net/dsl/has_connect.hpp
libcaf_net/caf/net/dsl/has_connect.hpp
+5
-5
libcaf_net/caf/net/dsl/has_uri_connect.hpp
libcaf_net/caf/net/dsl/has_uri_connect.hpp
+4
-4
libcaf_net/caf/net/lp/client_factory.hpp
libcaf_net/caf/net/lp/client_factory.hpp
+37
-55
libcaf_net/caf/net/lp/with.hpp
libcaf_net/caf/net/lp/with.hpp
+2
-2
libcaf_net/caf/net/ssl/tls.hpp
libcaf_net/caf/net/ssl/tls.hpp
+1
-1
libcaf_net/caf/net/tcp_stream_socket.hpp
libcaf_net/caf/net/tcp_stream_socket.hpp
+8
-0
libcaf_net/caf/net/web_socket/client_factory.hpp
libcaf_net/caf/net/web_socket/client_factory.hpp
+104
-70
libcaf_net/caf/net/web_socket/handshake.hpp
libcaf_net/caf/net/web_socket/handshake.hpp
+10
-0
libcaf_net/caf/net/web_socket/with.hpp
libcaf_net/caf/net/web_socket/with.hpp
+1
-1
libcaf_net/src/net/socket_manager.cpp
libcaf_net/src/net/socket_manager.cpp
+3
-0
libcaf_net/src/net/tcp_stream_socket.cpp
libcaf_net/src/net/tcp_stream_socket.cpp
+22
-0
libcaf_net/src/net/web_socket/handshake.cpp
libcaf_net/src/net/web_socket/handshake.cpp
+1
-1
No files found.
libcaf_core/caf/defaults.hpp
View file @
c0663ea7
...
@@ -154,4 +154,10 @@ namespace caf::defaults::net {
...
@@ -154,4 +154,10 @@ namespace caf::defaults::net {
/// previous connection has been closed.
/// previous connection has been closed.
constexpr
auto
max_connections
=
make_parameter
(
"max-connections"
,
size_t
{
64
});
constexpr
auto
max_connections
=
make_parameter
(
"max-connections"
,
size_t
{
64
});
/// The default port for HTTP servers.
constexpr
uint16_t
http_default_port
=
80
;
/// The default port for HTTPS servers.
constexpr
uint16_t
https_default_port
=
443
;
}
// namespace caf::defaults::net
}
// namespace caf::defaults::net
libcaf_net/caf/net/dsl/client_config.hpp
View file @
c0663ea7
...
@@ -9,7 +9,6 @@
...
@@ -9,7 +9,6 @@
#include "caf/intrusive_ptr.hpp"
#include "caf/intrusive_ptr.hpp"
#include "caf/net/dsl/base.hpp"
#include "caf/net/dsl/base.hpp"
#include "caf/net/dsl/config_base.hpp"
#include "caf/net/dsl/config_base.hpp"
#include "caf/net/dsl/fwd.hpp"
#include "caf/net/fwd.hpp"
#include "caf/net/fwd.hpp"
#include "caf/net/ssl/connection.hpp"
#include "caf/net/ssl/connection.hpp"
#include "caf/net/ssl/context.hpp"
#include "caf/net/ssl/context.hpp"
...
@@ -22,81 +21,12 @@
...
@@ -22,81 +21,12 @@
namespace
caf
::
net
::
dsl
{
namespace
caf
::
net
::
dsl
{
/// The server config type enum class.
/// Meta programming utility.
enum
class
client_config_type
{
lazy
,
socket
,
conn
,
fail
};
/// Meta programming utility for `as_base_ptr()`.
struct
client_config_tag
{};
/// Meta programming utility for `client_config<Base>::make()`.
template
<
class
T
>
template
<
class
T
>
struct
client_config_token
{};
struct
client_config_tag
{};
/// Base class for client configuration objects.
template
<
class
Base
>
class
client_config
:
public
Base
,
public
client_config_tag
{
public:
friend
class
lazy_client_config
<
Base
>
;
friend
class
socket_client_config
<
Base
>
;
friend
class
conn_client_config
<
Base
>
;
friend
class
fail_client_config
<
Base
>
;
using
lazy
=
lazy_client_config
<
Base
>
;
using
socket
=
socket_client_config
<
Base
>
;
using
conn
=
conn_client_config
<
Base
>
;
using
fail
=
fail_client_config
<
Base
>
;
/// Anchor type for meta programming.
using
base_type
=
client_config
;
client_config
(
client_config
&&
)
=
default
;
client_config
(
const
client_config
&
)
=
default
;
/// Virtual destructor.
virtual
~
client_config
()
=
default
;
/// Returns the server configuration type.
virtual
client_config_type
type
()
const
noexcept
=
0
;
template
<
class
Token
,
class
...
Ts
>
static
auto
make
(
client_config_token
<
Token
>
,
Ts
&&
...
xs
);
private:
/// Private constructor to enforce sealing.
template
<
class
...
Ts
>
explicit
client_config
(
multiplexer
*
mpx
,
Ts
&&
...
xs
)
:
Base
(
mpx
,
std
::
forward
<
Ts
>
(
xs
)...)
{
// nop
}
};
#define CAF_NET_DSL_ADD_CLIENT_TOKEN(type) \
struct client_config_bind_##type { \
template <class Base> \
using bind = typename client_config<Base>::type; \
}; \
static constexpr auto client_config_##type##_v \
= client_config_token<client_config_bind_##type> {}
/// Compile-time constant for `client_config::lazy`.
CAF_NET_DSL_ADD_CLIENT_TOKEN
(
lazy
);
/// Compile-time constant for `client_config::socket`.
CAF_NET_DSL_ADD_CLIENT_TOKEN
(
socket
);
/// Compile-time constant for `client_config::conn`.
CAF_NET_DSL_ADD_CLIENT_TOKEN
(
conn
);
/// Compile-time constant for `client_config::fail`.
CAF_NET_DSL_ADD_CLIENT_TOKEN
(
fail
);
/// Intrusive pointer type for server configurations.
template
<
class
Base
>
using
client_config_ptr
=
intrusive_ptr
<
client_config
<
Base
>>
;
/// Simple type for storing host and port information for reaching a server.
/// Simple type for storing host and port information for reaching a server.
struct
client_config_
server_address
{
struct
server_address
{
/// The host name or IP address of the host.
/// The host name or IP address of the host.
std
::
string
host
;
std
::
string
host
;
...
@@ -104,35 +34,22 @@ struct client_config_server_address {
...
@@ -104,35 +34,22 @@ struct client_config_server_address {
uint16_t
port
;
uint16_t
port
;
};
};
/// Configuration for a client that creates the socket on demand.
class
client_config
{
template
<
class
Base
>
class
lazy_client_config
final
:
public
client_config
<
Base
>
{
public:
public:
static
constexpr
auto
type_token
=
client_config_type
::
lazy
;
/// Configuration for a client that creates the socket on demand.
class
lazy
{
using
super
=
client_config
<
Base
>
;
public:
/// Type for holding a client address.
using
server_t
=
std
::
variant
<
server_address
,
uri
>
;
template
<
class
...
Ts
>
lazy
(
std
::
string
host
,
uint16_t
port
)
{
lazy_client_config
(
std
::
string
host
,
uint16_t
port
,
multiplexer
*
mpx
,
server
=
server_address
{
std
::
move
(
host
),
port
};
Ts
&&
...
xs
)
:
super
(
mpx
,
std
::
forward
<
Ts
>
(
xs
)...)
{
server
=
client_config_server_address
{
std
::
move
(
host
),
port
};
}
}
template
<
class
...
Ts
>
explicit
lazy
(
uri
addr
)
{
lazy_client_config
(
const
uri
&
addr
,
multiplexer
*
mpx
,
Ts
&&
...
xs
)
:
super
(
mpx
,
std
::
forward
<
Ts
>
(
xs
)...)
{
server
=
addr
;
server
=
addr
;
}
}
/// Returns the server configuration type.
client_config_type
type
()
const
noexcept
override
{
return
type_token
;
}
/// Type for holding a client address.
using
server_t
=
std
::
variant
<
client_config_server_address
,
uri
>
;
/// The address for reaching the server or an error.
/// The address for reaching the server or an error.
server_t
server
;
server_t
server
;
...
@@ -147,30 +64,54 @@ public:
...
@@ -147,30 +64,54 @@ public:
/// The maximum amount of retries.
/// The maximum amount of retries.
size_t
max_retry_count
=
0
;
size_t
max_retry_count
=
0
;
};
/// Configuration for a client that uses a user-provided socket.
/// Returns a function that, when called with a @ref stream_socket, calls
template
<
class
Base
>
/// `f` either with a new SSL connection from `ctx` or with the file the
class
socket_client_config
final
:
public
client_config
<
Base
>
{
/// file descriptor if no SSL context is defined.
public:
template
<
class
F
>
static
constexpr
auto
type_token
=
client_config_type
::
socket
;
auto
with_ctx
(
F
&&
f
)
{
return
[
this
,
g
=
std
::
forward
<
F
>
(
f
)](
stream_socket
fd
)
mutable
{
using
res_t
=
decltype
(
g
(
fd
));
if
(
ctx
)
{
auto
conn
=
ctx
->
new_connection
(
fd
);
if
(
conn
)
return
g
(
*
conn
);
else
return
res_t
{
std
::
move
(
conn
.
error
())};
}
else
return
g
(
fd
);
};
}
};
static
constexpr
auto
lazy_v
=
client_config_tag
<
lazy
>
{};
/// Configuration for a client that uses a user-provided socket.
class
socket
{
public:
explicit
socket
(
stream_socket
fd
)
:
fd
(
fd
)
{
// nop
}
using
super
=
client_config
<
Base
>
;
socket
()
=
delete
;
template
<
class
...
Ts
>
socket
(
const
socket
&
)
=
delete
;
socket_client_config
(
stream_socket
fd
,
multiplexer
*
mpx
,
Ts
&&
...
xs
)
:
super
(
mpx
,
std
::
forward
<
Ts
>
(
xs
)...),
fd
(
fd
)
{
socket
&
operator
=
(
const
socket
&
)
=
delete
;
// nop
socket
(
socket
&&
other
)
noexcept
:
fd
(
other
.
fd
)
{
other
.
fd
.
id
=
invalid_socket_id
;
}
}
~
socket_client_config
()
override
{
socket
&
operator
=
(
socket
&&
other
)
noexcept
{
if
(
fd
!=
invalid_socket
)
using
std
::
swap
;
close
(
fd
);
swap
(
fd
,
other
.
fd
);
return
*
this
;
}
}
/// Returns the server configuration type.
~
socket
()
{
client_config_type
type
()
const
noexcept
override
{
if
(
fd
!=
invalid_socket
)
return
type_token
;
close
(
fd
)
;
}
}
/// The socket file descriptor to use.
/// The socket file descriptor to use.
...
@@ -186,138 +127,88 @@ public:
...
@@ -186,138 +127,88 @@ public:
fd
.
id
=
invalid_socket_id
;
fd
.
id
=
invalid_socket_id
;
return
result
;
return
result
;
}
}
};
};
/// Configuration for a client that uses an already established SSL connection.
template
<
class
Base
>
class
conn_client_config
final
:
public
client_config
<
Base
>
{
public:
static
constexpr
auto
type_token
=
client_config_type
::
conn
;
using
super
=
client_config
<
Base
>
;
static
constexpr
auto
socket_v
=
client_config_tag
<
socket
>
{}
;
template
<
class
...
Ts
>
/// Configuration for a client that uses an already established SSL
conn_client_config
(
ssl
::
connection
state
,
multiplexer
*
mpx
,
Ts
&&
...
xs
)
/// connection.
:
super
(
mpx
,
std
::
forward
<
Ts
>
(
xs
)...),
state
(
std
::
move
(
state
))
{
class
conn
{
public:
explicit
conn
(
ssl
::
connection
st
)
:
state
(
std
::
move
(
st
))
{
// nop
// nop
}
}
~
conn_client_config
()
override
{
conn
()
=
delete
;
conn
(
const
conn
&
)
=
delete
;
conn
&
operator
=
(
const
conn
&
)
=
delete
;
conn
(
conn
&&
)
noexcept
=
default
;
conn
&
operator
=
(
conn
&&
)
noexcept
=
default
;
~
conn
()
{
if
(
state
)
{
if
(
state
)
{
if
(
auto
fd
=
state
.
fd
();
fd
!=
invalid_socket
)
if
(
auto
fd
=
state
.
fd
();
fd
!=
invalid_socket
)
close
(
fd
);
close
(
fd
);
}
}
}
}
/// Returns the server configuration type.
client_config_type
type
()
const
noexcept
override
{
return
type_token
;
}
/// SSL state for the connection.
/// SSL state for the connection.
ssl
::
connection
state
;
ssl
::
connection
state
;
};
};
/// Wraps an error that occurred earlier in the setup phase.
static
constexpr
auto
conn_v
=
client_config_tag
<
conn
>
{};
template
<
class
Base
>
class
fail_client_config
final
:
public
client_config
<
Base
>
{
public:
static
constexpr
auto
type_token
=
client_config_type
::
fail
;
using
super
=
client_config
<
Base
>
;
static
constexpr
auto
fail_v
=
client_config_tag
<
error
>
{}
;
template
<
class
...
Ts
>
template
<
class
Base
>
fail_client_config
(
error
err
,
multiplexer
*
mpx
,
Ts
&&
...
xs
)
class
value
:
public
Base
{
:
super
(
mpx
,
std
::
forward
<
Ts
>
(
xs
)...),
err
(
std
::
move
(
err
))
{
public:
// nop
using
super
=
Base
;
}
fail_client_config
(
error
err
,
const
super
&
other
)
template
<
class
Trait
,
class
...
Data
>
:
super
(
other
),
err
(
std
::
move
(
err
))
{
value
(
net
::
multiplexer
*
mpx
,
Trait
trait
,
Data
&&
...
arg
)
:
super
(
mpx
,
std
::
move
(
trait
)),
data
(
std
::
forward
<
Data
>
(
arg
)...)
{
// nop
// nop
}
}
/// Returns the server configuration type.
template
<
class
...
Data
>
client_config_type
type
()
const
noexcept
override
{
explicit
value
(
const
value
&
other
,
Data
&&
...
arg
)
return
type_token
;
:
super
(
other
),
data
(
std
::
forward
<
Data
>
(
arg
)...)
{
// nop
}
}
/// The forwarded error.
std
::
variant
<
error
,
lazy
,
socket
,
conn
>
data
;
error
err
;
};
/// Calls a function object with the actual subtype of a client configuration
template
<
class
T
,
class
Trait
,
class
...
Args
>
/// and returns its result.
static
intrusive_ptr
<
value
>
make
(
client_config_tag
<
T
>
,
template
<
class
F
,
class
Base
>
net
::
multiplexer
*
mpx
,
Trait
trait
,
decltype
(
auto
)
visit
(
F
&&
f
,
client_config
<
Base
>&
cfg
)
{
Args
&&
...
args
)
{
auto
type
=
cfg
.
type
();
return
make_counted
<
value
>
(
mpx
,
std
::
move
(
trait
),
std
::
in_place_type
<
T
>
,
switch
(
cfg
.
type
())
{
std
::
forward
<
Args
>
(
args
)...);
case
client_config_type
:
:
lazy
:
return
f
(
static_cast
<
lazy_client_config
<
Base
>&>
(
cfg
));
case
client_config_type
:
:
socket
:
return
f
(
static_cast
<
socket_client_config
<
Base
>&>
(
cfg
));
case
client_config_type
:
:
conn
:
return
f
(
static_cast
<
conn_client_config
<
Base
>&>
(
cfg
));
default:
assert
(
type
==
client_config_type
::
fail
);
return
f
(
static_cast
<
fail_client_config
<
Base
>&>
(
cfg
));
}
}
}
/// Calls a function object with the actual subtype of a client configuration
template
<
class
F
>
/// and returns its result.
auto
visit
(
F
&&
f
)
{
template
<
class
F
,
class
Base
>
return
std
::
visit
([
&
](
auto
&
arg
)
{
return
f
(
arg
);
},
data
);
decltype
(
auto
)
visit
(
F
&&
f
,
const
client_config
<
Base
>&
cfg
)
{
auto
type
=
cfg
.
type
();
switch
(
cfg
.
type
())
{
case
client_config_type
:
:
lazy
:
return
f
(
static_cast
<
const
lazy_client_config
<
Base
>&>
(
cfg
));
case
client_config_type
:
:
socket
:
return
f
(
static_cast
<
const
socket_client_config
<
Base
>&>
(
cfg
));
case
client_config_type
:
:
conn
:
return
f
(
static_cast
<
const
conn_client_config
<
Base
>&>
(
cfg
));
default:
assert
(
type
==
client_config_type
::
fail
);
return
f
(
static_cast
<
const
fail_client_config
<
Base
>&>
(
cfg
));
}
}
}
};
};
/// Gets a pointer to a specific subtype of a client configuration.
template
<
class
T
,
class
Base
>
T
*
get_if
(
client_config
<
Base
>*
config
)
{
if
(
T
::
type_token
==
config
->
type
())
return
static_cast
<
T
*>
(
config
);
return
nullptr
;
}
/// Gets a pointer to a specific subtype of a client configuration.
template
<
class
T
,
class
Base
>
const
T
*
get_if
(
const
client_config
<
Base
>*
config
)
{
if
(
T
::
type_token
==
config
->
type
())
return
static_cast
<
const
T
*>
(
config
);
return
nullptr
;
}
/// Creates a `fail_client_config` from another configuration object plus error.
template
<
class
Base
>
template
<
class
Base
>
auto
to_fail_config
(
client_config_ptr
<
Base
>
ptr
,
error
err
)
{
using
client_config_value
=
client_config
::
value
<
Base
>
;
using
impl_t
=
fail_client_config
<
Base
>
;
return
make_counted
<
impl_t
>
(
std
::
move
(
err
),
*
ptr
);
}
/// Returns the pointer as a pointer to the `client_config` base type.
template
<
class
Base
>
template
<
class
T
>
using
client_config_ptr
=
intrusive_ptr
<
client_config_value
<
Base
>>
;
auto
as_base_ptr
(
intrusive_ptr
<
T
>
ptr
,
std
::
enable_if_t
<
std
::
is_base_of_v
<
client_config_tag
,
T
>>*
=
nullptr
)
{
return
std
::
move
(
ptr
).
template
upcast
<
typename
T
::
base_type
>();
}
/// Creates a `fail_client_config` from another configuration object plus error.
template
<
class
Base
>
template
<
class
Base
>
template
<
class
Token
,
class
...
Ts
>
client_config_ptr
<
Base
>
to_fail_config
(
client_config_ptr
<
Base
>
ptr
,
error
err
)
{
auto
client_config
<
Base
>::
make
(
client_config_token
<
Token
>
,
Ts
&&
...
xs
)
{
using
val_t
=
typename
client_config
::
template
value
<
Base
>;
using
type_t
=
typename
Token
::
template
bind
<
Base
>;
return
make_counted
<
val_t
>
(
*
ptr
,
std
::
move
(
err
));
return
make_counted
<
type_t
>
(
std
::
forward
<
Ts
>
(
xs
)...);
}
}
}
// namespace caf::net::dsl
}
// namespace caf::net::dsl
libcaf_net/caf/net/dsl/client_factory_base.hpp
View file @
c0663ea7
...
@@ -20,22 +20,18 @@ namespace caf::net::dsl {
...
@@ -20,22 +20,18 @@ namespace caf::net::dsl {
template
<
class
ConfigBase
,
class
Derived
>
template
<
class
ConfigBase
,
class
Derived
>
class
client_factory_base
{
class
client_factory_base
{
public:
public:
using
config_type
=
client_config
<
ConfigBase
>
;
using
config_type
=
client_config
_value
<
ConfigBase
>
;
using
trait_type
=
typename
config_type
::
trait_type
;
using
trait_type
=
typename
config_type
::
trait_type
;
using
config_pointer
=
intrusive_ptr
<
config_type
>
;
using
config_pointer
=
intrusive_ptr
<
config_type
>
;
explicit
client_factory_base
(
config_pointer
cfg
)
:
cfg_
(
std
::
move
(
cfg
))
{
// nop
}
client_factory_base
(
const
client_factory_base
&
)
=
default
;
client_factory_base
(
const
client_factory_base
&
)
=
default
;
client_factory_base
&
operator
=
(
const
client_factory_base
&
)
=
default
;
client_factory_base
&
operator
=
(
const
client_factory_base
&
)
=
default
;
template
<
class
T
,
class
...
Ts
>
template
<
class
T
,
class
...
Ts
>
explicit
client_factory_base
(
dsl
::
client_config_t
oken
<
T
>
token
,
Ts
&&
...
xs
)
{
explicit
client_factory_base
(
dsl
::
client_config_t
ag
<
T
>
token
,
Ts
&&
...
xs
)
{
cfg_
=
config_type
::
make
(
token
,
std
::
forward
<
Ts
>
(
xs
)...);
cfg_
=
config_type
::
make
(
token
,
std
::
forward
<
Ts
>
(
xs
)...);
}
}
...
@@ -52,8 +48,8 @@ public:
...
@@ -52,8 +48,8 @@ public:
/// @param value The new retry delay.
/// @param value The new retry delay.
/// @returns a reference to this `client_factory`.
/// @returns a reference to this `client_factory`.
Derived
&
retry_delay
(
timespan
value
)
{
Derived
&
retry_delay
(
timespan
value
)
{
if
(
auto
*
cfg
=
get_if
<
lazy_client_config
<
ConfigBase
>>
(
cfg_
.
get
()
))
if
(
auto
*
lazy
=
get_if
<
client_config
::
lazy
>
(
&
cfg_
->
data
))
cfg
->
retry_delay
=
value
;
lazy
->
retry_delay
=
value
;
return
dref
();
return
dref
();
}
}
...
@@ -62,8 +58,8 @@ public:
...
@@ -62,8 +58,8 @@ public:
/// @param value The new connection timeout.
/// @param value The new connection timeout.
/// @returns a reference to this `client_factory`.
/// @returns a reference to this `client_factory`.
Derived
&
connection_timeout
(
timespan
value
)
{
Derived
&
connection_timeout
(
timespan
value
)
{
if
(
auto
*
cfg
=
get_if
<
lazy_client_config
<
ConfigBase
>>
(
cfg_
.
get
()
))
if
(
auto
*
lazy
=
get_if
<
client_config
::
lazy
>
(
&
cfg_
->
data
))
cfg
->
connection_timeout
=
value
;
lazy
->
connection_timeout
=
value
;
return
dref
();
return
dref
();
}
}
...
@@ -72,8 +68,8 @@ public:
...
@@ -72,8 +68,8 @@ public:
/// @param value The new maximum retry count.
/// @param value The new maximum retry count.
/// @returns a reference to this `client_factory`.
/// @returns a reference to this `client_factory`.
Derived
&
max_retry_count
(
size_t
value
)
{
Derived
&
max_retry_count
(
size_t
value
)
{
if
(
auto
*
cfg
=
get_if
<
lazy_client_config
<
ConfigBase
>>
(
cfg_
.
get
()
))
if
(
auto
*
lazy
=
get_if
<
client_config
::
lazy
>
(
&
cfg_
->
data
))
cfg
->
max_retry_count
=
value
;
lazy
->
max_retry_count
=
value
;
return
dref
();
return
dref
();
}
}
...
...
libcaf_net/caf/net/dsl/fwd.hpp
deleted
100644 → 0
View file @
5310b68e
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#pragma once
namespace
caf
::
net
::
dsl
{
enum
class
client_config_type
;
template
<
class
Base
>
class
client_config
;
template
<
class
Base
>
class
lazy_client_config
;
template
<
class
Base
>
class
socket_client_config
;
template
<
class
Base
>
class
conn_client_config
;
template
<
class
Base
>
class
fail_client_config
;
}
// namespace caf::net::dsl
libcaf_net/caf/net/dsl/has_connect.hpp
View file @
c0663ea7
...
@@ -27,8 +27,8 @@ public:
...
@@ -27,8 +27,8 @@ public:
/// @returns a `connect_factory` object initialized with the given parameters.
/// @returns a `connect_factory` object initialized with the given parameters.
auto
connect
(
std
::
string
host
,
uint16_t
port
)
{
auto
connect
(
std
::
string
host
,
uint16_t
port
)
{
auto
&
dref
=
static_cast
<
Subtype
&>
(
*
this
);
auto
&
dref
=
static_cast
<
Subtype
&>
(
*
this
);
return
dref
.
make
(
client_config
_lazy_v
,
std
::
move
(
host
),
port
,
this
->
mpx
(),
return
dref
.
make
(
client_config
::
lazy_v
,
this
->
mpx
(),
this
->
trait
(),
this
->
trait
()
);
std
::
move
(
host
),
port
);
}
}
/// Creates a `connect_factory` object for the given stream `fd`.
/// Creates a `connect_factory` object for the given stream `fd`.
...
@@ -36,7 +36,7 @@ public:
...
@@ -36,7 +36,7 @@ public:
/// @returns a `connect_factory` object that will use the given socket.
/// @returns a `connect_factory` object that will use the given socket.
auto
connect
(
stream_socket
fd
)
{
auto
connect
(
stream_socket
fd
)
{
auto
&
dref
=
static_cast
<
Subtype
&>
(
*
this
);
auto
&
dref
=
static_cast
<
Subtype
&>
(
*
this
);
return
dref
.
make
(
client_config
_socket_v
,
fd
,
this
->
mpx
(),
this
->
trait
()
);
return
dref
.
make
(
client_config
::
socket_v
,
this
->
mpx
(),
this
->
trait
(),
fd
);
}
}
/// Creates a `connect_factory` object for the given SSL `connection`.
/// Creates a `connect_factory` object for the given SSL `connection`.
...
@@ -44,8 +44,8 @@ public:
...
@@ -44,8 +44,8 @@ public:
/// @returns a `connect_factory` object that will use the given connection.
/// @returns a `connect_factory` object that will use the given connection.
auto
connect
(
ssl
::
connection
conn
)
{
auto
connect
(
ssl
::
connection
conn
)
{
auto
&
dref
=
static_cast
<
Subtype
&>
(
*
this
);
auto
&
dref
=
static_cast
<
Subtype
&>
(
*
this
);
return
dref
.
make
(
client_config
_conn_v
,
std
::
move
(
conn
),
this
->
mpx
(),
return
dref
.
make
(
client_config
::
conn_v
,
this
->
mpx
(),
this
->
trait
(),
this
->
trait
(
));
std
::
move
(
conn
));
}
}
};
};
...
...
libcaf_net/caf/net/dsl/has_uri_connect.hpp
View file @
c0663ea7
...
@@ -31,8 +31,8 @@ public:
...
@@ -31,8 +31,8 @@ public:
/// @returns a `connect_factory` object initialized with the given parameters.
/// @returns a `connect_factory` object initialized with the given parameters.
auto
connect
(
const
uri
&
endpoint
)
{
auto
connect
(
const
uri
&
endpoint
)
{
auto
&
dref
=
static_cast
<
Subtype
&>
(
*
this
);
auto
&
dref
=
static_cast
<
Subtype
&>
(
*
this
);
return
dref
.
make
(
client_config
_lazy_v
,
endpoint
,
this
->
mpx
(),
return
dref
.
make
(
client_config
::
lazy_v
,
this
->
mpx
(),
this
->
trait
(),
this
->
trait
()
);
endpoint
);
}
}
/// Creates a `connect_factory` object for the given TCP `endpoint`.
/// Creates a `connect_factory` object for the given TCP `endpoint`.
...
@@ -43,8 +43,8 @@ public:
...
@@ -43,8 +43,8 @@ public:
if
(
endpoint
)
if
(
endpoint
)
return
connect
(
*
endpoint
);
return
connect
(
*
endpoint
);
auto
&
dref
=
static_cast
<
Subtype
&>
(
*
this
);
auto
&
dref
=
static_cast
<
Subtype
&>
(
*
this
);
return
dref
.
make
(
client_config
_fail_v
,
std
::
move
(
endpoint
.
error
()
),
return
dref
.
make
(
client_config
::
fail_v
,
this
->
mpx
(),
this
->
trait
(
),
this
->
mpx
(),
this
->
trait
(
));
std
::
move
(
endpoint
.
error
()
));
}
}
};
};
...
...
libcaf_net/caf/net/lp/client_factory.hpp
View file @
c0663ea7
...
@@ -45,6 +45,12 @@ public:
...
@@ -45,6 +45,12 @@ public:
std
::
move
(
push
));
std
::
move
(
push
));
}
}
void
abort
(
const
error
&
err
)
override
{
super
::
abort
(
err
);
if
(
push_
)
push_
.
abort
(
err
);
}
error
start
(
net
::
binary
::
lower_layer
*
down_ptr
)
override
{
error
start
(
net
::
binary
::
lower_layer
*
down_ptr
)
override
{
super
::
down_
=
down_ptr
;
super
::
down_
=
down_ptr
;
return
super
::
init
(
std
::
move
(
pull_
),
std
::
move
(
push_
));
return
super
::
init
(
std
::
move
(
pull_
),
std
::
move
(
push_
));
...
@@ -75,39 +81,21 @@ public:
...
@@ -75,39 +81,21 @@ public:
using
super
::
super
;
using
super
::
super
;
using
start_res_t
=
expected
<
disposable
>
;
/// Starts a connection with the length-prefixing protocol.
/// Starts a connection with the length-prefixing protocol.
template
<
class
OnStart
>
template
<
class
OnStart
>
[[
nodiscard
]]
expected
<
disposable
>
start
(
OnStart
on_start
)
{
[[
nodiscard
]]
expected
<
disposable
>
start
(
OnStart
on_start
)
{
using
input_res_t
=
typename
Trait
::
input_resource
;
using
input_res_t
=
typename
Trait
::
input_resource
;
using
output_res_t
=
typename
Trait
::
output_resource
;
using
output_res_t
=
typename
Trait
::
output_resource
;
static_assert
(
std
::
is_invocable_v
<
OnStart
,
input_res_t
,
output_res_t
>
);
static_assert
(
std
::
is_invocable_v
<
OnStart
,
input_res_t
,
output_res_t
>
);
auto
f
=
[
this
,
&
on_start
](
auto
&
cfg
)
{
return
super
::
config
().
visit
([
this
,
&
on_start
](
auto
&
data
)
{
return
this
->
do_start
(
cfg
,
on_start
);
return
do_start
(
super
::
config
(),
data
,
on_start
);
};
});
return
visit
(
f
,
this
->
config
());
}
}
private:
private:
auto
try_connect
(
const
typename
config_type
::
lazy
&
cfg
,
const
std
::
string
&
host
,
uint16_t
port
)
{
auto
result
=
make_connected_tcp_stream_socket
(
host
,
port
,
cfg
.
connection_timeout
);
if
(
result
)
return
result
;
for
(
size_t
i
=
1
;
i
<=
cfg
.
max_retry_count
;
++
i
)
{
std
::
this_thread
::
sleep_for
(
cfg
.
retry_delay
);
result
=
make_connected_tcp_stream_socket
(
host
,
port
,
cfg
.
connection_timeout
);
if
(
result
)
return
result
;
}
return
result
;
}
template
<
class
Conn
,
class
OnStart
>
template
<
class
Conn
,
class
OnStart
>
start_res_t
do_start_impl
(
config_type
&
cfg
,
Conn
conn
,
OnStart
&
on_start
)
{
expected
<
disposable
>
do_start_impl
(
config_type
&
cfg
,
Conn
conn
,
OnStart
&
on_start
)
{
// s2a: socket-to-application (and a2s is the inverse).
// s2a: socket-to-application (and a2s is the inverse).
using
input_t
=
typename
Trait
::
input_type
;
using
input_t
=
typename
Trait
::
input_type
;
using
output_t
=
typename
Trait
::
output_type
;
using
output_t
=
typename
Trait
::
output_type
;
...
@@ -126,51 +114,45 @@ private:
...
@@ -126,51 +114,45 @@ private:
bridge_ptr
->
self_ref
(
ptr
->
as_disposable
());
bridge_ptr
->
self_ref
(
ptr
->
as_disposable
());
cfg
.
mpx
->
start
(
ptr
);
cfg
.
mpx
->
start
(
ptr
);
on_start
(
std
::
move
(
s2a_pull
),
std
::
move
(
a2s_push
));
on_start
(
std
::
move
(
s2a_pull
),
std
::
move
(
a2s_push
));
return
start_res_t
{
disposable
{
std
::
move
(
ptr
)}};
return
expected
<
disposable
>
{
disposable
{
std
::
move
(
ptr
)}};
}
template
<
class
OnStart
>
start_res_t
do_start
(
typename
config_type
::
lazy
&
cfg
,
const
std
::
string
&
host
,
uint16_t
port
,
OnStart
&
on_start
)
{
auto
fd
=
try_connect
(
cfg
,
host
,
port
);
if
(
fd
)
{
if
(
cfg
.
ctx
)
{
auto
conn
=
cfg
.
ctx
->
new_connection
(
*
fd
);
if
(
conn
)
return
do_start_impl
(
cfg
,
std
::
move
(
*
conn
),
on_start
);
cfg
.
call_on_error
(
conn
.
error
());
return
start_res_t
{
std
::
move
(
conn
.
error
())};
}
return
do_start_impl
(
cfg
,
*
fd
,
on_start
);
}
cfg
.
call_on_error
(
fd
.
error
());
return
start_res_t
{
std
::
move
(
fd
.
error
())};
}
}
template
<
class
OnStart
>
template
<
class
OnStart
>
start_res_t
do_start
(
typename
config_type
::
lazy
&
cfg
,
OnStart
&
on_start
)
{
expected
<
disposable
>
do_start
(
config_type
&
cfg
,
if
(
auto
*
st
=
std
::
get_if
<
dsl
::
client_config_server_address
>
(
&
cfg
.
server
))
dsl
::
client_config
::
lazy
&
data
,
return
do_start
(
cfg
,
st
->
host
,
st
->
port
,
on_start
);
OnStart
&
on_start
)
{
if
(
std
::
holds_alternative
<
uri
>
(
data
.
server
))
{
auto
err
=
make_error
(
sec
::
invalid_argument
,
auto
err
=
make_error
(
sec
::
invalid_argument
,
"length-prefix factories do not accept URIs"
);
"length-prefix factories do not accept URIs"
);
cfg
.
call_on_error
(
err
);
return
do_start
(
cfg
,
err
,
on_start
);
return
start_res_t
{
std
::
move
(
err
)};
}
auto
&
addr
=
std
::
get
<
dsl
::
server_address
>
(
data
.
server
);
return
detail
::
tcp_try_connect
(
std
::
move
(
addr
.
host
),
addr
.
port
,
data
.
connection_timeout
,
data
.
max_retry_count
,
data
.
retry_delay
)
.
and_then
(
data
.
with_ctx
([
this
,
&
cfg
,
&
on_start
](
auto
&
conn
)
{
return
this
->
do_start_impl
(
cfg
,
std
::
move
(
conn
),
on_start
);
}));
}
}
template
<
class
OnStart
>
template
<
class
OnStart
>
start_res_t
do_start
(
typename
config_type
::
socket
&
cfg
,
OnStart
&
on_start
)
{
expected
<
disposable
>
do_start
(
config_type
&
cfg
,
return
do_start_impl
(
cfg
,
cfg
.
take_fd
(),
on_start
);
dsl
::
client_config
::
socket
&
data
,
OnStart
&
on_start
)
{
return
do_start_impl
(
cfg
,
data
.
take_fd
(),
on_start
);
}
}
template
<
class
OnStart
>
template
<
class
OnStart
>
start_res_t
do_start
(
typename
config_type
::
conn
&
cfg
,
OnStart
&
on_start
)
{
expected
<
disposable
>
do_start
(
config_type
&
cfg
,
return
do_start_impl
(
cfg
,
std
::
move
(
cfg
.
state
),
on_start
);
dsl
::
client_config
::
conn
&
data
,
OnStart
&
on_start
)
{
return
do_start_impl
(
cfg
,
std
::
move
(
data
.
state
),
on_start
);
}
}
template
<
class
OnStart
>
template
<
class
OnStart
>
start_res_t
do_start
(
typename
config_type
::
fail
&
cfg
,
OnStart
&
)
{
expected
<
disposable
>
do_start
(
config_type
&
cfg
,
error
&
err
,
OnStart
&
)
{
cfg
.
call_on_error
(
cfg
.
err
);
cfg
.
call_on_error
(
err
);
return
start_res_t
{
std
::
move
(
cfg
.
err
)};
return
expected
<
disposable
>
{
std
::
move
(
err
)};
}
}
};
};
...
...
libcaf_net/caf/net/lp/with.hpp
View file @
c0663ea7
...
@@ -52,8 +52,8 @@ public:
...
@@ -52,8 +52,8 @@ public:
/// @private
/// @private
template
<
class
T
,
class
...
Ts
>
template
<
class
T
,
class
...
Ts
>
auto
make
(
dsl
::
client_config_t
oken
<
T
>
token
,
Ts
&&
...
xs
)
{
auto
make
(
dsl
::
client_config_t
ag
<
T
>
tag
,
Ts
&&
...
xs
)
{
return
client_factory
<
Trait
>
{
t
oken
,
std
::
forward
<
Ts
>
(
xs
)...};
return
client_factory
<
Trait
>
{
t
ag
,
std
::
forward
<
Ts
>
(
xs
)...};
}
}
private:
private:
...
...
libcaf_net/caf/net/ssl/tls.hpp
View file @
c0663ea7
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
namespace
caf
::
net
::
ssl
{
namespace
caf
::
net
::
ssl
{
/// Configures the allowed
D
TLS versions on a @ref context.
/// Configures the allowed TLS versions on a @ref context.
enum
class
tls
{
enum
class
tls
{
any
,
any
,
v1_0
,
v1_0
,
...
...
libcaf_net/caf/net/tcp_stream_socket.hpp
View file @
c0663ea7
...
@@ -60,3 +60,11 @@ make_connected_tcp_stream_socket(std::string host, uint16_t port,
...
@@ -60,3 +60,11 @@ make_connected_tcp_stream_socket(std::string host, uint16_t port,
timespan
timeout
=
infinite
);
timespan
timeout
=
infinite
);
}
// namespace caf::net
}
// namespace caf::net
namespace
caf
::
detail
{
expected
<
net
::
tcp_stream_socket
>
CAF_NET_EXPORT
//
tcp_try_connect
(
std
::
string
host
,
uint16_t
port
,
timespan
connection_timeout
,
size_t
max_retry_count
,
timespan
retry_delay
);
}
// namespace caf::detail
libcaf_net/caf/net/web_socket/client_factory.hpp
View file @
c0663ea7
...
@@ -61,12 +61,19 @@ private:
...
@@ -61,12 +61,19 @@ private:
namespace
caf
::
net
::
web_socket
{
namespace
caf
::
net
::
web_socket
{
/// Configuration type for WebSocket clients with a handshake object. The
/// handshake object sets the default endpoint to '/' for convenience.
template
<
class
Trait
>
template
<
class
Trait
>
class
client_factory_config
:
public
dsl
::
config_with_trait
<
Trait
>
{
class
client_factory_config
:
public
dsl
::
config_with_trait
<
Trait
>
{
public:
public:
using
super
=
dsl
::
config_with_trait
<
Trait
>
;
using
super
=
dsl
::
config_with_trait
<
Trait
>
;
using
super
::
super
;
client_factory_config
(
multiplexer
*
mpx
,
Trait
trait
)
:
super
(
mpx
,
std
::
move
(
trait
))
{
hs
.
endpoint
(
"/"
);
}
client_factory_config
(
const
client_factory_config
&
)
=
default
;
handshake
hs
;
handshake
hs
;
};
};
...
@@ -82,9 +89,7 @@ public:
...
@@ -82,9 +89,7 @@ public:
using
super
::
super
;
using
super
::
super
;
using
start_res_t
=
expected
<
disposable
>
;
using
config_type
=
typename
super
::
config_type
;
using
config_type
=
dsl
::
client_config
<
client_factory_config
<
Trait
>>
;
/// Starts a connection with the length-prefixing protocol.
/// Starts a connection with the length-prefixing protocol.
template
<
class
OnStart
>
template
<
class
OnStart
>
...
@@ -92,32 +97,15 @@ public:
...
@@ -92,32 +97,15 @@ public:
using
input_res_t
=
typename
Trait
::
input_resource
;
using
input_res_t
=
typename
Trait
::
input_resource
;
using
output_res_t
=
typename
Trait
::
output_resource
;
using
output_res_t
=
typename
Trait
::
output_resource
;
static_assert
(
std
::
is_invocable_v
<
OnStart
,
input_res_t
,
output_res_t
>
);
static_assert
(
std
::
is_invocable_v
<
OnStart
,
input_res_t
,
output_res_t
>
);
auto
f
=
[
this
,
&
on_start
](
auto
&
cfg
)
{
return
super
::
config
().
visit
([
this
,
&
on_start
](
auto
&
data
)
{
return
this
->
do_start
(
cfg
,
on_start
);
return
do_start
(
super
::
config
(),
data
,
on_start
);
};
});
return
visit
(
f
,
this
->
config
());
}
}
private:
private:
auto
try_connect
(
const
typename
config_type
::
lazy
&
cfg
,
const
std
::
string
&
host
,
uint16_t
port
)
{
auto
result
=
make_connected_tcp_stream_socket
(
host
,
port
,
cfg
.
connection_timeout
);
if
(
result
)
return
result
;
for
(
size_t
i
=
1
;
i
<=
cfg
.
max_retry_count
;
++
i
)
{
std
::
this_thread
::
sleep_for
(
cfg
.
retry_delay
);
result
=
make_connected_tcp_stream_socket
(
host
,
port
,
cfg
.
connection_timeout
);
if
(
result
)
return
result
;
}
return
result
;
}
template
<
class
Conn
,
class
OnStart
>
template
<
class
Conn
,
class
OnStart
>
start_res_t
do_start_impl
(
config_type
&
cfg
,
net
::
web_socket
::
handshake
&
hs
,
expected
<
disposable
>
Conn
conn
,
OnStart
&
on_start
)
{
do_start_impl
(
config_type
&
cfg
,
Conn
conn
,
OnStart
&
on_start
)
{
// s2a: socket-to-application (and a2s is the inverse).
// s2a: socket-to-application (and a2s is the inverse).
using
input_t
=
typename
Trait
::
input_type
;
using
input_t
=
typename
Trait
::
input_type
;
using
output_t
=
typename
Trait
::
output_type
;
using
output_t
=
typename
Trait
::
output_type
;
...
@@ -128,7 +116,7 @@ private:
...
@@ -128,7 +116,7 @@ private:
auto
bridge
=
bridge_t
::
make
(
cfg
.
mpx
,
std
::
move
(
a2s_pull
),
auto
bridge
=
bridge_t
::
make
(
cfg
.
mpx
,
std
::
move
(
a2s_pull
),
std
::
move
(
s2a_push
));
std
::
move
(
s2a_push
));
auto
bridge_ptr
=
bridge
.
get
();
auto
bridge_ptr
=
bridge
.
get
();
auto
impl
=
client
::
make
(
std
::
move
(
hs
),
std
::
move
(
bridge
));
auto
impl
=
client
::
make
(
std
::
move
(
cfg
.
hs
),
std
::
move
(
bridge
));
auto
fd
=
conn
.
fd
();
auto
fd
=
conn
.
fd
();
auto
transport
=
transport_t
::
make
(
std
::
move
(
conn
),
std
::
move
(
impl
));
auto
transport
=
transport_t
::
make
(
std
::
move
(
conn
),
std
::
move
(
impl
));
transport
->
active_policy
().
connect
(
fd
);
transport
->
active_policy
().
connect
(
fd
);
...
@@ -136,66 +124,112 @@ private:
...
@@ -136,66 +124,112 @@ private:
bridge_ptr
->
self_ref
(
ptr
->
as_disposable
());
bridge_ptr
->
self_ref
(
ptr
->
as_disposable
());
cfg
.
mpx
->
start
(
ptr
);
cfg
.
mpx
->
start
(
ptr
);
on_start
(
std
::
move
(
s2a_pull
),
std
::
move
(
a2s_push
));
on_start
(
std
::
move
(
s2a_pull
),
std
::
move
(
a2s_push
));
return
start_res_t
{
disposable
{
std
::
move
(
ptr
)}};
return
expected
<
disposable
>
{
disposable
{
std
::
move
(
ptr
)}};
}
}
template
<
class
OnStart
>
expected
<
void
>
sanity_check
(
config_type
&
cfg
)
{
start_res_t
do_start
(
typename
config_type
::
lazy
&
cfg
,
const
std
::
string
&
host
,
if
(
cfg
.
hs
.
has_mandatory_fields
())
{
uint16_t
port
,
std
::
string
path
,
OnStart
&
on_start
)
{
return
{};
net
::
web_socket
::
handshake
hs
;
}
else
{
hs
.
host
(
host
);
auto
err
=
make_error
(
sec
::
invalid_argument
,
hs
.
endpoint
(
path
);
"WebSocket handshake lacks mandatory fields"
);
auto
fd
=
try_connect
(
cfg
,
host
,
port
);
cfg
.
call_on_error
(
err
);
if
(
!
fd
)
{
return
{
std
::
move
(
err
)};
cfg
.
call_on_error
(
fd
.
error
());
}
return
start_res_t
{
std
::
move
(
fd
.
error
())};
}
if
(
cfg
.
ctx
)
{
auto
conn
=
cfg
.
ctx
->
new_connection
(
*
fd
);
if
(
conn
)
return
do_start_impl
(
cfg
,
hs
,
std
::
move
(
*
conn
),
on_start
);
cfg
.
call_on_error
(
conn
.
error
());
return
start_res_t
{
std
::
move
(
conn
.
error
())};
}
return
do_start_impl
(
cfg
,
hs
,
*
fd
,
on_start
);
}
}
template
<
class
OnStart
>
template
<
class
OnStart
>
start_res_t
do_start
(
typename
config_type
::
lazy
&
cfg
,
OnStart
&
on_start
)
{
expected
<
disposable
>
do_start
(
config_type
&
cfg
,
if
(
auto
*
st
=
std
::
get_if
<
dsl
::
client_config_server_address
>
(
&
cfg
.
server
))
dsl
::
client_config
::
lazy
&
data
,
return
do_start
(
cfg
,
st
->
host
,
st
->
port
,
"/"
,
on_start
);
dsl
::
server_address
&
addr
,
OnStart
&
on_start
)
{
const
auto
&
addr
=
std
::
get
<
uri
>
(
cfg
.
server
);
cfg
.
hs
.
host
(
addr
.
host
);
if
(
addr
.
scheme
()
!=
"ws"
&&
addr
.
scheme
()
!=
"wss"
)
{
return
detail
::
tcp_try_connect
(
std
::
move
(
addr
.
host
),
addr
.
port
,
return
make_error
(
sec
::
invalid_argument
,
"URI must use ws or wss scheme"
);
data
.
connection_timeout
,
data
.
max_retry_count
,
data
.
retry_delay
)
.
and_then
(
data
.
with_ctx
([
this
,
&
cfg
,
&
on_start
](
auto
&
conn
)
{
return
this
->
do_start_impl
(
cfg
,
std
::
move
(
conn
),
on_start
);
}));
}
}
if
(
addr
.
scheme
()
==
"ws"
&&
cfg
.
ctx
)
{
return
make_error
(
sec
::
logic_error
,
"found SSL config with scheme ws"
);
template
<
class
OnStart
>
expected
<
disposable
>
do_start
(
config_type
&
cfg
,
dsl
::
client_config
::
lazy
&
data
,
const
uri
&
addr
,
OnStart
&
on_start
)
{
const
auto
&
auth
=
addr
.
authority
();
auto
host
=
auth
.
host_str
();
auto
port
=
auth
.
port
;
// Sanity checking.
if
(
host
.
empty
())
{
auto
err
=
make_error
(
sec
::
invalid_argument
,
"URI must provide a valid hostname"
);
return
do_start
(
cfg
,
err
,
on_start
);
}
if
(
addr
.
scheme
()
==
"ws"
)
{
if
(
data
.
ctx
)
{
auto
err
=
make_error
(
sec
::
logic_error
,
"found SSL config with scheme ws"
);
return
do_start
(
cfg
,
err
,
on_start
);
}
if
(
port
==
0
)
port
=
defaults
::
net
::
http_default_port
;
}
else
if
(
addr
.
scheme
()
==
"wss"
)
{
if
(
port
==
0
)
port
=
defaults
::
net
::
https_default_port
;
if
(
!
data
.
ctx
)
{
// Auto-initialize SSL context for wss.
auto
ctx
=
ssl
::
context
::
make_client
(
ssl
::
tls
::
v1_0
);
if
(
!
ctx
)
return
do_start
(
cfg
,
ctx
.
error
(),
on_start
);
data
.
ctx
=
std
::
make_shared
<
ssl
::
context
>
(
std
::
move
(
*
ctx
));
}
}
else
{
auto
err
=
make_error
(
sec
::
invalid_argument
,
"URI must use ws or wss scheme"
);
return
do_start
(
cfg
,
err
,
on_start
);
}
// Fill the handshake with fields from the URI.
cfg
.
hs
.
host
(
host
);
cfg
.
hs
.
endpoint
(
addr
.
path_query_fragment
());
// Try to connect.
return
detail
::
tcp_try_connect
(
std
::
move
(
host
),
port
,
data
.
connection_timeout
,
data
.
max_retry_count
,
data
.
retry_delay
)
.
and_then
(
data
.
with_ctx
([
this
,
&
cfg
,
&
on_start
](
auto
&
conn
)
{
return
this
->
do_start_impl
(
cfg
,
std
::
move
(
conn
),
on_start
);
}));
}
}
auto
port
=
addr
.
authority
().
port
;
return
do_start
(
cfg
,
std
::
string
{
addr
.
host_str
()},
port
==
0
?
80
:
port
,
template
<
class
OnStart
>
addr
.
path_query_fragment
(),
on_start
);
expected
<
disposable
>
do_start
(
config_type
&
cfg
,
dsl
::
client_config
::
lazy
&
data
,
OnStart
&
on_start
)
{
auto
fn
=
[
this
,
&
cfg
,
&
data
,
&
on_start
](
auto
&
addr
)
{
return
this
->
do_start
(
cfg
,
data
,
addr
,
on_start
);
};
return
std
::
visit
(
fn
,
data
.
server
);
}
}
template
<
class
OnStart
>
template
<
class
OnStart
>
start_res_t
do_start
(
typename
config_type
::
socket
&
cfg
,
OnStart
&
)
{
expected
<
disposable
>
do_start
(
config_type
&
cfg
,
auto
err
=
make_error
(
sec
::
logic_error
,
"not implemented yet"
);
dsl
::
client_config
::
socket
&
data
,
cfg
.
call_on_error
(
err
);
OnStart
&
on_start
)
{
return
start_res_t
{
std
::
move
(
err
)};
return
sanity_check
(
cfg
).
and_then
([
&
]
{
//
// return do_start_impl(cfg, cfg.take_fd(), on_start);
return
do_start_impl
(
cfg
,
data
.
take_fd
(),
on_start
);
});
}
}
template
<
class
OnStart
>
template
<
class
OnStart
>
start_res_t
do_start
(
typename
config_type
::
conn
&
cfg
,
OnStart
&
)
{
expected
<
disposable
>
do_start
(
config_type
&
cfg
,
auto
err
=
make_error
(
sec
::
logic_error
,
"not implemented yet"
);
dsl
::
client_config
::
conn
&
data
,
cfg
.
call_on_error
(
err
);
OnStart
&
on_start
)
{
return
start_res_t
{
std
::
move
(
err
)};
return
sanity_check
(
cfg
).
and_then
([
&
]
{
//
// return do_start_impl(cfg, std::move(cfg.state), on_start);
return
do_start_impl
(
cfg
,
std
::
move
(
data
.
state
),
on_start
);
});
}
}
template
<
class
OnStart
>
template
<
class
OnStart
>
start_res_t
do_start
(
typename
config_type
::
fail
&
cfg
,
OnStart
&
)
{
expected
<
disposable
>
do_start
(
config_type
&
cfg
,
error
&
err
,
OnStart
&
)
{
cfg
.
call_on_error
(
cfg
.
err
);
cfg
.
call_on_error
(
err
);
return
start_res_t
{
std
::
move
(
cfg
.
err
)};
return
expected
<
disposable
>
{
std
::
move
(
err
)};
}
}
};
};
...
...
libcaf_net/caf/net/web_socket/handshake.hpp
View file @
c0663ea7
...
@@ -86,6 +86,11 @@ public:
...
@@ -86,6 +86,11 @@ public:
fields_
[
"_endpoint"
]
=
std
::
move
(
value
);
fields_
[
"_endpoint"
]
=
std
::
move
(
value
);
}
}
/// Checks whether the handshake has an `endpoint` defined.
bool
has_endpoint
()
const
noexcept
{
return
fields_
.
contains
(
"_endpoint"
);
}
/// Sets a value for the mandatory `Host` field.
/// Sets a value for the mandatory `Host` field.
/// @param value The Internet host and port number of the resource being
/// @param value The Internet host and port number of the resource being
/// requested, as obtained from the original URI given by the
/// requested, as obtained from the original URI given by the
...
@@ -94,6 +99,11 @@ public:
...
@@ -94,6 +99,11 @@ public:
fields_
[
"_host"
]
=
std
::
move
(
value
);
fields_
[
"_host"
]
=
std
::
move
(
value
);
}
}
/// Checks whether the handshake has an `host` defined.
bool
has_host
()
const
noexcept
{
return
fields_
.
contains
(
"_host"
);
}
/// Sets a value for the optional `Origin` field.
/// Sets a value for the optional `Origin` field.
/// @param value Indicates where the GET request originates from. Usually only
/// @param value Indicates where the GET request originates from. Usually only
/// sent by browser clients.
/// sent by browser clients.
...
...
libcaf_net/caf/net/web_socket/with.hpp
View file @
c0663ea7
...
@@ -51,7 +51,7 @@ public:
...
@@ -51,7 +51,7 @@ public:
/// @private
/// @private
template
<
class
T
,
class
...
Ts
>
template
<
class
T
,
class
...
Ts
>
auto
make
(
dsl
::
client_config_t
oken
<
T
>
token
,
Ts
&&
...
xs
)
{
auto
make
(
dsl
::
client_config_t
ag
<
T
>
token
,
Ts
&&
...
xs
)
{
return
client_factory
<
Trait
>
{
token
,
std
::
forward
<
Ts
>
(
xs
)...};
return
client_factory
<
Trait
>
{
token
,
std
::
forward
<
Ts
>
(
xs
)...};
}
}
...
...
libcaf_net/src/net/socket_manager.cpp
View file @
c0663ea7
...
@@ -104,6 +104,7 @@ void socket_manager::schedule(action what) {
...
@@ -104,6 +104,7 @@ void socket_manager::schedule(action what) {
}
}
void
socket_manager
::
shutdown
()
{
void
socket_manager
::
shutdown
()
{
CAF_LOG_TRACE
(
""
);
if
(
!
shutting_down_
)
{
if
(
!
shutting_down_
)
{
shutting_down_
=
true
;
shutting_down_
=
true
;
dispose
();
dispose
();
...
@@ -122,6 +123,7 @@ error socket_manager::start() {
...
@@ -122,6 +123,7 @@ error socket_manager::start() {
CAF_LOG_TRACE
(
""
);
CAF_LOG_TRACE
(
""
);
if
(
auto
err
=
nonblocking
(
fd_
,
true
))
{
if
(
auto
err
=
nonblocking
(
fd_
,
true
))
{
CAF_LOG_ERROR
(
"failed to set nonblocking flag in socket:"
<<
err
);
CAF_LOG_ERROR
(
"failed to set nonblocking flag in socket:"
<<
err
);
handler_
->
abort
(
err
);
cleanup
();
cleanup
();
return
err
;
return
err
;
}
else
if
(
err
=
handler_
->
start
(
this
);
err
)
{
}
else
if
(
err
=
handler_
->
start
(
this
);
err
)
{
...
@@ -148,6 +150,7 @@ void socket_manager::handle_write_event() {
...
@@ -148,6 +150,7 @@ void socket_manager::handle_write_event() {
}
}
void
socket_manager
::
handle_error
(
sec
code
)
{
void
socket_manager
::
handle_error
(
sec
code
)
{
CAF_LOG_TRACE
(
""
);
if
(
!
disposed_
)
if
(
!
disposed_
)
disposed_
=
true
;
disposed_
=
true
;
if
(
handler_
)
{
if
(
handler_
)
{
...
...
libcaf_net/src/net/tcp_stream_socket.cpp
View file @
c0663ea7
...
@@ -182,3 +182,25 @@ expected<tcp_stream_socket> make_connected_tcp_stream_socket(std::string host,
...
@@ -182,3 +182,25 @@ expected<tcp_stream_socket> make_connected_tcp_stream_socket(std::string host,
}
}
}
// namespace caf::net
}
// namespace caf::net
namespace
caf
::
detail
{
expected
<
net
::
tcp_stream_socket
>
tcp_try_connect
(
std
::
string
host
,
uint16_t
port
,
timespan
connection_timeout
,
size_t
max_retry_count
,
timespan
retry_delay
)
{
uri
::
authority_type
auth
;
auth
.
host
=
std
::
move
(
host
);
auth
.
port
=
port
;
auto
result
=
net
::
make_connected_tcp_stream_socket
(
auth
,
connection_timeout
);
if
(
result
)
return
result
;
for
(
size_t
i
=
1
;
i
<=
max_retry_count
;
++
i
)
{
std
::
this_thread
::
sleep_for
(
retry_delay
);
result
=
net
::
make_connected_tcp_stream_socket
(
auth
,
connection_timeout
);
if
(
result
)
return
result
;
}
return
result
;
}
}
// namespace caf::detail
libcaf_net/src/net/web_socket/handshake.cpp
View file @
c0663ea7
...
@@ -67,7 +67,7 @@ void handshake::randomize_key(unsigned seed) {
...
@@ -67,7 +67,7 @@ void handshake::randomize_key(unsigned seed) {
}
}
bool
handshake
::
has_mandatory_fields
()
const
noexcept
{
bool
handshake
::
has_mandatory_fields
()
const
noexcept
{
return
fields_
.
contains
(
"_endpoint"
)
&&
fields_
.
contains
(
"_host"
);
return
has_endpoint
()
&&
has_host
(
);
}
}
// -- HTTP generation and validation -------------------------------------------
// -- HTTP generation and validation -------------------------------------------
...
...
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