]> granicus.if.org Git - apache/commitdiff
Connection oriented filters are now stored in the conn_rec instead of the
authorRyan Bloom <rbb@apache.org>
Wed, 4 Oct 2000 23:19:33 +0000 (23:19 +0000)
committerRyan Bloom <rbb@apache.org>
Wed, 4 Oct 2000 23:19:33 +0000 (23:19 +0000)
request_rec.  This means that a conn_rec must be supplied when calling
ap_add_filter.  The reason for this change is that we need to be able to
add the core_filter (whether or SSL or not) before we try to read the
request.  This way, if a request fails, we can actually send the error
page back to the client.  With this change, we add the core filter to the
conn_rec during the pre-connection phase.
Submitted by: Ryan Bloom, Jeff Trawick, and Greg Ames

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

include/httpd.h
include/util_filter.h
modules/http/http_core.c
modules/http/http_protocol.c
server/connection.c
server/util_filter.c

index f222e0d4baaa93140ffa9098baf1e06b22f6ac16..77086f946f9c3a06c60efd19e680d186a3fa42be 100644 (file)
@@ -885,6 +885,9 @@ struct conn_rec {
     /** Location to store data read from the client.
      *  @defvar ap_bucket_brigade *input_data */
     struct ap_bucket_brigade *input_data;
+    /** A list of output filters to be used for this connection
+     *  @defvar ap_filter_t *filters */
+    struct ap_filter_t *output_filters;
 };
 
 /* Per-vhost config... */
index c7b20ba867740ca79abe730f854b68ecd5a60a6c..2b4f760590ee8b75b79b3634697feda83501d8d9 100644 (file)
@@ -332,7 +332,8 @@ API_EXPORT(void) ap_add_input_filter(const char *name, void *ctx, conn_rec *r);
  * @param r The request to add this filter for.
  * @deffunc void ap_add_filter(const char *name, request_rec *r)
  */
-API_EXPORT(void) ap_add_filter(const char *name, void *ctx, request_rec *r);
+API_EXPORT(void) ap_add_filter(const char *name, void *ctx, request_rec *r,
+                               conn_rec *c);
 
 /* The next two filters are for abstraction purposes only.  They could be
  * done away with, but that would require that we break modules if we ever
index a910a546e79e5412a2dacd5b16668adea645afc2..7e5d63f325e60d561fb577ba0656e61d74772d0a 100644 (file)
@@ -2564,7 +2564,7 @@ static apr_status_t writev_it_all(apr_socket_t *s, struct iovec *vec, int nvec,
     return APR_SUCCESS;
 }
 /* XXX handle partial writes */
