/* Copyright 2002-2004 Justin Erenkrantz and Greg Stein
 *
 * Licensed 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.
 */

#ifndef _SERF_PRIVATE_H_
#define _SERF_PRIVATE_H_

/* ### what the hell? why does the APR interface have a "size" ??
   ### the implication is that, if we bust this limit, we'd need to
   ### stop, rebuild a pollset, and repopulate it. what suckage.  */
#define MAX_CONN 16

/* Windows does not define IOV_MAX, so we need to ensure it is defined. */
#ifndef IOV_MAX
/* There is no limit for iovec count on Windows, but apr_socket_sendv
   allocates WSABUF structures on stack if vecs_count <= 50. */
#define IOV_MAX 50
#endif

/* Older versions of APR do not have this macro.  */
#ifdef APR_SIZE_MAX
#define REQUESTED_MAX APR_SIZE_MAX
#else
#define REQUESTED_MAX (~((apr_size_t)0))
#endif

#define SERF_IO_CLIENT (1)
#define SERF_IO_CONN (2)
#define SERF_IO_LISTENER (3)

/* Internal logging facilities, set flag to 1 to enable console logging for
   the selected component. */
#define SSL_VERBOSE 0
#define SSL_MSG_VERBOSE 0  /* logs decrypted requests and responses. */
#define SOCK_VERBOSE 0
#define SOCK_MSG_VERBOSE 0 /* logs bytes received from or written to a socket. */
#define CONN_VERBOSE 0
#define AUTH_VERBOSE 0

/* Older versions of APR do not have the APR_VERSION_AT_LEAST macro. Those
   implementations are safe.

   If the macro *is* defined, and we're on WIN32, and APR is version 1.4.0+,
   then we have a broken WSAPoll() implementation.

   See serf_context_create_ex() below.  */
#if defined(APR_VERSION_AT_LEAST) && defined(WIN32)
#if APR_VERSION_AT_LEAST(1,4,0)
#define BROKEN_WSAPOLL
#endif
#endif

typedef struct serf__authn_scheme_t serf__authn_scheme_t;

typedef struct serf_io_baton_t {
    int type;
    union {
        serf_incoming_t *client;
        serf_connection_t *conn;
        serf_listener_t *listener;
    } u;
} serf_io_baton_t;

/* Holds all the information corresponding to a request/response pair. */
struct serf_request_t {
    serf_connection_t *conn;

    apr_pool_t *respool;
    serf_bucket_alloc_t *allocator;

    /* The bucket corresponding to the request. Will be NULL once the
     * bucket has been emptied (for delivery into the socket).
     */
    serf_bucket_t *req_bkt;

    serf_request_setup_t setup;
    void *setup_baton;

    serf_response_acceptor_t acceptor;
    void *acceptor_baton;

    serf_response_handler_t handler;
    void *handler_baton;

    serf_bucket_t *resp_bkt;

    int writing_started;
    int priority;
    /* 1 if this is a request to setup a SSL tunnel, 0 for normal requests. */
    int ssltunnel;

    /* This baton is currently only used for digest authentication, which
       needs access to the uri of the request in the response handler.
       If serf_request_t is replaced by a serf_http_request_t in the future,
       which knows about uri and method and such, this baton won't be needed
       anymore. */
    void *auth_baton;

    struct serf_request_t *next;
};

typedef struct serf_pollset_t {
    /* the set of connections to poll */
    apr_pollset_t *pollset;
} serf_pollset_t;

typedef struct serf__authn_info_t {
    const serf__authn_scheme_t *scheme;

    void *baton;

    int failed_authn_types;
} serf__authn_info_t;

struct serf_context_t {
    /* the pool used for self and for other allocations */
    apr_pool_t *pool;

    void *pollset_baton;
    serf_socket_add_t pollset_add;
    serf_socket_remove_t pollset_rm;

    /* one of our connections has a dirty pollset state. */
    int dirty_pollset;

    /* the list of active connections */
    apr_array_header_t *conns;
#define GET_CONN(ctx, i) (((serf_connection_t **)(ctx)->conns->elts)[i])

    /* Proxy server address */
    apr_sockaddr_t *proxy_address;

    /* Progress callback */
    serf_progress_t progress_func;
    void *progress_baton;
    apr_off_t progress_read;
    apr_off_t progress_written;

    /* authentication info for the servers used in this context. Shared by all
       connections to the same server.
       Structure of the hashtable:  key: host url, e.g. https://localhost:80
                                  value: serf__authn_info_t *
     */
    apr_hash_t *server_authn_info;

    /* authentication info for the proxy configured in this context, shared by
       all connections. */
    serf__authn_info_t proxy_authn_info;

