connectivity: don't cache HTTP response for comparing connectivity response
We don't need to remember (and compare) all the bytes that we received. We can just compare them right away, and remember how many good bytes we received.
This commit is contained in:
@@ -92,7 +92,7 @@ struct _NMConnectivityCheckHandle {
|
||||
struct curl_slist *request_headers;
|
||||
struct curl_slist *hosts;
|
||||
|
||||
GString *recv_msg;
|
||||
gsize response_good_cnt;
|
||||
|
||||
guint curl_timer;
|
||||
int ch_ifindex;
|
||||
@@ -271,8 +271,6 @@ cb_data_complete (NMConnectivityCheckHandle *cb_data,
|
||||
|
||||
#if WITH_CONCHECK
|
||||
_con_config_unref (cb_data->concheck.con_config);
|
||||
if (cb_data->concheck.recv_msg)
|
||||
g_string_free (cb_data->concheck.recv_msg, TRUE);
|
||||
#endif
|
||||
g_free (cb_data->ifspec);
|
||||
if (cb_data->completed_log_message_free)
|
||||
@@ -391,8 +389,7 @@ _con_curl_check_connectivity (CURLM *mhandle, int sockfd, int ev_bitmask)
|
||||
}
|
||||
|
||||
if ( response_code == 200
|
||||
&& ( !cb_data->concheck.recv_msg
|
||||
|| cb_data->concheck.recv_msg->len == 0)) {
|
||||
&& cb_data->concheck.response_good_cnt == 0) {
|
||||
/* we expected no response, and indeed we got an empty reply (with status code 200) */
|
||||
cb_data_queue_completed (cb_data,
|
||||
NM_CONNECTIVITY_FULL,
|
||||
@@ -561,6 +558,8 @@ easy_write_cb (void *buffer, size_t size, size_t nmemb, void *userdata)
|
||||
{
|
||||
NMConnectivityCheckHandle *cb_data = userdata;
|
||||
size_t len = size * nmemb;
|
||||
size_t response_len;
|
||||
size_t check_len;
|
||||
const char *response;
|
||||
|
||||
if (cb_data->completed_state != NM_CONNECTIVITY_UNKNOWN) {
|
||||
@@ -573,11 +572,6 @@ easy_write_cb (void *buffer, size_t size, size_t nmemb, void *userdata)
|
||||
return len;
|
||||
}
|
||||
|
||||
if (!cb_data->concheck.recv_msg)
|
||||
cb_data->concheck.recv_msg = g_string_sized_new (len + 10);
|
||||
|
||||
g_string_append_len (cb_data->concheck.recv_msg, buffer, len);
|
||||
|
||||
response = _con_config_get_response (cb_data->concheck.con_config);;
|
||||
|
||||
if (response[0] == '\0') {
|
||||
@@ -586,22 +580,55 @@ easy_write_cb (void *buffer, size_t size, size_t nmemb, void *userdata)
|
||||
* response based on the status code 204.
|
||||
*
|
||||
* Continue receiving... */
|
||||
cb_data->concheck.response_good_cnt += len;
|
||||
|
||||
if (cb_data->concheck.response_good_cnt > (gsize) (100 * 1024)) {
|
||||
/* we expect an empty response. We accept either
|
||||
* 1) status code 204 and any response
|
||||
* 2) status code 200 and an empty reponse.
|
||||
*
|
||||
* Here, we want to continue receiving data, to see whether we have
|
||||
* case 1). Arguably, the server shouldn't send us 204 with a non-empty
|
||||
* response, but we accept that also with a non-empty response, so
|
||||
* keep receiving.
|
||||
*
|
||||
* However, if we get an excessive amound of data, we put a stop on it
|
||||
* and fail. */
|
||||
cb_data_queue_completed (cb_data,
|
||||
NM_CONNECTIVITY_PORTAL,
|
||||
"unexpected non-empty response",
|
||||
NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
if (cb_data->concheck.recv_msg->len >= strlen (response)) {
|
||||
/* We already have enough data -- check response */
|
||||
if (g_str_has_prefix (cb_data->concheck.recv_msg->str, response)) {
|
||||
cb_data_queue_completed (cb_data,
|
||||
NM_CONNECTIVITY_FULL,
|
||||
"expected response",
|
||||
NULL);
|
||||
} else {
|
||||
cb_data_queue_completed (cb_data,
|
||||
NM_CONNECTIVITY_PORTAL,
|
||||
"unexpected response",
|
||||
NULL);
|
||||
}
|
||||
nm_assert (cb_data->concheck.response_good_cnt < strlen (response));
|
||||
|
||||
response_len = strlen (response);
|
||||
|
||||
check_len = NM_MIN (len,
|
||||
response_len - cb_data->concheck.response_good_cnt);
|
||||
|
||||
if (strncmp (&response[cb_data->concheck.response_good_cnt],
|
||||
buffer,
|
||||
check_len) != 0) {
|
||||
cb_data_queue_completed (cb_data,
|
||||
NM_CONNECTIVITY_PORTAL,
|
||||
"unexpected response",
|
||||
NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cb_data->concheck.response_good_cnt += len;
|
||||
|
||||
if (cb_data->concheck.response_good_cnt >= response_len) {
|
||||
/* We already have enough data, and it matched. */
|
||||
cb_data_queue_completed (cb_data,
|
||||
NM_CONNECTIVITY_FULL,
|
||||
"expected response",
|
||||
NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user