-static apr_status_t send_the_file(request_rec *r, apr_file_t *fd, 
+static apr_status_t send_the_file(conn_rec *c, apr_file_t *fd, 
                                   apr_hdtr_t *hdtr, apr_off_t offset, 
                                   apr_size_t length, apr_size_t *nbytes) 
 {
@@ -2573,11 +2573,11 @@ static apr_status_t send_the_file(request_rec *r, apr_file_t *fd,
     apr_size_t n = length;
 
 #if APR_HAS_SENDFILE
-    if (!r->connection->keepalive) {
+    if (!c->keepalive) {
         /* Prepare the socket to be reused */
         flags |= APR_SENDFILE_DISCONNECT_SOCKET;
     }
-    rv = apr_sendfile(r->connection->client->bsock, 
+    rv = apr_sendfile(c->client->bsock, 
                       fd,      /* The file to send */
                       hdtr,    /* Header and trailer iovecs */
                       &offset, /* Offset in file to begin sending from */
@@ -2592,6 +2592,7 @@ static apr_status_t send_the_file(request_rec *r, apr_file_t *fd,
 
     return APR_SUCCESS;
 }
+
 /* Note --- ErrorDocument will now work from .htaccess files.  
  * The AllowOverride of Fileinfo allows webmasters to turn it off
  */
@@ -3286,7 +3287,7 @@ static int core_output_filter(ap_filter_t *f, ap_bucket_brigade *b)
     ap_bucket_brigade *more = NULL;
     apr_ssize_t bytes_sent = 0, nbytes = 0;
     ap_bucket *e;
-    request_rec *r = f->r;
+    conn_rec *c = f->c;
     core_output_filter_ctx_t *ctx = f->ctx;
 
     apr_ssize_t nvec = 0;
@@ -3299,7 +3300,7 @@ static int core_output_filter(ap_filter_t *f, ap_bucket_brigade *b)
     apr_off_t foffset = 0;
 
     if (ctx == NULL) {
-        f->ctx = ctx = apr_pcalloc(r->pool, sizeof(core_output_filter_ctx_t));
+        f->ctx = ctx = apr_pcalloc(c->pool, sizeof(core_output_filter_ctx_t));
     }
     /* If we have a saved brigade, concatenate the new brigade to it */
     if (ctx->b) {
@@ -3309,10 +3310,10 @@ static int core_output_filter(ap_filter_t *f, ap_bucket_brigade *b)
     }
 
     /* Hijack any bytes in BUFF and prepend it to the brigade. */
-    if (r->connection->client->outcnt) {
-        e = ap_bucket_create_heap(r->connection->client->outbase,
-                                  r->connection->client->outcnt, 1, NULL);
-        r->connection->client->outcnt = 0;
+    if (c->client->outcnt) {
+        e = ap_bucket_create_heap(c->client->outbase,
+                                  c->client->outcnt, 1, NULL);
+        c->client->outcnt = 0;
         AP_BRIGADE_INSERT_HEAD(b, e);
     }
 
@@ -3376,10 +3377,10 @@ static int core_output_filter(ap_filter_t *f, ap_bucket_brigade *b)
                 hdtr.numtrailers = nvec_trailers;
                 hdtr.trailers = vec_trailers;
             }
-            rv = send_the_file(r, fd, &hdtr, foffset, flen, &bytes_sent);
+            rv = send_the_file(c, fd, &hdtr, foffset, flen, &bytes_sent);
         }
         else {
-            rv = writev_it_all(r->connection->client->bsock, 
+            rv = writev_it_all(c->client->bsock, 
                                vec, nvec, 
                                nbytes, &bytes_sent);
             nbytes = 0; /* in case more points to another brigade */
@@ -3423,12 +3424,6 @@ static const char *core_method(const request_rec *r)
 static unsigned short core_port(const request_rec *r)
     { return DEFAULT_HTTP_PORT; }
 
-static int core_post_read_req(request_rec *r)
-{
-    ap_add_filter("CORE", NULL, r);
-    return DECLINED;
-}
-
 static void core_register_filter(request_rec *r)
 {
     int i;
@@ -3439,7 +3434,7 @@ static void core_register_filter(request_rec *r)
 
     for (i = 0; i < conf->filters->nelts; i++) {
         char *foobar = items[i];
-        ap_add_filter(foobar, NULL, r);
+        ap_add_filter(foobar, NULL, r, r->connection);
     }
 }
 
@@ -3457,7 +3452,6 @@ static void register_hooks(void)
     /* FIXME: I suspect we can eliminate the need for these - Ben */
     ap_hook_type_checker(do_nothing,NULL,NULL,AP_HOOK_REALLY_LAST);
     ap_hook_access_checker(do_nothing,NULL,NULL,AP_HOOK_REALLY_LAST);
-    ap_hook_post_read_request(core_post_read_req, NULL, NULL, AP_HOOK_REALLY_FIRST);
 
     /* define the CORE filter, then register a hook to insert it at
      * request-processing time.
index 2e6b6feafbc2d8be2a261e61d63ffd776799bb4a..3d3cb942cebaf76c3e4f7a6cbd0cee389637478a 100644 (file)
@@ -1244,6 +1244,7 @@ request_rec *ap_read_request(conn_rec *conn)
 
     r->status          = HTTP_REQUEST_TIME_OUT;  /* Until we get a request */
     r->the_request     = NULL;
+    r->output_filters  = conn->output_filters;
 
 #ifdef APACHE_XLATE
     r->rrx = apr_pcalloc(p, sizeof(struct ap_rr_xlate));
@@ -2108,8 +2109,8 @@ API_EXPORT(void) ap_send_http_header(request_rec *r)
     if (r->chunked) {
         apr_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
         apr_table_unset(r->headers_out, "Content-Length");
-        ap_add_filter("BUFFER", NULL, r);
-        ap_add_filter("CHUNK", NULL, r);
+        ap_add_filter("BUFFER", NULL, r, r->connection);
+        ap_add_filter("CHUNK", NULL, r, r->connection);
     }
 
     if (r->byterange > 1) {
index 9b1e04942ec08617ebc50e55785285769df879de..3eb453761fcb1a2c99a81dd5bb86fc05e8d73946 100644 (file)
@@ -217,6 +217,7 @@ CORE_EXPORT(void) ap_process_connection(conn_rec *c)
 int ap_pre_http_connection(conn_rec *c)
 {
     ap_add_input_filter("CORE_IN", NULL, c);
+    ap_add_filter("CORE", NULL, NULL, c);
     return OK;
 }
 
index c7641c3c3fdefc86a1c3c2e007fe8b823576f30d..f95532b6aad74b54809734e2cb5051faa0cc104a 100644 (file)
@@ -148,25 +148,28 @@ API_EXPORT(void) ap_add_input_filter(const char *name, void *ctx, conn_rec *c)
     }
 }
 
-API_EXPORT(void) ap_add_filter(const char *name, void *ctx, request_rec *r)
+API_EXPORT(void) ap_add_filter(const char *name, void *ctx, request_rec *r,
+                               conn_rec *c)
 {
     ap_filter_rec_t *frec = registered_output_filters;
 
     for (; frec != NULL; frec = frec->next) {
         if (!strcasecmp(name, frec->name)) {
-            ap_filter_t *f = apr_pcalloc(r->pool, sizeof(*f));
+            apr_pool_t *p = r ? r->pool : c->pool;
+            ap_filter_t *f = apr_pcalloc(p, sizeof(*f));
+            ap_filter_t **outf = r ? &r->output_filters : &c->output_filters;
 
             f->frec = frec;
             f->ctx = ctx;
             f->r = r;
-            f->c = NULL;
+            f->c = c;
 
-            if (INSERT_BEFORE(f, r->output_filters)) {
-                f->next = r->output_filters;
-                r->output_filters = f;
+            if (INSERT_BEFORE(f, *outf)) {
+                f->next = *outf;
+                *outf = f;
             }
             else {
-                ap_filter_t *fscan = r->output_filters;
+                ap_filter_t *fscan = *outf;
                 while (!INSERT_BEFORE(f, fscan->next))
                     fscan = fscan->next;
                 f->next = fscan->next;
@@ -201,7 +204,7 @@ API_EXPORT(apr_status_t) ap_get_brigade(ap_filter_t *next, ap_bucket_brigade *bb
 API_EXPORT(apr_status_t) ap_pass_brigade(ap_filter_t *next, ap_bucket_brigade *bb)
 {
     if (next) {
-        if (AP_BRIGADE_LAST(bb)->type == AP_BUCKET_EOS) {
+        if (AP_BRIGADE_LAST(bb)->type == AP_BUCKET_EOS && next->r) {
             next->r->eos_sent = 1;
         }
         return next->frec->filter_func(next, bb);
@@ -213,12 +216,13 @@ API_EXPORT(void) ap_save_brigade(ap_filter_t *f, ap_bucket_brigade **saveto,
                                         ap_bucket_brigade **b)
 {
     ap_bucket *e;
+    apr_pool_t *p = f->r ? f->r->pool : f->c->pool;
 
     /* If have never stored any data in the filter, then we had better
      * create an empty bucket brigade so that we can concat.
      */
     if (!(*saveto)) {
-        *saveto = ap_brigade_create(f->r->pool);
+        *saveto = ap_brigade_create(p);
     }
     
     AP_RING_FOREACH(e, &(*b)->list, ap_bucket, link) {