Commit 477e91d7 authored by Thomas Haller's avatar Thomas Haller

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.
parent 7807ffff
......@@ -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... */
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->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 response",
"unexpected non-empty response",
NULL);
return 0;
}
return len;
}
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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment