]> granicus.if.org Git - apache/blobdiff - server/connection.c
Cleanup the ZZZ comments. Basically these used to mark places where APR
[apache] / server / connection.c
index 4cdfbcf5e0fe3faea27ce152ac9d8c865a8d9889..a3bbd78792e0798db0aec211d67d52dbe560d37c 100644 (file)
 #include "http_request.h"
 #include "http_protocol.h"
 #include "ap_mpm.h"
+#include "mpm_status.h"
 #include "http_config.h"
 #include "http_vhost.h"
 
-/* TODO: re-implement the lingering close stuff */
+HOOK_STRUCT(
+           HOOK_LINK(pre_connection)
+           HOOK_LINK(process_connection)
+)
+
+IMPLEMENT_HOOK_VOID(pre_connection,(conn_rec *c),(c))
+IMPLEMENT_HOOK_RUN_FIRST(int,process_connection,(conn_rec *c),(c),DECLINED)
+
+/* TODO: reimplement the lingering close stuff */
 #define NO_LINGCLOSE
 
 /*
 #ifdef USE_SO_LINGER
 #define NO_LINGCLOSE           /* The two lingering options are exclusive */
 
-static void sock_enable_linger(int s) // ZZZZZ abstract the socket, s
+static void sock_enable_linger(int s) 
 {
-    struct linger li;                 // ZZZZZ SocketOptions...
+    struct linger li;                 
 
     li.l_onoff = 1;
     li.l_linger = MAX_SECS_TO_LINGER;
 
-    if (setsockopt(s, SOL_SOCKET, SO_LINGER, // ZZZZZ abstract, return SUCCESS or not
+    if (setsockopt(s, SOL_SOCKET, SO_LINGER, 
                   (char *) &li, sizeof(struct linger)) < 0) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, server_conf,
                    "setsockopt: (SO_LINGER)");
@@ -121,10 +130,9 @@ static void sock_enable_linger(int s) // ZZZZZ abstract the socket, s
  * distinguish between a dropped connection and something that might be
  * worth logging.
  */
-/*ZZZ this routine needs to be adapted for use with poll()*/
 static void lingering_close(request_rec *r)     
 {
-  /*ZZZ remove the hardwired 512. This is an IO Buffer Size */
+  /*TODO remove the hardwired 512. This is an IO Buffer Size */
     char dummybuf[512];    
     struct pollfd pd;
     int lsd;
@@ -137,7 +145,7 @@ static void lingering_close(request_rec *r)
 
     /* Send any leftover data to the client, but never try to again */
 
-    if (ap_bflush(r->connection->client) == -1) {
+    if (ap_bflush(r->connection->client) != APR_SUCCESS) {
        ap_bclose(r->connection->client);
        return;
     }
@@ -147,7 +155,7 @@ static void lingering_close(request_rec *r)
 
     lsd = r->connection->client->fd;
 
-    if ((shutdown(lsd, 1) != 0)  /* ZZZ abstract shutdown */
+    if ((shutdown(lsd, 1) != 0)  
         || ap_is_aborted(r->connection)) {
        ap_bclose(r->connection->client);
        return;
@@ -175,63 +183,119 @@ static void lingering_close(request_rec *r)
         pd.revents = 0;
     } while ((poll(&pd, 1, 2) == 1)   
              && read(lsd, dummybuf, sizeof(dummybuf)));
-      /* && (time() = epoch) < max_wait); */    /* ZZZZ time function is not good... */
+      /* && (time() = epoch) < max_wait); */    
 
     /* Should now have seen final ack.  Safe to finally kill socket */
     ap_bclose(r->connection->client);
 }
 #endif /* ndef NO_LINGCLOSE */
 
-
 CORE_EXPORT(void) ap_process_connection(conn_rec *c)
 {
-    request_rec *r;
-
     ap_update_vhost_given_ip(c);
 
+    ap_run_pre_connection(c);
+
+    ap_run_process_connection(c);
+
+    /*
+     * Close the connection, being careful to send out whatever is still
+     * in our buffers.  If possible, try to avoid a hard close until the
+     * client has ACKed our FIN and/or has stopped sending us data.
+     */
+
+#ifdef NO_LINGCLOSE
+    ap_bclose(c->client);      /* just close it */
+#else
+    if (r && r->connection
+       && !r->connection->aborted
+       && r->connection->client
+       && (r->connection->client->fd >= 0)) {
+
+       lingering_close(r);
+    }
+    else {
+       ap_bsetflag(c->client, B_EOUT, 1);
+       ap_bclose(c->client);
+    }
+#endif
+}
+
+int ap_process_http_connection(conn_rec *c)
+    {
+    request_rec *r;
+
     /*
      * Read and process each request found on our connection
      * until no requests are left or we decide to close.
      */
 
+    ap_update_connection_status(c->id, "Status", "Reading");
     while ((r = ap_read_request(c)) != NULL) {
 
        /* process the request if it was read without error */
 
+        ap_update_connection_status(c->id, "Status", "Writing");
        if (r->status == HTTP_OK)
            ap_process_request(r);
 
        if (!c->keepalive || c->aborted)
            break;
 
+        ap_update_connection_status(c->id, "Status", "Keepalive");
        ap_destroy_pool(r->pool);
 
-       if (ap_mpm_graceful_stop()) {
+       if (ap_graceful_stop_signalled()) {
            /* XXX: hey wait, this should do a lingering_close! */
            ap_bclose(c->client);
-           return;
+           return OK;
        }
     }
 
-    /*
-     * Close the connection, being careful to send out whatever is still
-     * in our buffers.  If possible, try to avoid a hard close until the
-     * client has ACKed our FIN and/or has stopped sending us data.
+    ap_reset_connection_status(c->id);
+    return OK;
+}
+
+/* Clearly some of this stuff doesn't belong in a generalised connection
+   structure, but for now...
+*/
+
+conn_rec *ap_new_connection(ap_context_t *p, server_rec *server, BUFF *inout,
+                           const struct sockaddr_in *remaddr,
+                           const struct sockaddr_in *saddr, long id)
+{
+    conn_rec *conn = (conn_rec *) ap_pcalloc(p, sizeof(conn_rec));
+
+    /* Got a connection structure, so initialize what fields we can
+     * (the rest are zeroed out by pcalloc).
      */
 
-#ifdef NO_LINGCLOSE
-    ap_bclose(c->client);      /* just close it */
-#else
-    if (r && r->connection
-       && !r->connection->aborted
-       && r->connection->client
-       && (r->connection->client->fd >= 0)) {
+    conn->conn_config=ap_create_conn_config(p);
 
-       lingering_close(r);
-    }
-    else {
-       ap_bsetflag(c->client, B_EOUT, 1);
-       ap_bclose(c->client);
-    }
-#endif
+    conn->pool = p;
+    conn->local_addr = *saddr;
+    conn->local_ip = ap_pstrdup(conn->pool,
+                               inet_ntoa(conn->local_addr.sin_addr));
+    conn->base_server = server;
+    conn->client = inout;
+
+    conn->remote_addr = *remaddr;
+    conn->remote_ip = ap_pstrdup(conn->pool,
+                             inet_ntoa(conn->remote_addr.sin_addr));
+    
+    conn->id = id;
+
+    return conn;
+}
+
+
+
+conn_rec *ap_new_apr_connection(ap_context_t *p, server_rec *server, BUFF *inout,
+                           const ap_socket_t *conn_socket, long id)
+{
+    struct sockaddr_in *sa_local, *sa_remote;
+
+    ap_get_local_name(&sa_local, conn_socket);
+    ap_get_remote_name(&sa_remote, conn_socket);
+    return ap_new_connection(p, server, inout, sa_remote, sa_local, id);
 }