#ifndef __DCL_HTTP_SERVER_EXTENSION_H__
#define __DCL_HTTP_SERVER_EXTENSION_H__ 20050509

#ifndef __DCL_CONFIG_H__
#include <dcl/_Config.h>
#endif

/* RFC 2616/5.1.1 */
enum HTTP_REQUEST_METHOD {
    HTTP_METHOD_UNKNOWN     = 0,
    HTTP_METHOD_OPTIONS     = 1,
    HTTP_METHOD_GET         = 3,
    HTTP_METHOD_HEAD        = 4,
    HTTP_METHOD_POST        = 5,
    HTTP_METHOD_PUT         = 6,
    HTTP_METHOD_DELETE      = 7,
    HTTP_METHOD_TRACE       = 8,
    HTTP_METHOD_CONNECT     = 9
};

enum HTTP_RESPONSE_STATUS_CODE {
    HTTP_STATUS_CONTINUE                    = 100,
    HTTP_STATUS_SWITCHING_PROTOCOLS         = 101,
    HTTP_STATUS_OK                          = 200,
    HTTP_STATUS_CREATED                     = 201,
    HTTP_STATUS_ACCEPTED                    = 202,
    HTTP_STATUS_NON_AUTHORITIVE             = 203,
    HTTP_STATUS_NO_CONTENT                  = 204,
    HTTP_STATUS_RESET_CONTENT               = 205,
    HTTP_STATUS_PARTIAL_CONTENT             = 206,
    HTTP_STATUS_MULTIPLE_CHOICES            = 300,
    HTTP_STATUS_MOVED_PERMANENTLY           = 301,
    HTTP_STATUS_FOUND                       = 302,
    HTTP_STATUS_SEE_OTHER                   = 303,
    HTTP_STATUS_NOT_MODIFIED                = 304,
    HTTP_STATUS_USE_PROXY                   = 305,
    HTTP_STATUS_TEMPORARY_REDIRECT          = 307,
    HTTP_STATUS_BAD_REQUEST                 = 400,
    HTTP_STATUS_UNAUTHORIZED                = 401,
    HTTP_STATUS_PAYMENT_REQUIRED            = 402,
    HTTP_STATUS_FORBIDDEN                   = 403,
    HTTP_STATUS_NOT_FOUND                   = 404,
    HTTP_STATUS_METHOD_NOT_ALLOWED          = 405,
    HTTP_STATUS_NOT_ACCEPTABLE              = 406,
    HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407,
    HTTP_STATUS_REQUEST_TIME_OUT            = 408,
    HTTP_STATUS_CONFLICT                    = 409,
    HTTP_STATUS_GONE                        = 410,
    HTTP_STATUS_LENGTH_REQUIRED             = 411,
    HTTP_STATUS_PRECONDITION_FAILED         = 412,
    HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE    = 413,
    HTTP_STATUS_REQUEST_URI_TOO_LARGE       = 414,
    HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE      = 415,
    HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE = 416,
    HTTP_STATUS_EXPECTATION_FAILED          = 417,
    HTTP_STATUS_INTERNAL_SERVER_ERROR       = 500,
    HTTP_STATUS_NOT_IMPLEMENTED             = 501,
    HTTP_STATUS_BAD_GATEWAY                 = 502,
    HTTP_STATUS_SERVICE_UNAVAILABLE         = 503,
    HTTP_STATUS_GATEWAY_TIME_OUT            = 504,
    HTTP_STATUS_VERSION_NOT_SUPPORTED       = 505
};

typedef struct _DCL_HTTP_CONN               DCL_HTTP_CONN;
typedef DCL_HTTP_CONN*                      DCL_HTTP_HCONN;
typedef struct _DCL_HTTP_SERVER_API         DCL_HTTP_SERVER_API;
typedef struct _DCL_HTTP_SERVLET_CONTEXT    DCL_HTTP_SERVLET_CONTEXT;
typedef struct _DCL_HTTP_SERVLET            DCL_HTTP_SERVLET;

/* callback functions */
/* for DCL_HTTP_SERVER_API */
typedef BOOL (* DCLHttpWriteClient)(
                DCL_HTTP_HCONN      hConn,      /* (IN) */
                const void*         pvBuffer,   /* (IN) */
                UINT32*             pnLength    /* (IN, OUT) */
                );
typedef BOOL (* DCLHttpReadClient)(
                DCL_HTTP_HCONN      hConn,      /* (IN) */
                void*               pvBuffer,   /* (OUT) */ 
                UINT32*             pnLength    /* (IN, OUT) */
                );
typedef BOOL (* DCLHttpSendResponseHeader)(
                DCL_HTTP_HCONN      hConn,      /* (IN) */
                UINT32              uStatusCode,/* (IN) */
                const char*         pszHeader,  /* (IN) */
                UINT32              uLength     /* (IN) number of bytes in header */
                );
typedef BOOL (* DCLHttpGetRequestHeader)(
                DCL_HTTP_HCONN      hConn,      /* (IN) */
                const char*         pszName,    /* (IN) NULL => all */
                char*               pchBuffer,  /* (OUT) */
                UINT32*             pnLength    /* (IN, OUT) */
                );
typedef BOOL (* DCLHttpGetCgiVariable)(
                DCL_HTTP_HCONN      hConn,      /* (IN) */
                const char*         pszVarName, /* (IN) NULL => all vars */
                void*               pvBuffer,   /* (OUT) */
                UINT32*             pnLength    /* (IN, OUT) */
                );
typedef void (* DCLHttpWriteStream)(
                void*               hStream,    /* (IN) */
                const void*         pvData,     /* (IN) */
                UINT32              uLength     /* (IN) */
                );
typedef void (* DCLHttpServerControl)(
                DCL_HTTP_HCONN      hConn,      /* (IN) */
                const char*         psControl,
                UINT32              uLength,
                DCLHttpWriteStream  pfnWriteResult,
                void*               hResultOutputStream
                );

/* for DCL_HTTP_SERVLET */
typedef BOOL (* DCLHttpServletInitialize)(
                const char* pszModuleName,      /* Module FileName */
                const DCL_HTTP_SERVER_API*  pSAPI,
                void* hErrorReport
                );
typedef BOOL (* DCLHttpServletCleanup)(
                void* hErrorReport
                );
typedef BOOL (* DCLHttpServletService)(
                const DCL_HTTP_SERVLET_CONTEXT* pContext,
                void* hErrorReport
                );

struct _DCL_HTTP_CONN {
    void*   pv;
};

struct _DCL_HTTP_SERVER_API {
    UINT32          uSize;                  /* (IN) size of this structure */
    UINT32          uVersion;               /* (IN) version info of this spec */
    DCLHttpWriteClient          pfnWriteClient;
    DCLHttpReadClient           pfnReadClient;
    DCLHttpSendResponseHeader   pfnSendResponseHeader;
    DCLHttpGetRequestHeader     pfnGetRequestHeader;
    DCLHttpGetCgiVariable       pfnGetCgiVariable;
    DCLHttpWriteStream          pfnReportError;
    DCLHttpServerControl        pfnServerControl;
};

struct _DCL_HTTP_SERVLET_CONTEXT {
    UINT32          uSize;                  /* (IN) size of this structure */
    UINT32          uVersion;               /* (IN) version info of this spec */
    DCL_HTTP_HCONN  hConn;                  /* (IN) */
    const char*     pszRemoteAddr;          /* (IN) REMOTE_ADDR */
    UINT32          uRemotePort;            /* (IN) REMOTE_PORT */
    UINT32          uRequestMethod;         /* (IN) RFC 2616/5.1.1 HTTP_REQUEST_METHOD */
    const char*     pszRequestMethod;       /* (IN) REQUEST_METHOD */
    const char*     pszPath;                /* (IN) URI's abs_path */
    const char*     pszQueryString;         /* (IN) QUERY_STRING */
    const char*     pszContentType;         /* (IN) CONTENT_TYPE */
    UINT32          uContentLength;         /* (IN) CONTENT_LENGTH */
    const char*     pszScriptFileName;      /* (IN) SCRIPT_FILE_NAME, PATH_TRANSLATED */
    const void*     pvScriptData;
    UINT32          uScriptLength;
};

struct _DCL_HTTP_SERVLET {
    /* DCL common members   */
    UINT32          uSize;              /* (OUT) size of this structure     */
    UINT32          uDCLVersion;        /* (OUT) DCL_VERSION, non DCL(0)    */
    const char*     pszBuildTimeStamp;  /* (OUT) __TIMESTAMP__              */
    UINT32          uBuildFlag;         /* (OUT) release(0), debug(1)       */
    UINT32          uModuleType;        /* (OUT) DCL_HTTP_SERVLET_MODULE    */
    const char*     pszDescription;     /* (OUT) module description         */

    /* private members      */
    UINT32          uVersion;           /* (OUT) version info of this spec  */
                                        /* DCL_HTTP_SERVER_VERSION          */

    DCLHttpServletInitialize    pfnInitialize;
    DCLHttpServletCleanup       pfnCleanup;
    DCLHttpServletService       pfnHttpService;
};

#endif  /* __DCL_HTTP_SERVER_EXTENSION_H__  */