You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by tr...@locus.apache.org on 2000/10/05 18:55:21 UTC

cvs commit: apache-2.0/src/main http_connection.c http_core.c http_protocol.c http_request.c util_filter.c

trawick     00/10/05 09:55:18

  Modified:    src/include http_core.h httpd.h util_filter.h
               src/main http_connection.c http_core.c http_protocol.c
                        http_request.c util_filter.c
  Log:
  Add a bit of infrastructure which will be needed for input filtering:
  
  1) separate filter lists hanging off the r and the c
  
     requests start off with the same filter list as the connection
  
     the input filter list is not initialized for subrequests
  
     internal redirects start off with the same filter list as the
     connection
  
  2) AddInputFilter directive (blatant rip-off of Ryan's AddOutputFilter
     directive); as with AddOutputFilter, the network is implicitly to the
     right of the specified filter list; this may not be the most
     intuitive way to specify the filters; not sure yet
  
  Revision  Changes    Path
  1.25      +1 -0      apache-2.0/src/include/http_core.h
  
  Index: http_core.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/include/http_core.h,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- http_core.h	2000/09/13 23:13:16	1.24
  +++ http_core.h	2000/10/05 16:54:52	1.25
  @@ -423,6 +423,7 @@
   #endif    
   
       apr_array_header_t *filters;
  +    apr_array_header_t *input_filters;
   } core_dir_config;
   
   /* Per-server core configuration */
  
  
  
  1.91      +4 -1      apache-2.0/src/include/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/include/httpd.h,v
  retrieving revision 1.90
  retrieving revision 1.91
  diff -u -r1.90 -r1.91
  --- httpd.h	2000/10/05 11:21:11	1.90
  +++ httpd.h	2000/10/05 16:54:54	1.91
  @@ -806,8 +806,11 @@
   #endif /*APACHE_XLATE*/
   
       /** A list of output filters to be used for this request 
  -     *  @defvar ap_filter_t *filters */
  +     *  @defvar ap_filter_t *output_filters */
       struct ap_filter_t *output_filters;
  +    /** A list of input filters to be used for this request 
  +     *  @defvar ap_filter_t *filters */
  +    struct ap_filter_t *input_filters;
       /** A flag to determine if the eos bucket has been sent yet
        *  @defvar int eos_sent */
       int eos_sent;
  
  
  
  1.23      +3 -2      apache-2.0/src/include/util_filter.h
  
  Index: util_filter.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/include/util_filter.h,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- util_filter.h	2000/10/05 12:01:37	1.22
  +++ util_filter.h	2000/10/05 16:54:55	1.23
  @@ -320,10 +320,11 @@
    * Add a filter to the current connection.  Filters are added in a FIFO manner.
    * The first filter added will be the first filter called.
    * @param name The name of the filter to add
  + * @param r The request to add this filter for (or NULL if it isn't associated with a request)
    * @param c The connection to add the fillter for
  - * @deffunc void ap_add_input_filter(const char *name, void *ctx, conn_rec *r)
  + * @deffunc void ap_add_input_filter(const char *name, void *ctx, request_rec *r, conn_rec *c)
    */
  -API_EXPORT(void) ap_add_input_filter(const char *name, void *ctx, conn_rec *r);
  +API_EXPORT(void) ap_add_input_filter(const char *name, void *ctx, request_rec *r, conn_rec *c);
   
   /**
    * Add a filter to the current request.  Filters are added in a FIFO manner.
  
  
  
  1.50      +1 -1      apache-2.0/src/main/http_connection.c
  
  Index: http_connection.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_connection.c,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- http_connection.c	2000/10/05 12:01:41	1.49
  +++ http_connection.c	2000/10/05 16:55:03	1.50
  @@ -216,7 +216,7 @@
   
   int ap_pre_http_connection(conn_rec *c)
   {
  -    ap_add_input_filter("CORE_IN", NULL, c);
  +    ap_add_input_filter("CORE_IN", NULL, NULL, c);
       ap_add_output_filter("CORE", NULL, NULL, c);
       return OK;
   }
  
  
  
  1.145     +22 -1     apache-2.0/src/main/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_core.c,v
  retrieving revision 1.144
  retrieving revision 1.145
  diff -u -r1.144 -r1.145
  --- http_core.c	2000/10/05 12:01:40	1.144
  +++ http_core.c	2000/10/05 16:55:04	1.145
  @@ -187,6 +187,7 @@
       conf->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME;
   
       conf->filters = apr_make_array(a, 2, sizeof(void *));
  +    conf->input_filters = apr_make_array(a, 2, sizeof(void *));
       return (void *)conf;
   }
   
  @@ -327,6 +328,8 @@
   	}
       }
       conf->filters = apr_append_arrays(a, base->filters, new->filters);
  +    conf->input_filters = apr_append_arrays(a, base->input_filters,
  +                                            new->input_filters);
   
       return (void*)conf;
   }
  @@ -1884,6 +1887,16 @@
       return NULL;
   }
   
  +static const char *add_input_filter(cmd_parms *cmd, void *dummy, const char *arg)
  +{
  +    core_dir_config *conf = dummy;
  +    char **newfilter;
  +    
  +    newfilter = (char **)apr_push_array(conf->input_filters);
  +    *newfilter = apr_pstrdup(cmd->pool, arg);
  +    return NULL;
  +}
  +
   static const char *add_module_command(cmd_parms *cmd, void *dummy,
   				      const char *arg)
   {
  @@ -2765,13 +2778,15 @@
   AP_INIT_TAKE12("RLimitNPROC", no_set_limit, NULL,
      OR_ALL, "soft/hard limits for max number of processes per uid"),
   #endif
  -/* XXX This should be allowable in .htaccess files, but currently it won't
  +/* XXX These should be allowable in .htaccess files, but currently it won't
    * play well with the Options stuff.  Until that is fixed, I would prefer
    * to leave it just in the conf file.  Other should feel free to disagree
    * with me.  Rbb.
    */
   AP_INIT_ITERATE("AddOutputFilter", add_filter, NULL, ACCESS_CONF,
      "filters to be run"),
  +AP_INIT_ITERATE("AddInputFilter", add_input_filter, NULL, ACCESS_CONF,
  +   "filters to be run on the request body"),
   { NULL }
   };
   
  @@ -3435,6 +3450,12 @@
       for (i = 0; i < conf->filters->nelts; i++) {
           char *foobar = items[i];
           ap_add_output_filter(foobar, NULL, r, r->connection);
  +    }
  +
  +    items = (char **)conf->input_filters->elts;
  +    for (i = 0; i < conf->input_filters->nelts; i++) {
  +        char *foobar = items[i];
  +        ap_add_input_filter(foobar, NULL, r, r->connection);
       }
   }
   
  
  
  
  1.143     +1 -0      apache-2.0/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v
  retrieving revision 1.142
  retrieving revision 1.143
  diff -u -r1.142 -r1.143
  --- http_protocol.c	2000/10/05 14:00:59	1.142
  +++ http_protocol.c	2000/10/05 16:55:08	1.143
  @@ -1249,6 +1249,7 @@
       r->status          = HTTP_REQUEST_TIME_OUT;  /* Until we get a request */
       r->the_request     = NULL;
       r->output_filters  = conn->output_filters;
  +    r->input_filters   = conn->input_filters;
   
   #ifdef APACHE_XLATE
       r->rrx = apr_pcalloc(p, sizeof(struct ap_rr_xlate));
  
  
  
  1.54      +3 -0      apache-2.0/src/main/http_request.c
  
  Index: http_request.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_request.c,v
  retrieving revision 1.53
  retrieving revision 1.54
  diff -u -r1.53 -r1.54
  --- http_request.c	2000/10/05 11:21:23	1.53
  +++ http_request.c	2000/10/05 16:55:09	1.54
  @@ -780,6 +780,7 @@
   
       /* start with the same set of output filters */
       rnew->output_filters = r->output_filters;
  +    /* no input filters for a subrequest */
   
       ap_set_sub_req_protocol(rnew, r);
   
  @@ -875,6 +876,7 @@
   
       /* start with the same set of output filters */
       rnew->output_filters = r->output_filters;
  +    /* no input filters for a subrequest */
   
       ap_set_sub_req_protocol(rnew, r);
       fdir = ap_make_dirstr_parent(rnew->pool, r->filename);
  @@ -1374,6 +1376,7 @@
       new->vlist_validator = r->vlist_validator;
   
       new->output_filters  = r->connection->output_filters;
  +    new->input_filters   = r->connection->input_filters;
   
       apr_table_setn(new->subprocess_env, "REDIRECT_STATUS",
   	apr_psprintf(r->pool, "%d", r->status));
  
  
  
  1.27      +10 -7     apache-2.0/src/main/util_filter.c
  
  Index: util_filter.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/util_filter.c,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- util_filter.c	2000/10/05 12:01:41	1.26
  +++ util_filter.c	2000/10/05 16:55:10	1.27
  @@ -118,25 +118,28 @@
                       &registered_output_filters);
   }
   
  -API_EXPORT(void) ap_add_input_filter(const char *name, void *ctx, conn_rec *c)
  +API_EXPORT(void) ap_add_input_filter(const char *name, void *ctx, 
  +                                     request_rec *r, conn_rec *c)
   {
       ap_filter_rec_t *frec = registered_input_filters;
   
       for (; frec != NULL; frec = frec->next) {
           if (!strcasecmp(name, frec->name)) {
  -            ap_filter_t *f = apr_pcalloc(c->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->input_filters : &c->input_filters;
   
               f->frec = frec;
               f->ctx = ctx;
  -            f->r = NULL;
  +            f->r = r;
               f->c = c;
   
  -            if (INSERT_BEFORE(f, c->input_filters)) {
  -                f->next = c->input_filters;
  -                c->input_filters = f;
  +            if (INSERT_BEFORE(f, *outf)) {
  +                f->next = *outf;
  +                *outf = f;
               }
               else {
  -                ap_filter_t *fscan = c->input_filters;
  +                ap_filter_t *fscan = *outf;
                   while (!INSERT_BEFORE(f, fscan->next))
                       fscan = fscan->next;
                   f->next = fscan->next;
  
  
  

Re: cvs commit: apache-2.0/src/main http_connection.c http_core.c http_protocol.c http_request.c util_filter.c

Posted by Jeff Trawick <tr...@bellsouth.net>.
rbb@covalent.net writes:

> > > Does this make sense?  How do we add input filters for a request?  We
> > > don't even have the request until after the input filters have been
> > > run.  
> > 
> > It should be o.k. to run through connection filters before we have set
> > up request filters.  That is o.k. on output (for second response)...
> > Why not on input?
> 
> All input filters are request filters.  That's what I'm trying to
> explain.  It isn't possible to add an input content filter.  At least, not
> that I can see working everytime.

I'm stuck already :(

Maybe my terminology is bad, because I have a hard time accepting that
it doesn't work (every time) to have an "input content filter."  Does
it work every time in 1.3 to have a request body and deliver it to a
handler that wants it?  If so, then it shouldn't be too hard to let a
filter play with the data in between the piece of code that knows how
to split off the request body and the handler.

Is this terminology wrong?

  request filter

    a filter which runs only within the scope of a particular request;
    it doesn't necessarily run on all requests on a connection

  input content filter

    a filter which transforms (or passes through unchanged) the
    request body (e.g., POST-ed data); an input content filter is a
    request filter

-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

Re: cvs commit: apache-2.0/src/main http_connection.c http_core.c http_protocol.c http_request.c util_filter.c

Posted by rb...@covalent.net.
On Thu, 5 Oct 2000, Greg Ames wrote:
> rbb@covalent.net wrote:

> I can envision a couple of ways to do that:
> 
> o Invent some kind of bucket unget operation, if one doesn't exist already.
> o Have a buffer that both getline() and ap_get_client_block() are allowed to
> access.  I would keep this out of http_protocol.

I have now detailed four times the correct way to do this with another
filter.  I have also said I will do it as soon as I get
ap_get_client_block working.  It doesn't make any sense to write the new
filter before ap_get_client_block works, because there is no way to test
the filter.  Expect the code sometime tonight or tomorrow.  I am about
twenty minutes away from really hacking on this code again.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: cvs commit: apache-2.0/src/main http_connection.c http_core.c http_protocol.c http_request.c util_filter.c

Posted by Greg Ames <gr...@raleigh.ibm.com>.
rbb@covalent.net wrote:
> 
> > > All of this assumes that CORE_IN has some understanding of HTTP, it
> > > doesn't, and it shouldn't.  The whole point of CORE_IN, is that it only
> > > understands reading from the network.
> > >
> >
[...]
> >                                   getline() has to be able to logically
> > extract just one line and nothing more.  
[...]

>           Getline parses it for a single line and saves the rest off to
> the side.  

That is the root of the problem.  ap_get_client_block has to be able to get
every byte of data beyond the LF that terminated the last header line. 
Saving it off to the side is what we want to do to get reasonable
performance, but once we're out of header mode and ap_get_client_block is
called, it needs a way to get whatever data was saved off to the side, in
addition to what's in buckets.  

I can envision a couple of ways to do that:

o Invent some kind of bucket unget operation, if one doesn't exist already.
o Have a buffer that both getline() and ap_get_client_block() are allowed to
access.  I would keep this out of http_protocol.

Greg

Re: cvs commit: apache-2.0/src/main http_connection.c http_core.c http_protocol.c http_request.c util_filter.c

Posted by rb...@covalent.net.
On 5 Oct 2000, Jeff Trawick wrote:

> rbb@covalent.net writes:
> 
> > A new input content filter cannot be added between the call to
> > ap_get_brigade and the time that it returns. 
> 
> Where do you see this happening in what I was talking about earlier?

The problem is that your patch makes the two filter types look similar,
even though they aren't.  The other problem is that what you want to do
won't currently work.  It just won't work yet.  It is technically
possible, but it requires a new filter to be written and added in all
cases.  But, that filter only makes sense for HTTP requests.  I will try
to make that all work, after I have finished with ap_get_client_block.

The biggest thing I am against from your patch though, is that it makes
input and output filters look alike even though they are very different.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: cvs commit: apache-2.0/src/main http_connection.c http_core.c http_protocol.c http_request.c util_filter.c

Posted by Jeff Trawick <tr...@bellsouth.net>.
rbb@covalent.net writes:

> A new input content filter cannot be added between the call to
> ap_get_brigade and the time that it returns. 

Where do you see this happening in what I was talking about earlier?

-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

Re: cvs commit: apache-2.0/src/main http_connection.c http_core.c http_protocol.c http_request.c util_filter.c

Posted by rb...@covalent.net.
> > All of this assumes that CORE_IN has some understanding of HTTP, it
> > doesn't, and it shouldn't.  The whole point of CORE_IN, is that it only
> > understands reading from the network.
> > 
> 
> CORE_IN doesn't need to know about HTTP.  Having it only understand network
> stuff and bucket brigades is perfect.  But it needs to co-operate with the
> protocol code above it that does know about HTTP.  getline()'s callers know
> when header lines are expected, and getline() has to be able to logically
> extract just one line and nothing more.  But there will be other code for
> uploads that will need to get data from CORE_IN.  

We're not communicating here.  There is no such concept as an input
request header currently.  It is not currently possible.  The reason for
this, is that the CORE_IN filter returns a chunk of data to
getline.  Getline parses it for a single line and saves the rest off to
the side.  That's how it currently works.  Getline isn't really a filter,
it is more analogous to a handler.

Later, when ap_get_client_block is called, it doesn't call getline.  It
will need to go either straight to the conn_rec, or it will have to call
ap_get_brigade.  Currently, if a body is sent with a request, it is likely
to be stored in the conn_rec.  This means that the data has already been
filtered.  It can't be filtered again, because it was filtered once when
the request was originally read.  There is no way currently for a request
body to go throught request input filters.

The only solution, is to have a filter that understands HTTP, and that can
break the brigade into multiple pieces of headers and bodies.  This filter
would keep a buffer of the input data until it was requested to give it to
the core.  This isn't in place, so there is no such thing as an input
request filter.  This doesn't even make sense to put into place until
ap_get_client block is finished (which I'm currently working on).

> The code that separates headers from request bodies worked last week (I
> think :-); we have enough Smart People (tm) hanging out on this list to get
> it working again if it's currently broken.  So if we can separate inbound
> headers from request bodies, why not let the request bodies flow thru
> inbound content filters if somebody wants to do that?

It's broken, because we added filtering.  This isn't a question of Smart
People (tm), it's a question of design.  input and output filters are not
orthogonal.  They can't be orthogonal, because the design doesn't allow
it.  Trying to pretend that they are is a mistake.

A new input content filter cannot be added between the call to
ap_get_brigade and the time that it returns.  input filters cannot be
removed between the call to ap_get_brigade and the time that it
returns.  Both of these limitations do not exist with output filters.  I
am trying to stress the fact that input and output filters do NOT work the
same way in this server.  The commit I am questioning makes them look very
similar on the surface, even though they are fundamentally different.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: cvs commit: apache-2.0/src/main http_connection.c http_core.c http_protocol.c http_request.c util_filter.c

Posted by Greg Ames <gr...@raleigh.ibm.com>.
rbb@covalent.net wrote:

> > What about the request body (and maybe even the header of the next
> > request) in the same buffer read by CORE_IN (or SSL)?
> >
> >   It doesn't matter that the request body is in the same packet as the
> >   request headers.  CORE_IN and getline() have to work together so that
> >   any data after the header is made available to CORE_IN for the next
> >   time it is called.
> >
> >   getline() is called repeatably to grab the request line and header
> >   fields.  It only cares about the conn_rec filters.  When it gets to
> >   the end of the header any unparsed data must be chained back on the
> >   conn_rec for CORE_IN (or SSL) to access again.
> 
> All of this assumes that CORE_IN has some understanding of HTTP, it
> doesn't, and it shouldn't.  The whole point of CORE_IN, is that it only
> understands reading from the network.
> 

CORE_IN doesn't need to know about HTTP.  Having it only understand network
stuff and bucket brigades is perfect.  But it needs to co-operate with the
protocol code above it that does know about HTTP.  getline()'s callers know
when header lines are expected, and getline() has to be able to logically
extract just one line and nothing more.  But there will be other code for
uploads that will need to get data from CORE_IN.  

The code that separates headers from request bodies worked last week (I
think :-); we have enough Smart People (tm) hanging out on this list to get
it working again if it's currently broken.  So if we can separate inbound
headers from request bodies, why not let the request bodies flow thru
inbound content filters if somebody wants to do that?

Greg

Re: cvs commit: apache-2.0/src/main http_connection.c http_core.c http_protocol.c http_request.c util_filter.c

Posted by rb...@covalent.net.
> > Does this make sense?  How do we add input filters for a request?  We
> > don't even have the request until after the input filters have been
> > run.  
> 
> It should be o.k. to run through connection filters before we have set
> up request filters.  That is o.k. on output (for second response)...
> Why not on input?

All input filters are request filters.  That's what I'm trying to
explain.  It isn't possible to add an input content filter.  At least, not
that I can see working everytime.

> >       If you are thinking of the request body, that won't work.  Most
> > browsers send the request body in the same packet as the request headers,
> > so the body will actually be stored in the conn_rec's bucket_brigade, and
> > the body will never get to go through the input_filters that were added
> > after reading the request.
> 
> What about the request body (and maybe even the header of the next
> request) in the same buffer read by CORE_IN (or SSL)?
> 
>   It doesn't matter that the request body is in the same packet as the
>   request headers.  CORE_IN and getline() have to work together so that
>   any data after the header is made available to CORE_IN for the next
>   time it is called.
> 
>   getline() is called repeatably to grab the request line and header
>   fields.  It only cares about the conn_rec filters.  When it gets to
>   the end of the header any unparsed data must be chained back on the
>   conn_rec for CORE_IN (or SSL) to access again.

All of this assumes that CORE_IN has some understanding of HTTP, it
doesn't, and it shouldn't.  The whole point of CORE_IN, is that it only
understands reading from the network.

The problem is that when the CORE_IN filter reads a block, it does just
that, it reads a block of data, and it doesn't understand anything about
the format of the input.  It then passes this input back up to the
previous filter.  In this case, the previous filter is getline.  Getline
takes that data and parses into one line chunks.  If there is more than
one line, then getline stores that extra data in c->input_data until it is
called again.  That's it.  That's all the filters there are.

When ap_get_client_block is called, the data has already been
filtered.  It can't be filtered again, that's not a good idea, we can't
garuantee that the filters will allow the same data to be filtered twice.

The only solution that would allow for request input filters, is to have a
filter above the core filter that understands HTTP, and knows how to break
apart the headers from the body and from the next set of headers.  That
filter would have to do it's own buffering of the input data, just passing
up a single block of data at a time.  That filter hasn't been written yet,
and I haven't really given it any thought at all.

Regardless, all filters must be on the filter stack before the first input
filter is called.  Adding an input filter while in the middle of filtering
the input will not cause the new filter to be called.

> If/when ap_get_client_block is called by a handler...
> 
>   call ap_get_brigade(r->input_filters) instead of ap_bread()
> 
>   If no request-specific filters were added, r->input_filters is
>   CORE_IN.
> 
>   If request-specific filters were added, r->input_filters is a not
>   CORE_IN, but eventually CORE_IN will be called to deliver data from
>   the client (possibly already read and stored by getline() or
>   CORE_IN in the conn_rec).

CORE_IN does not get data from the conn_rec.  It can't.  That data would
have been filtered twice.

> What about the end of the request body?
> 
>   The end of the request body is signaled by one of three things
>   (AFAIK :) ):
> 
>   a) end of connection
>   b) client provided Content-Length field in header and we've seen
>      that many bytes
>   c) chunked encoding was used and we've hit the trailing chunk header
> 
>   Somehow the request body filters need to get EOS (or equivalent)
>   when one of these happens.

That is not true.  BUFF didn't have an EOS concept.  The input filters
will end up working the same way.  The client will get a block of data,
and they will do with it as they please.

> 
>   Case a) is pretty simple...
> 
>   Case b)...  Theoretically, the CORE_IN filter could take care of
>   this (know the content-length and how many bytes had been delivered
>   so far), but CORE_IN doesn't know anything about the r and isn't
>   supposed to know such details.  If we have content-length in the
>   header, we can throw in a filter between the request body filters
>   and CORE_IN to insert EOS at the right point and make any extra data
>   returned by CORE_IN available to CORE_IN on the next pass.
> 
>   Case c)...  The CHUNK_IN filter needs to return eos at the right
>   point (not hard), and make any extra data returned to it available
>   to CORE_IN on the next pass.
> 
> > The more I look at our current filtering scheme, the more it looks like
> > input filters are only valid if they are added before the request is read
> > from the network.
> 
> Why is that true of content filters?  

