/******************************************************************************
 * Copyright (C) 2006 Tetsuya Kimata <kimata@acapulco.dyndns.org>
 *
 * All rights reserved.
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must
 *    not claim that you wrote the original software. If you use this
 *    software in a product, an acknowledgment in the product
 *    documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and must
 *    not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 *    distribution.
 *
 * $Id: ApacheResponse.h 2220 2006-12-10 06:10:27Z svn $
 *****************************************************************************/

#ifndef APACHE_RESPONSE_H
#define APACHE_RESPONSE_H

#include "http_protocol.h"
#include "http_request.h"

#include "Environment.h"

#include "apr_strings.h"
#include "apr_network_io.h"

#include "Uncopyable.h"

using namespace std;

class ApacheResponseWriter;
class ApacheRequestReader;

/**
 * @brief Apache のレスポンスを表すクラス．
 */
class ApacheResponse: public Uncopyable {
public:
    typedef request_rec Handle;
    typedef ApacheRequestReader  Reader;
    typedef ApacheResponseWriter Writer;

    static const char *get_request_uri(Handle *r)
    {
        return r->uri;
    };
    static const char *get_content_type(Handle *r)
    {
        const char *content_type;

        content_type = apr_table_get(r->headers_in, "Content-Type");

        if (content_type == NULL) {
            return "";
        }

        return content_type;
    };
    static apr_size_t get_content_size(Handle *r)
    {
        const char *content_size;

        content_size = apr_table_get(r->headers_in, "Content-Length");

        if (content_size == NULL) {
            return 0;
        }

        return static_cast<apr_size_t>(apr_atoi64(content_size));
    };
    static const char *get_query(Handle *r)
    {
        const char *query;

        query = r->args;

        if (query == NULL) {
            return "";
        }

        return query;
    };
    static const char *get_remote_ip(Handle *r)
    {
        return r->connection->remote_ip;
    };
    static apr_sockaddr_t *get_remote_addr(Handle *r)
    {
        return r->connection->remote_addr;
    };
    static const char *get_user_agent(Handle *r)
    {
        const char *agent;

        agent = apr_table_get(r->headers_in, "User-Agent");

        if (agent == NULL) {
            return "";
        }

        return agent;
    }
    static bool is_head_method(Handle *r)
    {
        return (r->header_only != 0);
    };
    static bool is_post_method(Handle *r)
    {
        return (r->method_number == M_POST);
    };
    static int is_meets_condition(Handle *r)
    {
        return ap_meets_conditions(r);
    };
    static int prepare_post_read(Handle *r)
    {
        int status;

        if ((status = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK) {
            return status;
        }
        if (ap_should_client_block(r) == 0) {
            return HTTP_NO_CONTENT;
        }

        return OK;
    };
    static void set_modified_time(Handle *r, apr_time_t time)
    {
        ap_update_mtime(r, time);
    };
    static void set_last_modified(Handle *r, apr_time_t time)
    {
        ap_set_last_modified(r);
    };
    static void set_content_type(Handle *r, const char *content_type)
    {
        ap_set_content_type(r, content_type);
    };
    static void set_accept_ranges(Handle *r)
    {
        apr_table_setn(r->headers_out, "Accept-Ranges", "bytes");
    }
    static void set_location(Handle *r, const char *uri)
    {
        apr_table_set(r->headers_out, "Location", uri);
    };
    static void set_content_disposition(Handle *r, const char *dispos)
    {
        apr_table_set(r->headers_out, "Content-Disposition", dispos);
    };
    static void set_env(Handle *r, const char *name, const char *value)
    {
        apr_table_setn(r->subprocess_env, name, value);
    };
};

#endif

// Local Variables:
// mode: c++
// coding: utf-8-dos
// End:
