mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-03 20:38:59 +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
						
							ee887b66bb
						
					
				
				
					commit
					a4ebfe8492
				
			@@ -440,6 +440,55 @@ AST_OPTIONAL_API(struct ast_websocket *, ast_websocket_client_create,
 | 
			
		||||
		  struct ast_tls_config *tls_cfg,
 | 
			
		||||
		  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.
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -1223,8 +1223,7 @@ static void websocket_client_destroy(void *obj)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct ast_websocket * websocket_client_create(
 | 
			
		||||
	const char *uri, const char *protocols,	struct ast_tls_config *tls_cfg,
 | 
			
		||||
	enum ast_websocket_result *result)
 | 
			
		||||
	struct ast_websocket_client_options *options, enum ast_websocket_result *result)
 | 
			
		||||
{
 | 
			
		||||
	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(
 | 
			
		||||
		    uri, &ws->client->host, &ws->client->resource_name)) {
 | 
			
		||||
		    options->uri, &ws->client->host, &ws->client->resource_name)) {
 | 
			
		||||
		ao2_ref(ws, -1);
 | 
			
		||||
		*result = WS_URI_PARSE_ERROR;
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	ws->client->protocols = ast_strdup(protocols);
 | 
			
		||||
	ws->client->protocols = ast_strdup(options->protocols);
 | 
			
		||||
 | 
			
		||||
	ws->client->version = 13;
 | 
			
		||||
	ws->opcode = -1;
 | 
			
		||||
@@ -1395,13 +1394,13 @@ static enum ast_websocket_result websocket_client_handshake(
 | 
			
		||||
	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;
 | 
			
		||||
	/* create and connect the client - note client_start
 | 
			
		||||
	   releases the session instance on failure */
 | 
			
		||||
	if (!(ws->client->ser = ast_tcptls_client_start(
 | 
			
		||||
		      ast_tcptls_client_create(ws->client->args)))) {
 | 
			
		||||
	if (!(ws->client->ser = ast_tcptls_client_start_timeout(
 | 
			
		||||
		      ast_tcptls_client_create(ws->client->args), timeout))) {
 | 
			
		||||
		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,
 | 
			
		||||
	 enum ast_websocket_result *result)
 | 
			
		||||
{
 | 
			
		||||
	struct ast_websocket *ws = websocket_client_create(
 | 
			
		||||
		uri, protocols, tls_cfg, result);
 | 
			
		||||
	struct ast_websocket_client_options options = {
 | 
			
		||||
		.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) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((*result = websocket_client_connect(ws)) != WS_OK) {
 | 
			
		||||
	if ((*result = websocket_client_connect(ws, options->timeout)) != WS_OK) {
 | 
			
		||||
		ao2_ref(ws, -1);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user