Skip to content

Commit 098f6ba

Browse files
committed
feat(websocket): Add websocket HTTP redirect
- Handle 301 status (moved permanently) and redirect the connection to the new host.
1 parent f1a72ec commit 098f6ba

File tree

1 file changed

+38
-13
lines changed

1 file changed

+38
-13
lines changed

components/esp_websocket_client/esp_websocket_client.c

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ static const char *TAG = "websocket_client";
6060
#define WS_OVER_TCP_SCHEME "ws"
6161
#define WS_OVER_TLS_SCHEME "wss"
6262
#define WS_HTTP_BASIC_AUTH "Basic "
63+
#define WS_HTTP_REDIRECT(code) ((code >= 300) && (code < 400))
64+
65+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
66+
// Features supported in 5.5.0
67+
#define WS_TRANSPORT_REDIRECT_HEADER_SUPPORT 1
68+
#endif
6369

6470
const static int STOPPED_BIT = BIT0;
6571
const static int CLOSE_FRAME_SENT_BIT = BIT1; // Indicates that a close frame was sent by the client
@@ -586,6 +592,23 @@ static esp_err_t esp_websocket_client_create_transport(esp_websocket_client_hand
586592
return ESP_OK;
587593
}
588594

595+
static void esp_websocket_client_prepare_transport(esp_websocket_client_handle_t client)
596+
{
597+
//get transport by scheme
598+
if (client->transport == NULL && client->config->ext_transport == NULL) {
599+
client->transport = esp_transport_list_get_transport(client->transport_list, client->config->scheme);
600+
}
601+
602+
if (client->transport == NULL) {
603+
ESP_LOGE(TAG, "There are no transports valid, stop websocket client");
604+
client->run = false;
605+
}
606+
//default port
607+
if (client->config->port == 0) {
608+
client->config->port = esp_transport_get_default_port(client->transport);
609+
}
610+
}
611+
589612
static int esp_websocket_client_send_with_exact_opcode(esp_websocket_client_handle_t client, ws_transport_opcodes_t opcode, const uint8_t *data, int len, TickType_t timeout)
590613
{
591614
int ret = -1;
@@ -985,19 +1008,7 @@ static void esp_websocket_client_task(void *pv)
9851008
esp_websocket_client_handle_t client = (esp_websocket_client_handle_t) pv;
9861009
client->run = true;
9871010

988-
//get transport by scheme
989-
if (client->transport == NULL && client->config->ext_transport == NULL) {
990-
client->transport = esp_transport_list_get_transport(client->transport_list, client->config->scheme);
991-
}
992-
993-
if (client->transport == NULL) {
994-
ESP_LOGE(TAG, "There are no transports valid, stop websocket client");
995-
client->run = false;
996-
}
997-
//default port
998-
if (client->config->port == 0) {
999-
client->config->port = esp_transport_get_default_port(client->transport);
1000-
}
1011+
esp_websocket_client_prepare_transport(client);
10011012

10021013
client->state = WEBSOCKET_STATE_INIT;
10031014
xEventGroupClearBits(client->status_bits, STOPPED_BIT | CLOSE_FRAME_SENT_BIT);
@@ -1035,6 +1046,20 @@ static void esp_websocket_client_task(void *pv)
10351046
esp_websocket_client_abort_connection(client, WEBSOCKET_ERROR_TYPE_TCP_TRANSPORT);
10361047
break;
10371048
}
1049+
#if WS_TRANSPORT_REDIRECT_HEADER_SUPPORT
1050+
else if (WS_HTTP_REDIRECT(result)) {
1051+
// Redirecting to a new URI
1052+
client->config->port = 0;
1053+
client->config->uri = esp_transport_ws_get_redir_uri(client->transport);
1054+
esp_websocket_client_set_uri(client, client->config->uri);
1055+
esp_websocket_client_prepare_transport(client);
1056+
1057+
// Rerun the connection with the redir uri.
1058+
client->state = WEBSOCKET_STATE_INIT;
1059+
ESP_LOGI(TAG, "Redirecting to %s", client->config->uri);
1060+
break;
1061+
}
1062+
#endif
10381063
ESP_LOGD(TAG, "Transport connected to %s://%s:%d", client->config->scheme, client->config->host, client->config->port);
10391064

10401065
client->state = WEBSOCKET_STATE_CONNECTED;

0 commit comments

Comments
 (0)