summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-01-14 14:38:10 +0100
committerThomas Haller <thaller@redhat.com>2019-01-31 11:33:44 +0100
commit7807ffff83c4d3411205ba11a2c5713cfa2842f7 (patch)
tree0a3b4d28a908411cdc54f0aa9b4252bbfcb4042b
parenta68b1827ec20a0fcbf6928468dd880e42c3dc4cb (diff)
downloadNetworkManager-7807ffff83c4d3411205ba11a2c5713cfa2842f7.tar.gz
connectivity: fix handling of no-response for captive portal detection
Since we only compare that the HTTP response starts with the expected response, we need to handle the empty expected response specially (because, every response has "" as prefix). So now if connectivity.response is set to "" (empty) we accept: - HTTP status code 204. We ignore and accept any extra data that we might receive. - HTTP status code 200 and an empty (or no) body.
-rw-r--r--man/NetworkManager.conf.xml4
-rw-r--r--src/nm-connectivity.c75
2 files changed, 58 insertions, 21 deletions
diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index e22aa20ad1..e97b6bb9eb 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -1087,7 +1087,9 @@ managed=1
<listitem><para>If set controls what body content
NetworkManager checks for when requesting the URI for
connectivity checking. If missing, defaults to
- "NetworkManager is online" </para></listitem>
+ "NetworkManager is online". If set to empty, the
+ HTTP server is expected to answer with status code
+ 204 or no data.</para></listitem>
</varlistentry>
</variablelist>
</para>
diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c
index 5f0567e9d0..8b9af50767 100644
--- a/src/nm-connectivity.c
+++ b/src/nm-connectivity.c
@@ -342,6 +342,7 @@ _con_curl_check_connectivity (CURLM *mhandle, int sockfd, int ev_bitmask)
}
while ((msg = curl_multi_info_read (mhandle, &m_left))) {
+ const char *response;
if (msg->msg != CURLMSG_DONE)
continue;
@@ -370,25 +371,45 @@ _con_curl_check_connectivity (CURLM *mhandle, int sockfd, int ev_bitmask)
g_strdup_printf ("check failed: (%d) %s",
msg->data.result,
curl_easy_strerror (msg->data.result)));
- } else if ( !((_con_config_get_response (cb_data->concheck.con_config))[0])
- && (curl_easy_getinfo (msg->easy_handle, CURLINFO_RESPONSE_CODE, &response_code) == CURLE_OK)
- && response_code == 204) {
- /* If we got a 204 response code (no content) and we actually
- * requested no content, report full connectivity. */
- cb_data_queue_completed (cb_data,
- NM_CONNECTIVITY_FULL,
- "no content, as expected",
- NULL);
- } else {
- /* If we get here, it means that easy_write_cb() didn't read enough
- * bytes to be able to do a match, or that we were asking for no content
- * (204 response code) and we actually got some. Either way, that is
- * an indication of a captive portal */
- cb_data_queue_completed (cb_data,
- NM_CONNECTIVITY_PORTAL,
- "unexpected short response",
- NULL);
+ continue;
+ }
+
+ response = _con_config_get_response (cb_data->concheck.con_config);
+
+ if ( response[0] == '\0'
+ && (curl_easy_getinfo (msg->easy_handle, CURLINFO_RESPONSE_CODE, &response_code) == CURLE_OK)) {
+
+ if (response_code == 204) {
+ /* We expected an empty response, and we got a 204 response code (no content).
+ * We may or may not have received any content (we would ignore it).
+ * Anyway, the response_code 204 means we are good. */
+ cb_data_queue_completed (cb_data,
+ NM_CONNECTIVITY_FULL,
+ "no content, as expected",
+ NULL);
+ continue;
+ }
+
+ if ( response_code == 200
+ && ( !cb_data->concheck.recv_msg
+ || cb_data->concheck.recv_msg->len == 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,
+ "empty response, as expected",
+ NULL);
+ continue;
+ }
}
+
+ /* If we get here, it means that easy_write_cb() didn't read enough
+ * bytes to be able to do a match, or that we were asking for no content
+ * (204 response code) and we actually got some. Either way, that is
+ * an indication of a captive portal */
+ cb_data_queue_completed (cb_data,
+ NM_CONNECTIVITY_PORTAL,
+ "unexpected short response",
+ NULL);
}
/* if we return a failure, we don't know what went wrong. It's likely serious, because
@@ -547,14 +568,28 @@ easy_write_cb (void *buffer, size_t size, size_t nmemb, void *userdata)
return 0;
}
+ if (len == 0) {
+ /* no data. That can happen, it's fine. */
+ 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
- && cb_data->concheck.recv_msg->len >= strlen (response)) {
+
+ if (response[0] == '\0') {
+ /* no response expected. We are however graceful and accept any
+ * extra response that we might receive. We determine the empty
+ * 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,