/* 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.
 */

/*
 * mod_data.c --- Turn the response into an rfc2397 data URL, suitable for
 *                displaying as inline content on a page.
 */

#include "apr.h"
#include "apr_strings.h"
#include "apr_buckets.h"
#include "apr_base64.h"
#include "apr_lib.h"

#include "ap_config.h"
#include "util_filter.h"
#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "http_request.h"
#include "http_protocol.h"

#define DATA_FILTER "DATA"

module AP_MODULE_DECLARE_DATA data_module;

typedef struct data_ctx
{
    unsigned char overflow[3];
    int count;
    apr_bucket_brigade *bb;
} data_ctx;

/**
 * Create a data URL as follows:
 *
 * data:[<mime-type>;][charset=<charset>;]base64,<payload>
 *
 * Where:
 *
 * mime-type: The mime type of the original response.
 * charset: The optional character set corresponding to the mime type.
 * payload: A base64 version of the response body.
 *
 * The content type of the response is set to text/plain.
 *
 * The Content-Length header, if present, is updated with the new content
 * length based on the increase in size expected from the base64 conversion.
 * If the Content-Length header is too large to fit into an int, we remove
 * the Content-Length header instead.
 */
static apr_status_t data_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
{
    apr_bucket *e, *ee;
    request_rec *r = f->r;
    data_ctx *ctx = f->ctx;
    apr_status_t rv = APR_SUCCESS;

    /* first time in? create a context */
    if (!ctx) {
        char *type;
        char *charset = NULL;
        char *end;
        const char *content_length;

        /* base64-ing won't work on subrequests, it would be nice if
         * it did. Within subrequests, we have no EOS to check for,
         * so we don't know when to flush the tail to the network.
         */
        if (!ap_is_initial_req(f->r)) {
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next, bb);
        }

        ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
        ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);

        type = apr_pstrdup(r->pool, r->content_type);
        if (type) {
            charset = strchr(type, ' ');
            if (charset) {
                *charset++ = 0;
                end = strchr(charset, ' ');
                if (end) {
                    *end++ = 0;
                }
            }
        }

        apr_brigade_printf(ctx->bb, NULL, NULL, "data:%s%s;base64,",
                type ? type : "", charset ? charset : "");

        content_length = apr_table_get(r->headers_out, "Content-Length");
        if (content_length) {
            apr_off_t len, clen;
            apr_brigade_length(ctx->bb, 1, &len);
            clen = apr_atoi64(content_length);
            if (clen >= 0 && clen < APR_INT32_MAX) {
                ap_set_content_length(r, len +
                                      apr_base64_encode_len((int)clen) - 1);
            }
            else {
                apr_table_unset(r->headers_out, "Content-Length");
            }
        }

        ap_set_content_type(r, "text/plain");

    }

    /* Do nothing if asked to filter nothing. */
    if (APR_BRIGADE_EMPTY(bb)) {
        return ap_pass_brigade(f->next, bb);
    }

    while (APR_SUCCESS == rv && !APR_BRIGADE_EMPTY(bb)) {
        const char *data;
        apr_size_t size;
        apr_size_t tail;
        apr_size_t len;
        /* buffer big enough for 8000 encoded bytes (6000 raw bytes) and terminator */
        char buffer[APR_BUCKET_BUFF_SIZE + 1];
        char encoded[((sizeof(ctx->overflow)) / 3) * 4 + 1];

        e = APR_BRIGADE_FIRST(bb);

        /* EOS means we are done. */
        if (APR_BUCKET_IS_EOS(e)) {

            /* write away the tail */
            if (ctx->count) {
                len = apr_base64_encode_binary(encoded, ctx->overflow,
                        ctx->count);
                apr_brigade_write(ctx->bb, NULL, NULL, encoded, len - 1);
                ctx->count = 0;
            }

            /* pass the EOS across */
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(ctx->bb, e);

            /* pass what we have down the chain */
            ap_remove_output_filter(f);
            rv = ap_pass_brigade(f->next, ctx->bb);

            /* pass any stray buckets after the EOS down the stack */
            if ((APR_SUCCESS == rv) && (!APR_BRIGADE_EMPTY(bb))) {
               rv = ap_pass_brigade(f->next, bb);
            }
            continue;
        }

        /* flush what we can, we can't flush the tail until EOS */
        if (APR_BUCKET_IS_FLUSH(e)) {

            /* pass the flush bucket across */
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(ctx->bb, e);

            /* pass what we have down the chain */
            rv = ap_pass_brigade(f->next, ctx->bb);
            continue;
        }

        /* metadata buckets are preserved as is */
        if (APR_BUCKET_IS_METADATA(e)) {
            /*
             * Remove meta data bucket from old brigade and insert into the
             * new.
             */
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
            continue;
        }

        /* make sure we don't read more than 6000 bytes at a time */
        apr_brigade_partition(bb, (APR_BUCKET_BUFF_SIZE / 4 * 3), &ee);

        /* size will never be more than 6000 bytes */
        if (APR_SUCCESS == (rv = apr_bucket_read(e, &data, &size,
                APR_BLOCK_READ))) {

            /* fill up and write out our overflow buffer if partially used */
            while (size && ctx->count && ctx->count < sizeof(ctx->overflow)) {
                ctx->overflow[ctx->count++] = *data++;
                size--;
            }
            if (ctx->count == sizeof(ctx->overflow)) {
                len = apr_base64_encode_binary(encoded, ctx->overflow,
                        sizeof(ctx->overflow));
                apr_brigade_write(ctx->bb, NULL, NULL, encoded, len - 1);
                ctx->count = 0;
            }

            /* write the main base64 chunk */
            tail = size % sizeof(ctx->overflow);
            size -= tail;
            if (size) {
                len = apr_base64_encode_binary(buffer,
                        (const unsigned char *) data, size);
                apr_brigade_write(ctx->bb, NULL, NULL, buffer, len - 1);
            }

            /* save away any tail in the overflow buffer */
            if (tail) {
                memcpy(ctx->overflow, data + size, tail);
                ctx->count += tail;
            }

            apr_bucket_delete(e);

            /* pass what we have down the chain */
            rv = ap_pass_brigade(f->next, ctx->bb);
            if (rv) {
                /* should break out of the loop, since our write to the client
                 * failed in some way. */
                continue;
            }

        }

    }

    return rv;

}

static const command_rec data_cmds[] = { { NULL } };

static void register_hooks(apr_pool_t *p)
{
    ap_register_output_filter(DATA_FILTER, data_out_filter, NULL,
            AP_FTYPE_RESOURCE);
}
AP_DECLARE_MODULE(data) = { STANDARD20_MODULE_STUFF,
    NULL,  /* create per-directory config structure */
    NULL, /* merge per-directory config structures */
    NULL, /* create per-server config structure */
    NULL, /* merge per-server config structures */
    data_cmds, /* command apr_table_t */
    register_hooks /* register hooks */
};
