]> granicus.if.org Git - apache/commitdiff
Move the keepalives field out of the conn_rec and into an HTTP specific
authorRyan Bloom <rbb@apache.org>
Wed, 18 Apr 2001 03:53:34 +0000 (03:53 +0000)
committerRyan Bloom <rbb@apache.org>
Wed, 18 Apr 2001 03:53:34 +0000 (03:53 +0000)
connection record.  This also moves some HTTP specific back out of the
core and into the HTTP module.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88881 13f79535-47bb-0310-9956-ffa450edef68

include/httpd.h
modules/http/config.m4
modules/http/http_core.c
modules/http/http_protocol.c
modules/http/mod_core.h
modules/loggers/mod_log_config.c
server/protocol.c

index d1f00af5d8d8f0df52018b6c579bab007e7bbfa2..75610b671e78861b65cbfb217d6bc458dc526eb4 100644 (file)
@@ -860,14 +860,10 @@ struct conn_rec {
     unsigned aborted:1;
     /** Are we using HTTP Keep-Alive?  -1 fatal error, 0 undecided, 1 yes */
     signed int keepalive:2;
-    /** Did we use HTTP Keep-Alive? */
-    unsigned keptalive:1;
     /** have we done double-reverse DNS? -1 yes/failure, 0 not yet, 
      *  1 yes/success */
     signed int double_reverse:2;
 
-    /** How many times have we used it? */
-    int keepalives;
     /** server IP address */
     char *local_ip;
     /** used for ap_get_server_name when UseCanonicalName is set to DNS
index 6d581e586dfa5e91fccb4e645ea5242780d7c008..da29de1a798d21656b2df94dbed6129f47f63bb6 100644 (file)
@@ -7,5 +7,8 @@ http_objects="http_core.lo http_protocol.lo http_request.lo"
 APACHE_MODULE(http, HTTP protocol handling, $http_objects, , yes)
 APACHE_MODULE(mime, mapping of file-extension to MIME, , , yes)
 
+if test "$enable_http" = "yes"; then
+  AC_DEFINE(AP_HTTP_ENABLED, 1, [HTTP is enabled on this server])
+fi
 
 APACHE_MODPATH_FINISH
index f5948973ab6232eaa5c654851df3445cbe0ba0c6..ce6df793f1cf0820c9a53d237a696e178e0e08a4 100644 (file)
@@ -58,6 +58,7 @@
 
 #include "apr_strings.h"
 #include "apr_thread_proc.h"    /* for RLIMIT stuff */
+#include "apr_lib.h"
 
 #define APR_WANT_STRFUNC
 #include "apr_want.h"
@@ -65,6 +66,7 @@
 #define CORE_PRIVATE
 #include "httpd.h"
 #include "http_config.h"
+#include "http_log.h"
 #include "http_connection.h"
 #include "http_protocol.h"     /* For index_of_response().  Grump. */
 #include "http_request.h"
@@ -295,6 +297,151 @@ static int ap_process_http_connection(conn_rec *c)
     return OK;
 }
 
