Fix handling of 'Connection' header in squeasel

This patch bumps Impala's version of squeasel to
030ccce87359d892e22fb368c5fc5b75d9a2a5f7
in order to pull in a fix for an issue where squeasel was improperly
closing connections when the 'Connection: Upgrade' header was included
in the request, which Apache Knox will include in certain situations.

See https://github.com/cloudera/squeasel/pull/16

Change-Id: I9b9c4f328f0be7800aab978e14b7f46c67293417
Reviewed-on: http://gerrit.cloudera.org:8080/14915
Reviewed-by: Adar Dembo <adar@cloudera.com>
Reviewed-by: Tim Armstrong <tarmstrong@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
diff --git a/be/src/thirdparty/squeasel/squeasel.c b/be/src/thirdparty/squeasel/squeasel.c
index 16c8ff4..f663437 100644
--- a/be/src/thirdparty/squeasel/squeasel.c
+++ b/be/src/thirdparty/squeasel/squeasel.c
@@ -693,20 +693,32 @@
   return j;
 }
 
-// HTTP 1.1 assumes keep alive if "Connection:" header is not set
-// This function must tolerate situations when connection info is not
-// set up, for example if request parsing failed.
 static int should_keep_alive(const struct sq_connection *conn) {
   const char *http_version = conn->request_info.http_version;
   const char *header = sq_get_header(conn, "Connection");
+
+  // Start by checking our own internal request state and configuration.
   if (conn->must_close ||
-      conn->status_code == 401 ||
-      sq_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0 ||
-      (header != NULL && sq_strcasecmp(header, "keep-alive") != 0) ||
-      (header == NULL && http_version && strcmp(http_version, "1.1"))) {
+      sq_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0) {
     return 0;
   }
-  return 1;
+
+  // Now consider the HTTP version and "Connection:" header.
+
+  // If we couldn't parse an HTTP version, assume 1.0.
+  //
+  // We must tolerate situations when connection info is not set up, for
+  // example if HTTP request parsing failed.
+  int http_1_0 = !http_version || sq_strcasecmp(http_version, "1.0") == 0;
+  if (!header) {
+    // HTTP 1.1 assumes keep alive if the "Connection:" header is not set.
+    return !http_1_0;
+  }
+
+  // With HTTP 1.0, keep alive only if the "Connection: keep-alive" header
+  // exists. Otherwise, keep alive unless the "Connection: close" header exists.
+  return (http_1_0 && sq_strcasecmp(header, "keep-alive") == 0) ||
+         (!http_1_0 && sq_strcasecmp(header, "close") != 0);
 }
 
 static const char *suggest_connection_header(const struct sq_connection *conn) {
@@ -3236,8 +3248,7 @@
     conn->must_close = 1;
     fclose_on_exec(&file);
     sq_printf(conn, "HTTP/1.1 200 OK\r\n"
-              "Content-Type: text/html\r\nConnection: %s\r\n\r\n",
-              suggest_connection_header(conn));
+              "Content-Type: text/html\r\nConnection: close\r\n\r\n");
     send_ssi_file(conn, path, &file, 0);
     sq_fclose(&file);
   }