mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +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
					
						 George Joseph
						George Joseph
					
				
			
			
				
	
			
			
			
						parent
						
							ce91a0fdbc
						
					
				
				
					commit
					851a759619
				
			| @@ -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