/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "httpd.h" #include "http_config.h" #include "http_log.h" #include "fcgid_filter.h" #include "fcgid_bucket.h" #include "fcgid_conf.h" apr_status_t fcgid_filter(ap_filter_t * f, apr_bucket_brigade * bb) { apr_status_t rv; apr_bucket_brigade *tmp_brigade; apr_size_t save_size = 0; conn_rec *c = f->c; server_rec *s = f->r->server; fcgid_server_conf *sconf = ap_get_module_config(s->module_config, &fcgid_module); tmp_brigade = apr_brigade_create(f->r->pool, f->r->connection->bucket_alloc); while (!APR_BRIGADE_EMPTY(bb)) { apr_size_t readlen; const char *buffer; apr_bucket *e = APR_BRIGADE_FIRST(bb); if (APR_BUCKET_IS_EOS(e)) break; if (APR_BUCKET_IS_METADATA(e)) { apr_bucket_delete(e); continue; } /* Read the bucket now */ if ((rv = apr_bucket_read(e, &buffer, &readlen, APR_BLOCK_READ)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, f->r, "mod_fcgid: can't read data from fcgid handler"); return rv; } /* Move on to next bucket if it's fastcgi header bucket */ if (e->type == &ap_bucket_type_fcgid_header || (e->type == &apr_bucket_type_immortal && readlen == 0)) { apr_bucket_delete(e); continue; } save_size += readlen; /* Cache it to tmp_brigade */ APR_BUCKET_REMOVE(e); APR_BRIGADE_INSERT_TAIL(tmp_brigade, e); /* I will pass tmp_brigade to next filter if I have got too much buckets */ if (save_size > sconf->output_buffersize) { APR_BRIGADE_INSERT_TAIL(tmp_brigade, apr_bucket_flush_create(f->r-> connection-> bucket_alloc)); if ((rv = ap_pass_brigade(f->next, tmp_brigade)) != APR_SUCCESS) return rv; /* Is the client aborted? */ if (c && c->aborted) return APR_SUCCESS; save_size = 0; } } /* Any thing left? */ if (!APR_BRIGADE_EMPTY(tmp_brigade)) { if ((rv = ap_pass_brigade(f->next, tmp_brigade)) != APR_SUCCESS) return rv; } /* This filter is done once it has served up its content */ ap_remove_output_filter(f); return APR_SUCCESS; }