+static int read_request_line(request_rec *r)
+{
+    char l[DEFAULT_LIMIT_REQUEST_LINE + 2]; /* getline's two extra for \n\0 */
+    const char *ll = l;
+    const char *uri;
+    const char *pro;
+    int major = 1, minor = 0;   /* Assume HTTP/1.0 if non-"HTTP" protocol */
+    int len;
+    /* Read past empty lines until we get a real request line,
+     * a read error, the connection closes (EOF), or we timeout.
+     *
+     * We skip empty lines because browsers have to tack a CRLF on to the end
+     * of POSTs to support old CERN webservers.  But note that we may not
+     * have flushed any previous response completely to the client yet.
+     * We delay the flush as long as possible so that we can improve
+     * performance for clients that are pipelining requests.  If a request
+     * is pipelined then we won't block during the (implicit) read() below.
+     * If the requests aren't pipelined, then the client is still waiting
+     * for the final buffer flush from us, and we will block in the implicit
+     * read().  B_SAFEREAD ensures that the BUFF layer flushes if it will
+     * have to block during a read.
+     */
+    while ((len = ap_getline(l, sizeof(l), r, 0)) <= 0) {
+        if (len < 0) {             /* includes EOF */
+            /* this is a hack to make sure that request time is set,
+             * it's not perfect, but it's better than nothing
+             */
+            r->request_time = apr_time_now();
+            return 0;
+        }
+    }
+    /* we've probably got something to do, ignore graceful restart requests */
+    /* XXX - sigwait doesn't work if the signal has been SIG_IGNed (under
+     * linux 2.0 w/ glibc 2.0, anyway), and this step isn't necessary when
+     * we're running a sigwait thread anyway. If/when unthreaded mode is
+     * put back in, we should make sure to ignore this signal iff a sigwait
+     * thread isn't used. - mvsk
+#ifdef SIGWINCH
+    apr_signal(SIGWINCH, SIG_IGN);
+#endif
+    */
+    r->request_time = apr_time_now();
+    r->the_request = apr_pstrdup(r->pool, l);
+    r->method = ap_getword_white(r->pool, &ll);
+#if 0
+/* XXX If we want to keep track of the Method, the protocol module should do
+ * it.  That support isn't in the scoreboard yet.  Hopefully next week
+ * sometime.   rbb */
+    ap_update_connection_status(AP_CHILD_THREAD_FROM_ID(conn->id), "Method", r->method);
+#endif
+    uri = ap_getword_white(r->pool, &ll);
+    /* Provide quick information about the request method as soon as known */
+    r->method_number = ap_method_number_of(r->method);
+    if (r->method_number == M_GET && r->method[0] == 'H') {
+        r->header_only = 1;
+    }
+    ap_parse_uri(r, uri);
+    /* ap_getline returns (size of max buffer - 1) if it fills up the
+     * buffer before finding the end-of-line.  This is only going to
+     * happen if it exceeds the configured limit for a request-line.
+     */
+    if (len > r->server->limit_req_line) {
+        r->status    = HTTP_REQUEST_URI_TOO_LARGE;
+        r->proto_num = HTTP_VERSION(1,0);
+        r->protocol  = apr_pstrdup(r->pool, "HTTP/1.0");
+        return 0;
+    }
+    if (ll[0]) {
+        r->assbackwards = 0;
+        pro = ll;
+        len = strlen(ll);
+    } else {
+        r->assbackwards = 1;
+        pro = "HTTP/0.9";
+        len = 8;
+    }
+    r->protocol = apr_pstrndup(r->pool, pro, len);
+    /* XXX ap_update_connection_status(conn->id, "Protocol", r->protocol); */
+    /* Avoid sscanf in the common case */
+    if (len == 8 &&
+        pro[0] == 'H' && pro[1] == 'T' && pro[2] == 'T' && pro[3] == 'P' &&
+        pro[4] == '/' && apr_isdigit(pro[5]) && pro[6] == '.' &&
+        apr_isdigit(pro[7])) {
+        r->proto_num = HTTP_VERSION(pro[5] - '0', pro[7] - '0');
+    } else if (2 == sscanf(r->protocol, "HTTP/%u.%u", &major, &minor)
+               && minor < HTTP_VERSION(1,0))    /* don't allow HTTP/0.1000 */
+        r->proto_num = HTTP_VERSION(major, minor);
+    else
+        r->proto_num = HTTP_VERSION(1,0);
+    return 1;
+}
+
+static int http_create_request(request_rec *r)
+{
+    ap_http_conn_rec *hconn = ap_get_module_config(r->connection->conn_config, &http_module);
+    int keptalive;
+
+    hconn = apr_pcalloc(r->pool, sizeof(*hconn));
+    ap_set_module_config(r->connection->conn_config, &http_module, hconn);
+
+    if (!r->main && !r->prev && !r->next) {
+        keptalive = r->connection->keepalive == 1;
+        r->connection->keepalive    = 0;
+        /* XXX can we optimize these timeouts at all? gstein */
+        apr_setsocketopt(r->connection->client_socket, APR_SO_TIMEOUT,
+                         (int)(keptalive
+                         ? r->server->keep_alive_timeout * APR_USEC_PER_SEC
+                         : r->server->timeout * APR_USEC_PER_SEC));
+        /* Get the request... */
+        if (!read_request_line(r)) {
+            if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {
+                ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
+                              "request failed: URI too long");
+                ap_send_error_response(r, 0);
+                ap_run_log_transaction(r);
+                return OK;
+            }
+            return DONE;
+        }
+        if (keptalive) {
+            apr_setsocketopt(r->connection->client_socket,
+                             APR_SO_TIMEOUT,
+                             (int)(r->server->timeout * APR_USEC_PER_SEC));
+        }
+    }
+    return OK;
+}
+
 static void register_hooks(apr_pool_t *p)
 {
     ap_hook_pre_connection(ap_pre_http_connection,NULL,NULL,
@@ -303,6 +450,7 @@ static void register_hooks(apr_pool_t *p)
                               APR_HOOK_REALLY_LAST);
     ap_hook_http_method(http_method,NULL,NULL,APR_HOOK_REALLY_LAST);
     ap_hook_default_port(http_port,NULL,NULL,APR_HOOK_REALLY_LAST);
+    ap_hook_create_request(http_create_request, NULL, NULL, APR_HOOK_MIDDLE);
 
     ap_register_input_filter("HTTP_IN", ap_http_filter, AP_FTYPE_CONNECTION);
     ap_register_input_filter("DECHUNK", ap_dechunk_filter, AP_FTYPE_TRANSCODE);
index 9d765249d90c8ae916694219dfb282bda8df4704..ebbcd2231265030bc82d1e4cfc9c807930eecd52 100644 (file)
@@ -105,6 +105,7 @@ AP_DECLARE(int) ap_set_keepalive(request_rec *r)
     int ka_sent = 0;
     int wimpy = ap_find_token(r->pool,
                            apr_table_get(r->headers_out, "Connection"), "close");
+    ap_http_conn_rec *hconn = ap_get_module_config(r->connection->conn_config, &http_module);
     const char *conn = apr_table_get(r->headers_in, "Connection");
 
     /* The following convoluted conditional determines whether or not
@@ -146,7 +147,7 @@ AP_DECLARE(int) ap_set_keepalive(request_rec *r)
         && r->server->keep_alive
        && (r->server->keep_alive_timeout > 0)
        && ((r->server->keep_alive_max == 0)
-           || (r->server->keep_alive_max > r->connection->keepalives))
+           || (r->server->keep_alive_max > hconn->keepalives))
        && !ap_status_drops_connection(r->status)
        && !wimpy
        && !ap_find_token(r->pool, conn, "close")
@@ -154,10 +155,10 @@ AP_DECLARE(int) ap_set_keepalive(request_rec *r)
            || apr_table_get(r->headers_in, "Via"))
        && ((ka_sent = ap_find_token(r->pool, conn, "keep-alive"))
            || (r->proto_num >= HTTP_VERSION(1,1)))) {
-        int left = r->server->keep_alive_max - r->connection->keepalives;
+        int left = r->server->keep_alive_max - hconn->keepalives;
 
         r->connection->keepalive = 1;
-        r->connection->keepalives++;
+        hconn->keepalives++;
 
         /* If they sent a Keep-Alive token, send one back */
         if (ka_sent) {
index e9ff827ed1ad96f2bce8e829ce14d14f02e1d69c..477b98175476573ba2fe777284e008ef2f228c1a 100644 (file)
@@ -70,6 +70,13 @@ extern "C" {
  * @package mod_core private header file
  */
 
+typedef struct ap_http_conn_rec ap_http_conn_rec;
+
+struct ap_http_conn_rec {
+    /** How many times have we used it? */
+    int keepalives;
+};
+
 /*
  * These (input) filters are internal to the mod_core operation.
  */
@@ -92,6 +99,8 @@ AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb);
 AP_DECLARE(int) ap_send_http_trace(request_rec *r);
 int ap_send_http_options(request_rec *r);
 
+AP_DECLARE_DATA module http_module;
+
 #ifdef __cplusplus
 }
 #endif
index fbe7ec1ca7052bc341cfba418a29239d3579a35d..375da431152df46980ed727fc1dcf9052942b840 100644 (file)
 #include "http_core.h"          /* For REMOTE_NAME */
 #include "http_log.h"
 #include "http_protocol.h"
+#include "mod_core.h"
 
 #if APR_HAVE_UNISTD_H
 #include <unistd.h>
@@ -527,13 +528,19 @@ static const char *log_child_pid(request_rec *r, char *a)
 }
 static const char *log_connection_status(request_rec *r, char *a)
 {
+#ifdef AP_HTTP_ENABLED
+    ap_http_conn_rec *hconn = ap_get_module_config(r->connection->conn_config, 
+                                                &http_module);
+#endif
     if (r->connection->aborted)
         return "X";
 
+#ifdef AP_HTTP_ENABLED
     if ((r->connection->keepalive) &&
-        ((r->server->keep_alive_max - r->connection->keepalives) > 0)) {
+        ((r->server->keep_alive_max - hconn->keepalives) > 0)) {
         return "+";
     }
+#endif
 
     return "-";
 }
