Return-Path: Delivered-To: apmail-httpd-test-dev-archive@httpd.apache.org Received: (qmail 37166 invoked by uid 500); 23 Feb 2002 05:33:10 -0000 Mailing-List: contact test-dev-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: test-dev@httpd.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list test-dev@httpd.apache.org Received: (qmail 37155 invoked from network); 23 Feb 2002 05:33:10 -0000 Message-ID: <3C7729A2.7030906@apache.org> Date: Fri, 22 Feb 2002 21:33:22 -0800 From: Ian Holsman User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:0.9.8+) Gecko/20020220 X-Accept-Language: en-us MIME-Version: 1.0 To: test-dev@httpd.apache.org Subject: [submission] mod-bucketeer Content-Type: multipart/mixed; boundary="------------030505080302050904060305" X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N --------------030505080302050904060305 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit thought this module would be of use to people over here. I'm currently using it to test mod-include. what it does: - parses incoming stream of bytes. IF it finds a '^B' or a '^F' it will create a new bucket at this point and will insert a flush bucket (if you specify ^F) why is this usefull: - testing mod-include boundry conditions and other wierd & wonderfull things with weird bucket sizes. ..Ian --------------030505080302050904060305 Content-Type: text/plain; name="mod_bucketeer.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mod_bucketeer.c" /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * * Portions of this software are based upon public domain software * (zlib functions gz_open and gzwrite) */ /* * mod_bucketeer.c: split buckets whenever we find a control-char * * Written by Ian Holsman (IanH@apache.org) * */ #include "httpd.h" #include "http_config.h" #include "http_log.h" #include "apr_strings.h" #include "apr_general.h" #include "util_filter.h" #include "apr_buckets.h" #include "http_request.h" static const char bucketeerFilterName[] = "BUCKETEER"; module AP_MODULE_DECLARE_DATA bucketeer_module; typedef struct bucketeer_filter_config_t { char bucketdelimter; char flushdelimiter; } bucketeer_filter_config_t; static void *create_bucketeer_server_config(apr_pool_t *p, server_rec *s) { bucketeer_filter_config_t *c = apr_pcalloc(p, sizeof *c); c->bucketdelimter = 0x02; /* ^B */ c->flushdelimiter = 0x06; /* ^F */ return c; } typedef struct bucketeer_ctx_t { apr_bucket_brigade *bb; } bucketeer_ctx_t; static apr_status_t bucketeer_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) { apr_bucket *e; request_rec *r = f->r; bucketeer_ctx_t *ctx = f->ctx; bucketeer_filter_config_t *c = ap_get_module_config(r->server->module_config, &bucketeer_module); /* If we don't have a context, we need to ensure that it is okay to send * the deflated content. If we have a context, that means we've done * this before and we liked it. * This could be not so nice if we always fail. But, if we succeed, * we're in better shape. */ if (!ctx) { if (strncmp(r->content_type, "text/", 5)) { ap_remove_output_filter(f); return ap_pass_brigade(f->next, bb); } /* We're cool with filtering this. */ ctx = f->ctx = apr_pcalloc(f->r->pool, sizeof(*ctx)); ctx->bb = apr_brigade_create(f->r->pool); } APR_BRIGADE_FOREACH(e, bb) { const char *data; apr_size_t len; int done = 0; apr_size_t i; apr_size_t lastpos; if (APR_BUCKET_IS_EOS(e)) { APR_BUCKET_REMOVE(e); APR_BRIGADE_INSERT_TAIL(ctx->bb, e); /* Okay, we've seen the EOS. * Time to pass it along down the chain. */ return ap_pass_brigade(f->next, ctx->bb); } if (APR_BUCKET_IS_FLUSH(e)) { /* * Ignore flush buckets for the moment.. * we decide what to stream */ continue; } /* read */ apr_bucket_read(e, &data, &len, APR_BLOCK_READ); if (len>0) { lastpos=0; for (i=0; iflushdelimiter ) { apr_bucket *p; if ( i-lastpos-1>0) { p = apr_bucket_pool_create(apr_pmemdup( f->r->pool, &data[lastpos], i-lastpos), i-lastpos, f->r->pool); APR_BRIGADE_INSERT_TAIL(ctx->bb,p); } lastpos=i+1; p = apr_bucket_flush_create(); APR_BRIGADE_INSERT_TAIL(ctx->bb,p); } else { if (data[i] == c->bucketdelimter) { apr_bucket *p; if ( i-lastpos-1>0) { p = apr_bucket_pool_create(apr_pmemdup( f->r->pool, &data[lastpos], i-lastpos), i-lastpos, f->r->pool); APR_BRIGADE_INSERT_TAIL(ctx->bb,p); } lastpos=i+1; } } } /* XXX: really should append this to the next 'real' bucket */ if ( lastpos < i ) { apr_bucket *p; p = apr_bucket_pool_create(apr_pmemdup( f->r->pool,&data[lastpos],i-lastpos),i-lastpos,f->r->pool); lastpos=i; APR_BRIGADE_INSERT_TAIL(ctx->bb,p); } } } return APR_SUCCESS; } static void register_hooks(apr_pool_t * p) { ap_register_output_filter(bucketeerFilterName, bucketeer_out_filter, AP_FTYPE_CONTENT-1); } static const command_rec bucketeer_filter_cmds[] = { {NULL} }; module AP_MODULE_DECLARE_DATA bucketeer_module = { STANDARD20_MODULE_STUFF, NULL, NULL, create_bucketeer_server_config, NULL, bucketeer_filter_cmds, register_hooks }; --------------030505080302050904060305--