Because the data is passed back through all of the filters when it is
first read.  If we want to change that fine, but currently, what you hve
added doesn't make sense, and it won't work.

I can fix it later today or tomorrow if you would like me to.  It requires
a new filter.  Which I was going to add anyway.  The new filter would
solve two problems.  1)  The input would be parsed into headers and body
segments, which would be passed up to the higher filters when data was
requested.  2)  The /r/n issue would move down to that filter, because it
doesn't really belong in getline.

Ryan



_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------



Re: cvs commit: apache-2.0/src/main http_connection.c http_core.c http_protocol.c http_request.c util_filter.c

Posted by Jeff Trawick <tr...@bellsouth.net>.
rbb@covalent.net writes:

> On 5 Oct 2000 trawick@locus.apache.org wrote:
> 
> > trawick     00/10/05 09:55:18
> > 
> >   Modified:    src/include http_core.h httpd.h util_filter.h
> >                src/main http_connection.c http_core.c http_protocol.c
> >                         http_request.c util_filter.c
> >   Log:
> >   Add a bit of infrastructure which will be needed for input filtering:
> >   
> >   1) separate filter lists hanging off the r and the c
> >   
> >      requests start off with the same filter list as the connection
> >   
> >      the input filter list is not initialized for subrequests
> >   
> >      internal redirects start off with the same filter list as the
> >      connection
> 
> Does this make sense?  How do we add input filters for a request?  We
> don't even have the request until after the input filters have been
> run.  

