/*
 * 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;
    int 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;
}