    /* List of authn types supported by the client.*/
    int authn_types;
    /* Callback function used to get credentials for a realm. */
    serf_credentials_callback_t cred_cb; 
};

struct serf_listener_t {
    serf_context_t *ctx;
    serf_io_baton_t baton;
    apr_socket_t *skt;
    apr_pool_t *pool;
    apr_pollfd_t desc;
    void *accept_baton;
    serf_accept_client_t accept_func;
};

struct serf_incoming_t {
    serf_context_t *ctx;
    serf_io_baton_t baton;
    void *request_baton;
    serf_incoming_request_cb_t request;
    apr_socket_t *skt;
    apr_pollfd_t desc;
};

/* States for the different stages in the lifecyle of a connection. */
typedef enum {
    SERF_CONN_INIT,             /* no socket created yet */
    SERF_CONN_SETUP_SSLTUNNEL,  /* ssl tunnel being setup, no requests sent */
    SERF_CONN_CONNECTED,        /* conn is ready to send requests */
    SERF_CONN_CLOSING           /* conn is closing, no more requests,
                                   start a new socket */
} serf__connection_state_t;

struct serf_connection_t {
    serf_context_t *ctx;

    apr_status_t status;
    serf_io_baton_t baton;

    apr_pool_t *pool;
    serf_bucket_alloc_t *allocator;

    apr_sockaddr_t *address;

    apr_socket_t *skt;
    apr_pool_t *skt_pool;

    /* the last reqevents we gave to pollset_add */
    apr_int16_t reqevents;

    /* the events we've seen for this connection in our returned pollset */
    apr_int16_t seen_in_pollset;

    /* are we a dirty connection that needs its poll status updated? */
    int dirty_conn;

    /* number of completed requests we've sent */
    unsigned int completed_requests;

    /* number of completed responses we've got */
    unsigned int completed_responses;

    /* keepalive */
    unsigned int probable_keepalive_limit;

    /* Current state of the connection (whether or not it is connected). */
    serf__connection_state_t state;

    /* This connection may have responses without a request! */
    int async_responses;
    serf_bucket_t *current_async_response;
    serf_response_acceptor_t async_acceptor;
    void *async_acceptor_baton;
    serf_response_handler_t async_handler;
    void *async_handler_baton;

    /* A bucket wrapped around our socket (for reading responses). */
    serf_bucket_t *stream;
    /* A reference to the aggregate bucket that provides the boundary between
     * request level buckets and connection level buckets.
     */
    serf_bucket_t *ostream_head;
    serf_bucket_t *ostream_tail;

    /* Aggregate bucket used to send the CONNECT request. */
    serf_bucket_t *ssltunnel_ostream;

    /* The list of active requests. */
    serf_request_t *requests;
    serf_request_t *requests_tail;

    struct iovec vec[IOV_MAX];
    int vec_len;

    serf_connection_setup_t setup;
    void *setup_baton;
    serf_connection_closed_t closed;
    void *closed_baton;

    /* Max. number of outstanding requests. */
    unsigned int max_outstanding_requests;

    int hit_eof;

    /* Host url, path ommitted, syntax: https://svn.apache.org . */
    const char *host_url;
    
    /* Exploded host url, path ommitted. Only scheme, hostinfo, hostname &
       port values are filled in. */
    apr_uri_t host_info;

    /* authentication info for this connection. */
    serf__authn_info_t authn_info;

    /* Time marker when connection begins. */
    apr_time_t connect_time;

    /* Calculated connection latency. Negative value if latency is unknown. */
    apr_interval_time_t latency;

    /* Needs to read first before we can write again. */
    int stop_writing;
};

/*** Internal bucket functions ***/

/** Transform a response_bucket in-place into an aggregate bucket. Restore the
    status line and all headers, not just the body.
 
    This can only be used when we haven't started reading the body of the
    response yet.
 
    Keep internal for now, probably only useful within serf.
 */
apr_status_t serf_response_full_become_aggregate(serf_bucket_t *bucket);

/**
 * Remove the header from the list, do nothing if the header wasn't added.
 */
void serf__bucket_headers_remove(serf_bucket_t *headers_bucket,
                                 const char *header);

/*** Authentication handler declarations ***/

typedef enum { PROXY, HOST } peer_t;

/**
 * For each authentication scheme we need a handler function of type
 * serf__auth_handler_func_t. This function will be called when an
 * authentication challenge is received in a session.
 */
typedef apr_status_t
(*serf__auth_handler_func_t)(int code,
                             serf_request_t *request,
                             serf_bucket_t *response,
                             const char *auth_hdr,
                             const char *auth_attr,
                             void *baton,
                             apr_pool_t *pool);

/**
 * For each authentication scheme we need an initialization function of type
 * serf__init_context_func_t. This function will be called the first time
 * serf tries a specific authentication scheme handler.
 */