It should be o.k. to run through connection filters before we have set
up request filters.  That is o.k. on output (for second response)...
Why not on input?

>       If you are thinking of the request body, that won't work.  Most
> browsers send the request body in the same packet as the request headers,
> so the body will actually be stored in the conn_rec's bucket_brigade, and
> the body will never get to go through the input_filters that were added
> after reading the request.

What about the request body (and maybe even the header of the next
request) in the same buffer read by CORE_IN (or SSL)?

  It doesn't matter that the request body is in the same packet as the
  request headers.  CORE_IN and getline() have to work together so that
  any data after the header is made available to CORE_IN for the next
  time it is called.

  getline() is called repeatably to grab the request line and header
  fields.  It only cares about the conn_rec filters.  When it gets to
  the end of the header any unparsed data must be chained back on the
  conn_rec for CORE_IN (or SSL) to access again.

If/when ap_get_client_block is called by a handler...

  call ap_get_brigade(r->input_filters) instead of ap_bread()

  If no request-specific filters were added, r->input_filters is
  CORE_IN.

  If request-specific filters were added, r->input_filters is a not
  CORE_IN, but eventually CORE_IN will be called to deliver data from
  the client (possibly already read and stored by getline() or
  CORE_IN in the conn_rec).

What about the end of the request body?

  The end of the request body is signaled by one of three things
  (AFAIK :) ):

  a) end of connection
  b) client provided Content-Length field in header and we've seen
     that many bytes
  c) chunked encoding was used and we've hit the trailing chunk header

  Somehow the request body filters need to get EOS (or equivalent)
  when one of these happens.

  Case a) is pretty simple...

  Case b)...  Theoretically, the CORE_IN filter could take care of
  this (know the content-length and how many bytes had been delivered
  so far), but CORE_IN doesn't know anything about the r and isn't
  supposed to know such details.  If we have content-length in the
  header, we can throw in a filter between the request body filters
  and CORE_IN to insert EOS at the right point and make any extra data
  returned by CORE_IN available to CORE_IN on the next pass.

  Case c)...  The CHUNK_IN filter needs to return eos at the right
  point (not hard), and make any extra data returned to it available
  to CORE_IN on the next pass.

