Index: modules/http/http_core.c
===================================================================
--- modules/http/http_core.c	(revision 1663701)
+++ modules/http/http_core.c	(working copy)
@@ -48,6 +48,20 @@ AP_DECLARE_DATA const char *ap_multipart_boundary;
  */
 static int async_mpm = 0;
 
+module AP_MODULE_DECLARE_DATA http_module;
+
+typedef struct {
+    int keep_alive_timeout_set;
+} http_srv_cfg;
+
+static void *create_srv_cfg(apr_pool_t *p, server_rec *s)
+{
+    http_srv_cfg *scfg = apr_palloc(p, sizeof *scfg);
+
+    scfg->keep_alive_timeout_set = 0;
+    return scfg;
+}
+
 static const char *set_keep_alive_timeout(cmd_parms *cmd, void *dummy,
                                           const char *arg)
 {
@@ -61,6 +75,19 @@ static const char *set_keep_alive_timeout(cmd_parm
     if (ap_timeout_parameter_parse(arg, &timeout, "s") != APR_SUCCESS)
         return "KeepAliveTimeout has wrong format";
     cmd->server->keep_alive_timeout = timeout;
+
+    /* We don't want to take into account whether or not KeepAliveTimeout is
+     * set for the main server, because if no http_module directive is used
+     * for a vhost, it will inherit the http_srv_cfg from the main server.
+     * However keep_alive_timeout_set helps determine whether the vhost should
+     * use its own configured timeout or the one from the vhost delared first
+     * on the same IP:port (ie. c->base_server, and the legacy behaviour).
+     */
+    if (cmd->server->is_virtual) {
+        http_srv_cfg *scfg = ap_get_module_config(cmd->server->module_config,
+                                                  &http_module);
+        scfg->keep_alive_timeout_set = 1;
+    }
     return NULL;
 }
 
@@ -179,6 +206,12 @@ static int ap_process_http_sync_connection(conn_re
 
     ap_update_child_status_from_conn(c->sbh, SERVER_BUSY_READ, c);
     while ((r = ap_read_request(c)) != NULL) {
+        server_rec *s = r->server;
+        http_srv_cfg *scfg = ap_get_module_config(s->module_config,
+                                                  &http_module);
+        if (!scfg->keep_alive_timeout_set) {
+            s = c->base_server;
+        }
 
         c->keepalive = AP_CONN_UNKNOWN;
         /* process the request if it was read without error */
@@ -215,7 +248,7 @@ static int ap_process_http_sync_connection(conn_re
             csd = ap_get_conn_socket(c);
         }
         apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1);
-        apr_socket_timeout_set(csd, c->base_server->keep_alive_timeout);
+        apr_socket_timeout_set(csd, s->keep_alive_timeout);
         /* Go straight to select() to wait for the next request */
     }
 
@@ -301,7 +334,7 @@ AP_DECLARE_MODULE(http) = {
     STANDARD20_MODULE_STUFF,
     NULL,              /* create per-directory config structure */
     NULL,              /* merge per-directory config structures */
-    NULL,              /* create per-server config structure */
+    create_srv_cfg,    /* create per-server config structure */
     NULL,              /* merge per-server config structures */
     http_cmds,         /* command apr_table_t */
     register_hooks     /* register hooks */
