mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 20:20:07 +00:00
res_http_websocket: Add a client connection timeout
Previously there was no way to specify a connection timeout when attempting to connect a websocket client to a server. This patch makes it possible to now do such. Change-Id: I5812f6f28d3d13adbc246517f87af177fa20ee9d
This commit is contained in:
committed by
Friendly Automation
parent
c1ca028a0b
commit
9f5c1d30ed
@@ -440,6 +440,55 @@ AST_OPTIONAL_API(struct ast_websocket *, ast_websocket_client_create,
|
|||||||
struct ast_tls_config *tls_cfg,
|
struct ast_tls_config *tls_cfg,
|
||||||
enum ast_websocket_result *result), { return NULL;});
|
enum ast_websocket_result *result), { return NULL;});
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Options used for a websocket client
|
||||||
|
*/
|
||||||
|
struct ast_websocket_client_options {
|
||||||
|
/*!
|
||||||
|
* The URI to connect to
|
||||||
|
*
|
||||||
|
* Expected uri form:
|
||||||
|
* \verbatim ws[s]://<address>[:port][/<path>] \endverbatim
|
||||||
|
* The address (can be a host name) and port are parsed out and used to connect
|
||||||
|
* to the remote server. If multiple IPs are returned during address
|
||||||
|
* resolution then the first one is chosen.
|
||||||
|
*/
|
||||||
|
const char *uri;
|
||||||
|
/*!
|
||||||
|
* A comma separated string of supported protocols
|
||||||
|
*/
|
||||||
|
const char *protocols;
|
||||||
|
/*!
|
||||||
|
* Optional connection timeout
|
||||||
|
*
|
||||||
|
* How long (in milliseconds) to attempt to connect (-1 equals infinite)
|
||||||
|
*/
|
||||||
|
int timeout;
|
||||||
|
/*!
|
||||||
|
* Secure websocket credentials
|
||||||
|
*/
|
||||||
|
struct ast_tls_config *tls_cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Create, and connect, a websocket client using given options.
|
||||||
|
*
|
||||||
|
* If the client websocket successfully connects, then the accepted protocol can be
|
||||||
|
* checked via a call to ast_websocket_client_accept_protocol.
|
||||||
|
*
|
||||||
|
* \note While connecting this *will* block until a response is received
|
||||||
|
* from the remote host, or the connection timeout is reached
|
||||||
|
*
|
||||||
|
* \param options Websocket client options
|
||||||
|
* \param result result code set on client failure
|
||||||
|
*
|
||||||
|
* \return a client websocket.
|
||||||
|
* \retval NULL if object could not be created or connected
|
||||||
|
*/
|
||||||
|
AST_OPTIONAL_API(struct ast_websocket *, ast_websocket_client_create_with_options,
|
||||||
|
(struct ast_websocket_client_options *options,
|
||||||
|
enum ast_websocket_result *result), { return NULL;});
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Retrieve the server accepted sub-protocol on the client.
|
* \brief Retrieve the server accepted sub-protocol on the client.
|
||||||
*
|
*
|
||||||
|
@@ -1223,8 +1223,7 @@ static void websocket_client_destroy(void *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct ast_websocket * websocket_client_create(
|
static struct ast_websocket * websocket_client_create(
|
||||||
const char *uri, const char *protocols, struct ast_tls_config *tls_cfg,
|
struct ast_websocket_client_options *options, enum ast_websocket_result *result)
|
||||||
enum ast_websocket_result *result)
|
|
||||||
{
|
{
|
||||||
struct ast_websocket *ws = ao2_alloc(sizeof(*ws), session_destroy_fn);
|
struct ast_websocket *ws = ao2_alloc(sizeof(*ws), session_destroy_fn);
|
||||||
|
|
||||||
@@ -1248,18 +1247,18 @@ static struct ast_websocket * websocket_client_create(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (websocket_client_parse_uri(
|
if (websocket_client_parse_uri(
|
||||||
uri, &ws->client->host, &ws->client->resource_name)) {
|
options->uri, &ws->client->host, &ws->client->resource_name)) {
|
||||||
ao2_ref(ws, -1);
|
ao2_ref(ws, -1);
|
||||||
*result = WS_URI_PARSE_ERROR;
|
*result = WS_URI_PARSE_ERROR;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(ws->client->args = websocket_client_args_create(
|
if (!(ws->client->args = websocket_client_args_create(
|
||||||
ws->client->host, tls_cfg, result))) {
|
ws->client->host, options->tls_cfg, result))) {
|
||||||
ao2_ref(ws, -1);
|
ao2_ref(ws, -1);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ws->client->protocols = ast_strdup(protocols);
|
ws->client->protocols = ast_strdup(options->protocols);
|
||||||
|
|
||||||
ws->client->version = 13;
|
ws->client->version = 13;
|
||||||
ws->opcode = -1;
|
ws->opcode = -1;
|
||||||
@@ -1395,13 +1394,13 @@ static enum ast_websocket_result websocket_client_handshake(
|
|||||||
return websocket_client_handshake_get_response(client);
|
return websocket_client_handshake_get_response(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum ast_websocket_result websocket_client_connect(struct ast_websocket *ws)
|
static enum ast_websocket_result websocket_client_connect(struct ast_websocket *ws, int timeout)
|
||||||
{
|
{
|
||||||
enum ast_websocket_result res;
|
enum ast_websocket_result res;
|
||||||
/* create and connect the client - note client_start
|
/* create and connect the client - note client_start
|
||||||
releases the session instance on failure */
|
releases the session instance on failure */
|
||||||
if (!(ws->client->ser = ast_tcptls_client_start(
|
if (!(ws->client->ser = ast_tcptls_client_start_timeout(
|
||||||
ast_tcptls_client_create(ws->client->args)))) {
|
ast_tcptls_client_create(ws->client->args), timeout))) {
|
||||||
return WS_CLIENT_START_ERROR;
|
return WS_CLIENT_START_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1422,14 +1421,26 @@ struct ast_websocket *AST_OPTIONAL_API_NAME(ast_websocket_client_create)
|
|||||||
(const char *uri, const char *protocols, struct ast_tls_config *tls_cfg,
|
(const char *uri, const char *protocols, struct ast_tls_config *tls_cfg,
|
||||||
enum ast_websocket_result *result)
|
enum ast_websocket_result *result)
|
||||||
{
|
{
|
||||||
struct ast_websocket *ws = websocket_client_create(
|
struct ast_websocket_client_options options = {
|
||||||
uri, protocols, tls_cfg, result);
|
.uri = uri,
|
||||||
|
.protocols = protocols,
|
||||||
|
.timeout = -1,
|
||||||
|
.tls_cfg = tls_cfg,
|
||||||
|
};
|
||||||
|
|
||||||
|
return ast_websocket_client_create_with_options(&options, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ast_websocket *AST_OPTIONAL_API_NAME(ast_websocket_client_create_with_options)
|
||||||
|
(struct ast_websocket_client_options *options, enum ast_websocket_result *result)
|
||||||
|
{
|
||||||
|
struct ast_websocket *ws = websocket_client_create(options, result);
|
||||||
|
|
||||||
if (!ws) {
|
if (!ws) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*result = websocket_client_connect(ws)) != WS_OK) {
|
if ((*result = websocket_client_connect(ws, options->timeout)) != WS_OK) {
|
||||||
ao2_ref(ws, -1);
|
ao2_ref(ws, -1);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user