> The more I look at our current filtering scheme, the more it looks like
> input filters are only valid if they are added before the request is read
> from the network.

Why is that true of content filters?  
-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

Re: cvs commit: apache-2.0/src/main http_connection.c http_core.c http_protocol.c http_request.c util_filter.c

Posted by rb...@covalent.net.
On 5 Oct 2000 trawick@locus.apache.org wrote:

> trawick     00/10/05 09:55:18
> 
>   Modified:    src/include http_core.h httpd.h util_filter.h
>                src/main http_connection.c http_core.c http_protocol.c
>                         http_request.c util_filter.c
>   Log:
>   Add a bit of infrastructure which will be needed for input filtering:
>   
>   1) separate filter lists hanging off the r and the c
>   
>      requests start off with the same filter list as the connection
>   
>      the input filter list is not initialized for subrequests
>   
>      internal redirects start off with the same filter list as the
>      connection

Does this make sense?  How do we add input filters for a request?  We
don't even have the request until after the input filters have been
run.  If you are thinking of the request body, that won't work.  Most
browsers send the request body in the same packet as the request headers,
so the body will actually be stored in the conn_rec's bucket_brigade, and
the body will never get to go through the input_filters that were added
after reading the request.

The more I look at our current filtering scheme, the more it looks like
input filters are only valid if they are added before the request is read
from the network.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------



Re: cvs commit: apache-2.0/src/main http_connection.c http_core.c http_protocol.c http_request.c util_filter.c

Posted by rb...@covalent.net.
On 5 Oct 2000 trawick@locus.apache.org wrote:

> trawick     00/10/05 09:55:18
> 
>   Modified:    src/include http_core.h httpd.h util_filter.h
>                src/main http_connection.c http_core.c http_protocol.c
>                         http_request.c util_filter.c
>   Log:
>   Add a bit of infrastructure which will be needed for input filtering:
>   
>   1) separate filter lists hanging off the r and the c
>   
>      requests start off with the same filter list as the connection
>   
>      the input filter list is not initialized for subrequests
>   
>      internal redirects start off with the same filter list as the
>      connection

Does this make sense?  How do we add input filters for a request?  We
don't even have the request until after the input filters have been
run.  If you are thinking of the request body, that won't work.  Most
browsers send the request body in the same packet as the request headers,
so the body will actually be stored in the conn_rec's bucket_brigade, and
the body will never get to go through the input_filters that were added
after reading the request.

The more I look at our current filtering scheme, the more it looks like
input filters are only valid if they are added before the request is read
from the network.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------