#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)");
* 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;
/* 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;
}
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;
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);
}