index 45395faabef96b572ec03601cdea83cbce0d1a0b..1e4aa6fc913427b26f3fb7088594f9c55593b6e0 100644 (file)
@@ -363,116 +363,6 @@ AP_CORE_DECLARE(void) ap_parse_uri(request_rec *r, const char *uri)
     }
 }
 
-static int read_request_line(request_rec *r)
-{
-    char l[DEFAULT_LIMIT_REQUEST_LINE + 2]; /* getline's two extra for \n\0 */
-    const char *ll = l;
-    const char *uri;
-    const char *pro;
-
-#if 0
-    conn_rec *conn = r->connection;
-#endif
-    int major = 1, minor = 0;   /* Assume HTTP/1.0 if non-"HTTP" protocol */
-    int len;
-
-    /* Read past empty lines until we get a real request line,
-     * a read error, the connection closes (EOF), or we timeout.
-     *
-     * We skip empty lines because browsers have to tack a CRLF on to the end
-     * of POSTs to support old CERN webservers.  But note that we may not
-     * have flushed any previous response completely to the client yet.
-     * We delay the flush as long as possible so that we can improve
-     * performance for clients that are pipelining requests.  If a request
-     * is pipelined then we won't block during the (implicit) read() below.
-     * If the requests aren't pipelined, then the client is still waiting
-     * for the final buffer flush from us, and we will block in the implicit
-     * read().  B_SAFEREAD ensures that the BUFF layer flushes if it will
-     * have to block during a read.
-     */
-
-    while ((len = ap_getline(l, sizeof(l), r, 0)) <= 0) {
-        if (len < 0) {             /* includes EOF */
-           /* this is a hack to make sure that request time is set,
-            * it's not perfect, but it's better than nothing 
-            */
-           r->request_time = apr_time_now();
-            return 0;
-        }
-    }
-    /* we've probably got something to do, ignore graceful restart requests */
-
-    /* XXX - sigwait doesn't work if the signal has been SIG_IGNed (under
-     * linux 2.0 w/ glibc 2.0, anyway), and this step isn't necessary when
-     * we're running a sigwait thread anyway. If/when unthreaded mode is
-     * put back in, we should make sure to ignore this signal iff a sigwait
-     * thread isn't used. - mvsk
-
-#ifdef SIGWINCH
-    apr_signal(SIGWINCH, SIG_IGN);
-#endif
-    */
-
-    r->request_time = apr_time_now();
-    r->the_request = apr_pstrdup(r->pool, l);
-    r->method = ap_getword_white(r->pool, &ll);
-
-#if 0
-/* XXX If we want to keep track of the Method, the protocol module should do
- * it.  That support isn't in the scoreboard yet.  Hopefully next week 
- * sometime.   rbb */
-    ap_update_connection_status(AP_CHILD_THREAD_FROM_ID(conn->id), "Method", r->method); 
-#endif
-    uri = ap_getword_white(r->pool, &ll);
-
-    /* Provide quick information about the request method as soon as known */
-
-    r->method_number = ap_method_number_of(r->method);
-    if (r->method_number == M_GET && r->method[0] == 'H') {
-        r->header_only = 1;
-    }
-
-    ap_parse_uri(r, uri);
-
-    /* ap_getline returns (size of max buffer - 1) if it fills up the
-     * buffer before finding the end-of-line.  This is only going to
-     * happen if it exceeds the configured limit for a request-line.
-     */
-    if (len > r->server->limit_req_line) {
-        r->status    = HTTP_REQUEST_URI_TOO_LARGE;
-        r->proto_num = HTTP_VERSION(1,0);
-        r->protocol  = apr_pstrdup(r->pool, "HTTP/1.0");
-        return 0;
-    }
-
-    if (ll[0]) {
-        r->assbackwards = 0;
-        pro = ll;
-        len = strlen(ll);
-    } else {
-        r->assbackwards = 1;
-        pro = "HTTP/0.9";
-        len = 8;
-    }
-    r->protocol = apr_pstrndup(r->pool, pro, len);
-
-    /* XXX ap_update_connection_status(conn->id, "Protocol", r->protocol); */
-
-    /* Avoid sscanf in the common case */
-    if (len == 8 &&
-        pro[0] == 'H' && pro[1] == 'T' && pro[2] == 'T' && pro[3] == 'P' &&
-        pro[4] == '/' && apr_isdigit(pro[5]) && pro[6] == '.' &&
-        apr_isdigit(pro[7])) {
-       r->proto_num = HTTP_VERSION(pro[5] - '0', pro[7] - '0');
-    } else if (2 == sscanf(r->protocol, "HTTP/%u.%u", &major, &minor)
-               && minor < HTTP_VERSION(1,0))   /* don't allow HTTP/0.1000 */
-       r->proto_num = HTTP_VERSION(major, minor);
-    else
-       r->proto_num = HTTP_VERSION(1,0);
-
-    return 1;
-}
-
 static void get_mime_headers(request_rec *r)
 {
     char field[DEFAULT_LIMIT_REQUEST_FIELDSIZE + 2]; /* getline's two extra */
@@ -556,9 +446,6 @@ request_rec *ap_read_request(conn_rec *conn)
     r->connection      = conn;
     r->server          = conn->base_server;
 
-    conn->keptalive    = conn->keepalive == 1;
-    conn->keepalive    = 0;
-
     r->user            = NULL;
     r->ap_auth_type    = NULL;
 
@@ -571,7 +458,9 @@ request_rec *ap_read_request(conn_rec *conn)
     r->notes           = apr_table_make(r->pool, 5);
 
     r->request_config  = ap_create_request_config(r->pool);
-    ap_run_create_request(r);
+    if (ap_run_create_request(r) != OK) {
+        return NULL;
+    }
     r->per_dir_config  = r->server->lookup_defaults;
 
     r->sent_bodyct     = 0;                      /* bytect isn't for body */
@@ -584,30 +473,10 @@ request_rec *ap_read_request(conn_rec *conn)
     r->output_filters  = conn->output_filters;
     r->input_filters   = conn->input_filters;
 
-    apr_setsocketopt(conn->client_socket, APR_SO_TIMEOUT, 
-                     (int)(conn->keptalive
-                     ? r->server->keep_alive_timeout * APR_USEC_PER_SEC
-                     : r->server->timeout * APR_USEC_PER_SEC));
-                     
     ap_add_output_filter("BYTERANGE", NULL, r, r->connection);
     ap_add_output_filter("CONTENT_LENGTH", NULL, r, r->connection);
     ap_add_output_filter("HTTP_HEADER", NULL, r, r->connection);
 
-    /* Get the request... */
-    if (!read_request_line(r)) {
-        if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {
-            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
-                         "request failed: URI too long");
-            ap_send_error_response(r, 0);
-            ap_run_log_transaction(r);
-            return r;
-        }
-        return NULL;
-    }
-    if (r->connection->keptalive) {
-        apr_setsocketopt(r->connection->client_socket, APR_SO_TIMEOUT,
-                         (int)(r->server->timeout * APR_USEC_PER_SEC));
-    }
     if (!r->assbackwards) {
         get_mime_headers(r);
         if (r->status != HTTP_REQUEST_TIME_OUT) {
@@ -646,8 +515,6 @@ request_rec *ap_read_request(conn_rec *conn)
     /* we may have switched to another server */
     r->per_dir_config = r->server->lookup_defaults;
 
-    conn->keptalive = 0;        /* We now have a request to play with */
-
     if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1,1))) ||
         ((r->proto_num == HTTP_VERSION(1,1)) &&
          !apr_table_get(r->headers_in, "Host"))) {