typedef apr_status_t
(*serf__init_context_func_t)(int code,
                             serf_context_t *conn,
                             apr_pool_t *pool);

/**
 * For each authentication scheme we need an initialization function of type
 * serf__init_conn_func_t. This function will be called when a new
 * connection is opened.
 */
typedef apr_status_t
(*serf__init_conn_func_t)(const serf__authn_scheme_t *scheme,
                          int code,
                          serf_connection_t *conn,
                          apr_pool_t *pool);

/**
 * For each authentication scheme we need a setup_request function of type
 * serf__setup_request_func_t. This function will be called when a
 * new serf_request_t object is created and should fill in the correct
 * authentication headers (if needed).
 */
typedef apr_status_t
(*serf__setup_request_func_t)(peer_t peer,
                              int code,
                              serf_connection_t *conn,
                              serf_request_t *request,
                              const char *method,
                              const char *uri,
                              serf_bucket_t *hdrs_bkt);

/**
 * This function will be called when a response is received, so that the 
 * scheme handler can validate the Authentication related response headers
 * (if needed).
 */
typedef apr_status_t
(*serf__validate_response_func_t)(const serf__authn_scheme_t *scheme,
                                  peer_t peer,
                                  int code,
                                  serf_connection_t *conn,
                                  serf_request_t *request,
                                  serf_bucket_t *response,
                                  apr_pool_t *pool);

/**
 * serf__authn_scheme_t: vtable for an authn scheme provider.
 */
struct serf__authn_scheme_t {
    /* The name of this authentication scheme. Used in headers of requests and
       for logging. */
    const char *name;

    /* Key is the name of the authentication scheme in lower case, to
       facilitate case insensitive matching of the response headers. */
    const char *key;

    /* Internal code used for this authn type. */
    int type;

    /* The context initialization function if any; otherwise, NULL */
    serf__init_context_func_t init_ctx_func;

    /* The connection initialization function if any; otherwise, NULL */
    serf__init_conn_func_t init_conn_func;

    /* The authentication handler function */
    serf__auth_handler_func_t handle_func;

    /* Function to set up the authentication header of a request */
    serf__setup_request_func_t setup_request_func;

    /* Function to validate the authentication header of a response */
    serf__validate_response_func_t validate_response_func;
};

/**
 * Handles a 401 or 407 response, tries the different available authentication
 * handlers.
 */
apr_status_t serf__handle_auth_response(int *consumed_response,
                                        serf_request_t *request,
                                        serf_bucket_t *response,
                                        void *baton,
                                        apr_pool_t *pool);

/* Get the cached serf__authn_info_t object for the target server, or create one
   when this is the first connection to the server.
   TODO: The serf__authn_info_t objects are allocated in the context pool, so
   a context that's used to connect to many different servers using Basic or 
   Digest authencation will hold on to many objects indefinitely. We should be
   able to cleanup stale objects from time to time. */
serf__authn_info_t *serf__get_authn_info_for_server(serf_connection_t *conn);

/* fromt context.c */
void serf__context_progress_delta(void *progress_baton, apr_off_t read,
                                  apr_off_t written);

/* from incoming.c */
apr_status_t serf__process_client(serf_incoming_t *l, apr_int16_t events);
apr_status_t serf__process_listener(serf_listener_t *l);

/* from outgoing.c */
apr_status_t serf__open_connections(serf_context_t *ctx);
apr_status_t serf__process_connection(serf_connection_t *conn,
                                       apr_int16_t events);
apr_status_t serf__conn_update_pollset(serf_connection_t *conn);
serf_request_t *serf__ssltunnel_request_create(serf_connection_t *conn,
                                               serf_request_setup_t setup,
                                               void *setup_baton);
apr_status_t serf__provide_credentials(serf_context_t *ctx,
                                       char **username,
                                       char **password,
                                       serf_request_t *request,
                                       void *baton,
                                       int code, const char *authn_type,
                                       const char *realm,
                                       apr_pool_t *pool);

/* from ssltunnel.c */
apr_status_t serf__ssltunnel_connect(serf_connection_t *conn);


/** Logging functions. Use one of the [COMP]_VERBOSE flags to enable specific
    logging. 
 **/

/* Logs a standard event, with filename & timestamp header */
void serf__log(int verbose_flag, const char *filename, const char *fmt, ...);

/* Logs a standard event, but without prefix. This is useful to build up
 log lines in parts. */
void serf__log_nopref(int verbose_flag, const char *fmt, ...);

/* Logs a socket event, add local and remote ip address:port */
void serf__log_skt(int verbose_flag, const char *filename, apr_socket_t *skt,
                   const char *fmt, ...);

#endif
