/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
 * pkix_pl_httpdefaultclient.c
 *
 * HTTPDefaultClient Function Definitions
 *
 */

#include "pkix_pl_httpdefaultclient.h"

static void *plContext = NULL;

/*
 * The interface specification for an http client requires that it register
 * a function table of type SEC_HttpClientFcn, which is defined as a union
 * of tables, of which only version 1 is defined at present.
 *
 * Note: these functions violate the PKIX calling conventions, in that they
 * return SECStatus rather than PKIX_Error*, and that they do not provide a
 * plContext argument. They are implemented here as calls to PKIX functions,
 * but the plContext value is circularly defined - a true kludge. Its value
 * is saved at the time of the call to pkix_pl_HttpDefaultClient_Create for
 * subsequent use, but since that initial call comes from the
 * pkix_pl_HttpDefaultClient_CreateSessionFcn, it's not really getting saved.
 */
static SEC_HttpClientFcnV1 vtable = {
        pkix_pl_HttpDefaultClient_CreateSessionFcn,
        pkix_pl_HttpDefaultClient_KeepAliveSessionFcn,
        pkix_pl_HttpDefaultClient_FreeSessionFcn,
        pkix_pl_HttpDefaultClient_RequestCreateFcn,
        pkix_pl_HttpDefaultClient_SetPostDataFcn,
        pkix_pl_HttpDefaultClient_AddHeaderFcn,
        pkix_pl_HttpDefaultClient_TrySendAndReceiveFcn,
        pkix_pl_HttpDefaultClient_CancelFcn,
        pkix_pl_HttpDefaultClient_FreeFcn
};

static SEC_HttpClientFcn httpClient;

static const char *eohMarker = "\r\n\r\n";
static const PKIX_UInt32 eohMarkLen = 4; /* strlen(eohMarker) */
static const char *crlf = "\r\n";
static const PKIX_UInt32 crlfLen = 2; /* strlen(crlf) */
static const char *httpprotocol = "HTTP/";
static const PKIX_UInt32 httpprotocolLen = 5; /* strlen(httpprotocol) */


#define HTTP_UNKNOWN_CONTENT_LENGTH -1

/* --Private-HttpDefaultClient-Functions------------------------- */

/*
 * FUNCTION: pkix_pl_HttpDefaultClient_HdrCheckComplete
 * DESCRIPTION:
 *
 *  This function determines whether the headers in the current receive buffer
 *  in the HttpDefaultClient pointed to by "client" are complete. If so, the
 *  input data is checked for status code, content-type and content-length are
 *  extracted, and the client is set up to read the body of the response.
 *  Otherwise, the client is set up to continue reading header data.
 *
 * PARAMETERS:
 *  "client"
 *      The address of the HttpDefaultClient object. Must be non-NULL.
 *  "bytesRead"
 *      The UInt32 number of bytes received in the latest read.
 *  "pKeepGoing"
 *      The address at which the Boolean state machine flag is stored to
 *      indicate whether processing can continue without further input.
 *      Must be non-NULL.
 *  "plCtx"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a HttpDefaultClient Error if the function fails in a
 *      non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_HttpDefaultClient_HdrCheckComplete(
        PKIX_PL_HttpDefaultClient *client,
        PKIX_UInt32 bytesRead,
        PKIX_Boolean *pKeepGoing,
        void *plCtx)
{
        PKIX_UInt32 alreadyScanned = 0;
        PKIX_UInt32 comp = 0;
        PKIX_UInt32 headerLength = 0;
        PKIX_Int32 contentLength = HTTP_UNKNOWN_CONTENT_LENGTH;
        char *eoh = NULL;
        char *statusLineEnd = NULL;
        char *space = NULL;
        char *nextHeader = NULL;
        const char *httpcode = NULL;
        char *thisHeaderEnd = NULL;
        char *value = NULL;
        char *colon = NULL;
	char *copy = NULL;
        char *body = NULL;

        PKIX_ENTER
                (HTTPDEFAULTCLIENT,
                "pkix_pl_HttpDefaultClient_HdrCheckComplete");
        PKIX_NULLCHECK_TWO(client, pKeepGoing);

        *pKeepGoing = PKIX_FALSE;

        /* Does buffer contain end-of-header marker? */

        /* Copy number of scanned bytes into a variable. */
        alreadyScanned = client->filledupBytes;
        /*
         * If this is the initial buffer, we have to scan from the beginning.
         * If we scanned, failed to find eohMarker, and read some more, we
         * only have to scan from where we left off.
         */
        if (alreadyScanned > eohMarkLen) {
            /* Back up and restart scanning over a few bytes that were
             * scanned before */
            PKIX_UInt32 searchStartPos = alreadyScanned - eohMarkLen;
            eoh = PL_strnstr(&(client->rcvBuf[searchStartPos]), eohMarker,
                             bytesRead + searchStartPos);
        } else {
            /* A search from the beginning of the buffer. */
            eoh = PL_strnstr(client->rcvBuf, eohMarker, bytesRead);
        }

        client->filledupBytes += bytesRead;

        if (eoh == NULL) { /* did we see end-of-header? */
                /* No. Continue to read header data */
                client->connectStatus = HTTP_RECV_HDR;
                *pKeepGoing = PKIX_TRUE;
                goto cleanup;
        }

        /* Yes. Calculate how many bytes in header (not counting eohMarker) */
        headerLength = (eoh - client->rcvBuf);

        /* allocate space to copy header (and for the NULL terminator) */
        PKIX_CHECK(PKIX_PL_Malloc(headerLength + 1, (void **)&copy, plCtx),
                PKIX_MALLOCFAILED);

        /* copy header data before we corrupt it (by storing NULLs) */
        PORT_Memcpy(copy, client->rcvBuf, headerLength);
	/* Store the NULL terminator */
	copy[headerLength] = '\0';
	client->rcvHeaders = copy;

        /* Did caller want a pointer to header? */
        if (client->rcv_http_headers != NULL) {
                /* store pointer for caller */
                *(client->rcv_http_headers) = copy;
        }

        /* Check that message status is okay. */
        statusLineEnd = PL_strnstr(client->rcvBuf, crlf, client->capacity);
        if (statusLineEnd == NULL) {
                client->connectStatus = HTTP_ERROR;
                PORT_SetError(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
                goto cleanup;
        }

        *statusLineEnd = '\0';

        space = strchr((const char *)client->rcvBuf, ' ');
        if (space == NULL) {
                client->connectStatus = HTTP_ERROR;
                goto cleanup;
        }

        comp = PORT_Strncasecmp((const char *)client->rcvBuf, httpprotocol,
                                httpprotocolLen);
        if (comp != 0) {
                client->connectStatus = HTTP_ERROR;
                goto cleanup;
        }

        httpcode = space + 1;
        space = strchr(httpcode, ' ');
        if (space == NULL) {
                client->connectStatus = HTTP_ERROR;
                goto cleanup;
        }
        *space = '\0';

        client->responseCode = atoi(httpcode);
        if (client->responseCode != 200) {
                client->connectStatus = HTTP_ERROR;
                goto cleanup;
        }

        /* Find the content-type and content-length */
        nextHeader = statusLineEnd + crlfLen;
        *eoh = '\0';
        do {
                thisHeaderEnd = NULL;
                value = NULL;

                colon = strchr(nextHeader, ':');
                if (colon == NULL) {
                        client->connectStatus = HTTP_ERROR;
                        goto cleanup;
                }
                *colon = '\0';
                value = colon + 1;
                if (*value != ' ') {
                        client->connectStatus = HTTP_ERROR;
                        goto cleanup;
                }
                value++;
                thisHeaderEnd = strstr(value, crlf);
                if (thisHeaderEnd != NULL) {
                        *thisHeaderEnd = '\0';
                }
                comp = PORT_Strcasecmp(nextHeader, "content-type");
                if (comp == 0) {
                        client->rcvContentType = PORT_Strdup(value);
                } else {
                        comp = PORT_Strcasecmp(nextHeader, "content-length");
                        if (comp == 0) {
                                contentLength = atoi(value);
                        }
                }
                if (thisHeaderEnd != NULL) {
                        nextHeader = thisHeaderEnd + crlfLen;
                } else {
                        nextHeader = NULL;
                }
        } while ((nextHeader != NULL) && (nextHeader < (eoh + crlfLen)));
                
        /* Did caller provide a pointer to return content-type? */
        if (client->rcv_http_content_type != NULL) {
                *(client->rcv_http_content_type) = client->rcvContentType;
        }

        if (client->rcvContentType == NULL) {
                client->connectStatus = HTTP_ERROR;
                goto cleanup;
        }

         /* How many bytes remain in current buffer, beyond the header? */
         headerLength += eohMarkLen;
         client->filledupBytes -= headerLength;
 
         /*
          * The headers have passed validation. Now figure out whether the
          * message is within the caller's size limit (if one was specified).
          */
         switch (contentLength) {
         case 0:
             client->rcv_http_data_len = 0;
             client->connectStatus = HTTP_COMPLETE;
             *pKeepGoing = PKIX_FALSE;
             break;
 
         case HTTP_UNKNOWN_CONTENT_LENGTH:
             /* Unknown contentLength indicator.Will be set by
              * pkix_pl_HttpDefaultClient_RecvBody whey connection get closed */
             client->rcv_http_data_len = HTTP_UNKNOWN_CONTENT_LENGTH;
             contentLength =                 /* Try to reserve 4K+ buffer */
                 client->filledupBytes + HTTP_DATA_BUFSIZE;
             if (client->maxResponseLen > 0 &&
                 contentLength > (PKIX_Int32)client->maxResponseLen) {
                 if (client->filledupBytes < client->maxResponseLen) {
                     contentLength = client->maxResponseLen;
                 } else {
                     client->connectStatus = HTTP_ERROR;
                     goto cleanup;
                 }
             }
             /* set available number of bytes in the buffer */
             client->capacity = contentLength;
             client->connectStatus = HTTP_RECV_BODY;
             *pKeepGoing = PKIX_TRUE;
             break;
 
         default:
             client->rcv_http_data_len = contentLength;
             if (client->maxResponseLen > 0 &&
                 (PKIX_Int32)client->maxResponseLen < contentLength) {
                 client->connectStatus = HTTP_ERROR;
                 goto cleanup;
             }
             
             /*
              * Do we have all of the message body, or do we need to read some more?
              */
             if ((PKIX_Int32)client->filledupBytes < contentLength) {
                 client->connectStatus = HTTP_RECV_BODY;
                 *pKeepGoing = PKIX_TRUE;
             } else {
                 client->connectStatus = HTTP_COMPLETE;
                 *pKeepGoing = PKIX_FALSE;
             }
         }
 
         if (contentLength > 0) {
             /* allocate a buffer of size contentLength  for the content */
             PKIX_CHECK(PKIX_PL_Malloc(contentLength, (void **)&body, plCtx),
                        PKIX_MALLOCFAILED);
             
             /* copy any remaining bytes in current buffer into new buffer */
             if (client->filledupBytes > 0) {
                 PORT_Memcpy(body, &(client->rcvBuf[headerLength]),
                             client->filledupBytes);
             }
         }
 
         PKIX_CHECK(PKIX_PL_Free(client->rcvBuf, plCtx),
                    PKIX_FREEFAILED);
         client->rcvBuf = body;

cleanup:

        PKIX_RETURN(HTTPDEFAULTCLIENT);
}

/*
 * FUNCTION: PKIX_PL_HttpDefaultClient_Create
 * DESCRIPTION:
 *
 *  This function creates a new HttpDefaultClient, and stores the result at
 *  "pClient".
 *
 *  The HttpClient API does not include a plContext argument in its
 *  function calls. Its value at the time of this Create call must be the
 *  same as when the client is invoked.
 *
 * PARAMETERS:
 *  "host"
 *      The name of the server with which we hope to exchange messages. Must
 *      be non-NULL.
 *  "portnum"
 *      The port number to be used for our connection to the server.
 *  "pClient"
 *      The address at which the created HttpDefaultClient is to be stored.
 *      Must be non-NULL.
 *  "plCtx"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a HttpDefaultClient Error if the function fails in
 *      a non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_HttpDefaultClient_Create(
        const char *host,
        PRUint16 portnum,
        PKIX_PL_HttpDefaultClient **pClient,
        void *plCtx)
{
        PKIX_PL_HttpDefaultClient *client = NULL;

        PKIX_ENTER(HTTPDEFAULTCLIENT, "PKIX_PL_HttpDefaultClient_Create");
        PKIX_NULLCHECK_TWO(pClient, host);

        /* allocate an HttpDefaultClient */
        PKIX_CHECK(PKIX_PL_Object_Alloc
                (PKIX_HTTPDEFAULTCLIENT_TYPE,
                sizeof (PKIX_PL_HttpDefaultClient),
                (PKIX_PL_Object **)&client,
                plCtx),
                PKIX_COULDNOTCREATEHTTPDEFAULTCLIENTOBJECT);

        /* Client timeout is overwritten in HttpDefaultClient_RequestCreate
         * function. Default value will be ignored. */
        client->timeout = 0;
        client->connectStatus = HTTP_NOT_CONNECTED;
        client->portnum = portnum;
        client->bytesToWrite = 0;
        client->send_http_data_len = 0;
        client->rcv_http_data_len = 0;
        client->capacity = 0;
        client->filledupBytes = 0;
        client->responseCode = 0;
        client->maxResponseLen = 0;
        client->GETLen = 0;
        client->POSTLen = 0;
        client->pRcv_http_data_len = NULL;
        client->callbackList = NULL;
        client->GETBuf = NULL;
        client->POSTBuf = NULL;
        client->rcvBuf = NULL;
        /* "host" is a parsing result by CERT_GetURL function that adds
         * "end of line" to the value. OK to dup the string. */
        client->host = PORT_Strdup(host);
        if (!client->host) {
            PKIX_ERROR(PKIX_ALLOCERROR);
        }
        client->path = NULL;
        client->rcvContentType = NULL;
        client->rcvHeaders = NULL;
        client->send_http_method = HTTP_POST_METHOD;
        client->send_http_content_type = NULL;
        client->send_http_data = NULL;
        client->rcv_http_response_code = NULL;
        client->rcv_http_content_type = NULL;
        client->rcv_http_headers = NULL;
        client->rcv_http_data = NULL;
        client->socket = NULL;

        /*
         * The HttpClient API does not include a plCtx argument in its
         * function calls. Save it here.
         */
        client->plContext = plCtx;

        *pClient = client;

cleanup:
        if (PKIX_ERROR_RECEIVED) {
                PKIX_DECREF(client);
        }

        PKIX_RETURN(HTTPDEFAULTCLIENT);
}

/*
 * FUNCTION: pkix_pl_HttpDefaultClient_Destroy
 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_HttpDefaultClient_Destroy(
        PKIX_PL_Object *object,
        void *plCtx)
{
        PKIX_PL_HttpDefaultClient *client = NULL;

        PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_Destroy");
        PKIX_NULLCHECK_ONE(object);

        PKIX_CHECK(pkix_CheckType
                    (object, PKIX_HTTPDEFAULTCLIENT_TYPE, plCtx),
                    PKIX_OBJECTNOTANHTTPDEFAULTCLIENT);

        client = (PKIX_PL_HttpDefaultClient *)object;

        if (client->rcvHeaders) {
            PKIX_PL_Free(client->rcvHeaders, plCtx);
            client->rcvHeaders = NULL;
        }
        if (client->rcvContentType) {
            PORT_Free(client->rcvContentType);
            client->rcvContentType = NULL;
        }
        if (client->GETBuf != NULL) {
                PR_smprintf_free(client->GETBuf);
                client->GETBuf = NULL;
        }
        if (client->POSTBuf != NULL) {
                PKIX_PL_Free(client->POSTBuf, plCtx);
                client->POSTBuf = NULL;
        }
        if (client->rcvBuf != NULL) {
                PKIX_PL_Free(client->rcvBuf, plCtx);
                client->rcvBuf = NULL;
        }
        if (client->host) {
                PORT_Free(client->host);
                client->host = NULL;
        }
        if (client->path) {
                PORT_Free(client->path);
                client->path = NULL;
        }
        PKIX_DECREF(client->socket);

cleanup:

        PKIX_RETURN(HTTPDEFAULTCLIENT);
}

/*
 * FUNCTION: pkix_pl_HttpDefaultClient_RegisterSelf
 *
 * DESCRIPTION:
 *  Registers PKIX_PL_HTTPDEFAULTCLIENT_TYPE and its related
 *  functions with systemClasses[]
 *
 * THREAD SAFETY:
 *  Not Thread Safe - for performance and complexity reasons
 *
 *  Since this function is only called by PKIX_PL_Initialize, which should
 *  only be called once, it is acceptable that this function is not
 *  thread-safe.
 */
PKIX_Error *
pkix_pl_HttpDefaultClient_RegisterSelf(void *plCtx)
{
        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
        pkix_ClassTable_Entry *entry =
            &systemClasses[PKIX_HTTPDEFAULTCLIENT_TYPE];

        PKIX_ENTER(HTTPDEFAULTCLIENT,
                "pkix_pl_HttpDefaultClient_RegisterSelf");

        entry->description = "HttpDefaultClient";
        entry->typeObjectSize = sizeof(PKIX_PL_HttpDefaultClient);
        entry->destructor = pkix_pl_HttpDefaultClient_Destroy;
 
        httpClient.version = 1;
        httpClient.fcnTable.ftable1 = vtable;
        (void)SEC_RegisterDefaultHttpClient(&httpClient);

        PKIX_RETURN(HTTPDEFAULTCLIENT);
}

/* --Private-HttpDefaultClient-I/O-Functions---------------------------- */
/*
 * FUNCTION: pkix_pl_HttpDefaultClient_ConnectContinue
 * DESCRIPTION:
 *
 *  This function determines whether a socket Connect initiated earlier for the
 *  HttpDefaultClient "client" has completed, and stores in "pKeepGoing" a flag
 *  indicating whether processing can continue without further input.
 *
 * PARAMETERS:
 *  "client"
 *      The address of the HttpDefaultClient object. Must be non-NULL.
 *  "pKeepGoing"
 *      The address at which the Boolean state machine flag is stored to
 *      indicate whether processing can continue without further input.
 *      Must be non-NULL.
 *  "plCtx"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a HttpDefaultClient Error if the function fails in a
 *      non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_HttpDefaultClient_ConnectContinue(
        PKIX_PL_HttpDefaultClient *client,
        PKIX_Boolean *pKeepGoing,
        void *plCtx)
{
        PRErrorCode status;
        PKIX_Boolean keepGoing = PKIX_FALSE;
        PKIX_PL_Socket_Callback *callbackList = NULL;

        PKIX_ENTER
                (HTTPDEFAULTCLIENT,
                "pkix_pl_HttpDefaultClient_ConnectContinue");
        PKIX_NULLCHECK_ONE(client);

        callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;

        PKIX_CHECK(callbackList->connectcontinueCallback
                (client->socket, &status, plCtx),
                PKIX_SOCKETCONNECTCONTINUEFAILED);

        if (status == 0) {
                client->connectStatus = HTTP_CONNECTED;
                keepGoing = PKIX_TRUE;
        } else if (status != PR_IN_PROGRESS_ERROR) {
                PKIX_ERROR(PKIX_UNEXPECTEDERRORINESTABLISHINGCONNECTION);
        }

        *pKeepGoing = keepGoing;

cleanup:
        PKIX_RETURN(HTTPDEFAULTCLIENT);
}

/*
 * FUNCTION: pkix_pl_HttpDefaultClient_Send
 * DESCRIPTION:
 *
 *  This function creates and sends HTTP-protocol headers and, if applicable,
 *  data, for the HttpDefaultClient "client", and stores in "pKeepGoing" a flag
 *  indicating whether processing can continue without further input, and at
 *  "pBytesTransferred" the number of bytes sent.
 *
 *  If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use
 *  and that transmission has not completed.
 *
 * PARAMETERS:
 *  "client"
 *      The address of the HttpDefaultClient object. Must be non-NULL.
 *  "pKeepGoing"
 *      The address at which the Boolean state machine flag is stored to
 *      indicate whether processing can continue without further input.
 *      Must be non-NULL.
 *  "pBytesTransferred"
 *      The address at which the number of bytes sent is stored. Must be
 *      non-NULL.
 *  "plCtx"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a HttpDefaultClient Error if the function fails in a
 *      non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_HttpDefaultClient_Send(
        PKIX_PL_HttpDefaultClient *client,
        PKIX_Boolean *pKeepGoing,
        PKIX_UInt32 *pBytesTransferred,
        void *plCtx)
{
        PKIX_Int32 bytesWritten = 0;
        PKIX_Int32 lenToWrite = 0;
        PKIX_PL_Socket_Callback *callbackList = NULL;
        char *dataToWrite = NULL;

        PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_Send");
        PKIX_NULLCHECK_THREE(client, pKeepGoing, pBytesTransferred);

        *pKeepGoing = PKIX_FALSE;

        /* Do we have anything waiting to go? */
        if ((client->GETBuf) || (client->POSTBuf)) {

                if (client->GETBuf) {
                        dataToWrite = client->GETBuf;
                        lenToWrite = client->GETLen;
                } else {
                        dataToWrite = client->POSTBuf;
                        lenToWrite = client->POSTLen;
                }

                callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;

                PKIX_CHECK(callbackList->sendCallback
                        (client->socket,
                        dataToWrite,
                        lenToWrite,
                        &bytesWritten,
                        plCtx),
                        PKIX_SOCKETSENDFAILED);

                client->rcvBuf = NULL;
                client->capacity = 0;
                client->filledupBytes = 0;

                /*
                 * If the send completed we can proceed to try for the
                 * response. If the send did not complete we will have
                 * to poll for completion later.
                 */
                if (bytesWritten >= 0) {
                        client->connectStatus = HTTP_RECV_HDR;
                        *pKeepGoing = PKIX_TRUE;
                } else {
                        client->connectStatus = HTTP_SEND_PENDING;
                        *pKeepGoing = PKIX_FALSE;
                }

        }

        *pBytesTransferred = bytesWritten;

cleanup:
        PKIX_RETURN(HTTPDEFAULTCLIENT);
}

/*
 * FUNCTION: pkix_pl_HttpDefaultClient_SendContinue
 * DESCRIPTION:
 *
 *  This function determines whether the sending of the HTTP message for the
 *  HttpDefaultClient "client" has completed, and stores in "pKeepGoing" a
 *  flag indicating whether processing can continue without further input, and
 *  at "pBytesTransferred" the number of bytes sent.
 *
 *  If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use
 *  and that transmission has not completed.
 *
 * PARAMETERS:
 *  "client"
 *      The address of the HttpDefaultClient object. Must be non-NULL.
 *  "pKeepGoing"
 *      The address at which the Boolean state machine flag is stored to
 *      indicate whether processing can continue without further input.
 *      Must be non-NULL.
 *  "pBytesTransferred"
 *      The address at which the number of bytes sent is stored. Must be
 *      non-NULL.
 *  "plCtx"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a HttpDefaultClient Error if the function fails in a
 *      non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_HttpDefaultClient_SendContinue(
        PKIX_PL_HttpDefaultClient *client,
        PKIX_Boolean *pKeepGoing,
        PKIX_UInt32 *pBytesTransferred,
        void *plCtx)
{
        PKIX_Int32 bytesWritten = 0;
        PKIX_PL_Socket_Callback *callbackList = NULL;

        PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_SendContinue");
        PKIX_NULLCHECK_THREE(client, pKeepGoing, pBytesTransferred);

        *pKeepGoing = PKIX_FALSE;

        callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;

        PKIX_CHECK(callbackList->pollCallback
                (client->socket, &bytesWritten, NULL, plCtx),
                PKIX_SOCKETPOLLFAILED);

        /*
         * If the send completed we can proceed to try for the
         * response. If the send did not complete we will have
         * continue to poll.
         */
        if (bytesWritten >= 0) {
                       client->connectStatus = HTTP_RECV_HDR;
                *pKeepGoing = PKIX_TRUE;
        }

        *pBytesTransferred = bytesWritten;

cleanup:
        PKIX_RETURN(HTTPDEFAULTCLIENT);
}

/*
 * FUNCTION: pkix_pl_HttpDefaultClient_RecvHdr
 * DESCRIPTION:
 *
 *  This function receives HTTP headers for the HttpDefaultClient "client", and
 *  stores in "pKeepGoing" a flag indicating whether processing can continue
 *  without further input.
 *
 * PARAMETERS:
 *  "client"
 *      The address of the HttpDefaultClient object. Must be non-NULL.
 *  "pKeepGoing"
 *      The address at which the Boolean state machine flag is stored to
 *      indicate whether processing can continue without further input.
 *      Must be non-NULL.
 *  "plCtx"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a HttpDefaultClient Error if the function fails in a
 *      non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_HttpDefaultClient_RecvHdr(
        PKIX_PL_HttpDefaultClient *client,
        PKIX_Boolean *pKeepGoing,
        void *plCtx)
{
        PKIX_UInt32 bytesToRead = 0;
        PKIX_Int32 bytesRead = 0;
        PKIX_PL_Socket_Callback *callbackList = NULL;

        PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_RecvHdr");
        PKIX_NULLCHECK_TWO(client, pKeepGoing);

        /*
         * rcvbuf, capacity, and filledupBytes were
         * initialized when we wrote the headers. We begin by reading
         * HTTP_HEADER_BUFSIZE bytes, repeatedly increasing the buffersize and
         * reading again if necessary, until we have read the end-of-header
         * marker, "\r\n\r\n", or have reached our maximum.
         */
        client->capacity += HTTP_HEADER_BUFSIZE;
        PKIX_CHECK(PKIX_PL_Realloc
                (client->rcvBuf,
                client->capacity,
                (void **)&(client->rcvBuf),
                plCtx),
                PKIX_REALLOCFAILED);

        bytesToRead = client->capacity - client->filledupBytes;

        callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;

        PKIX_CHECK(callbackList->recvCallback
                (client->socket,
                (void *)&(client->rcvBuf[client->filledupBytes]),
                bytesToRead,
                &bytesRead,
                plCtx),
                PKIX_SOCKETRECVFAILED);

        if (bytesRead > 0) {
            /* client->filledupBytes will be adjusted by
             * pkix_pl_HttpDefaultClient_HdrCheckComplete */
            PKIX_CHECK(
                pkix_pl_HttpDefaultClient_HdrCheckComplete(client, bytesRead,
                                                           pKeepGoing,
                                                           plCtx),
                       PKIX_HTTPDEFAULTCLIENTHDRCHECKCOMPLETEFAILED);
        } else {
            client->connectStatus = HTTP_RECV_HDR_PENDING;
            *pKeepGoing = PKIX_FALSE;
        }

cleanup:
        PKIX_RETURN(HTTPDEFAULTCLIENT);
}

/*
 * FUNCTION: pkix_pl_HttpDefaultClient_RecvHdrContinue
 * DESCRIPTION:
 *
 *  This function determines whether the receiving of the HTTP headers for the
 *  HttpDefaultClient "client" has completed, and stores in "pKeepGoing" a flag
 *  indicating whether processing can continue without further input.
 *
 * PARAMETERS:
 *  "client"
 *      The address of the HttpDefaultClient object. Must be non-NULL.
 *  "pKeepGoing"
 *      The address at which the Boolean state machine flag is stored to
 *      indicate whether processing can continue without further input.
 *      Must be non-NULL.
 *  "plCtx"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a HttpDefaultClient Error if the function fails in a
 *      non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_HttpDefaultClient_RecvHdrContinue(
        PKIX_PL_HttpDefaultClient *client,
        PKIX_Boolean *pKeepGoing,
        void *plCtx)
{
        PKIX_Int32 bytesRead = 0;
        PKIX_PL_Socket_Callback *callbackList = NULL;

        PKIX_ENTER
                (HTTPDEFAULTCLIENT,
                "pkix_pl_HttpDefaultClient_RecvHdrContinue");
        PKIX_NULLCHECK_TWO(client, pKeepGoing);

        callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;

        PKIX_CHECK(callbackList->pollCallback
                (client->socket, NULL, &bytesRead, plCtx),
                PKIX_SOCKETPOLLFAILED);

        if (bytesRead > 0) {
                client->filledupBytes += bytesRead;

                PKIX_CHECK(pkix_pl_HttpDefaultClient_HdrCheckComplete
                        (client, bytesRead, pKeepGoing, plCtx),
                        PKIX_HTTPDEFAULTCLIENTHDRCHECKCOMPLETEFAILED);

        } else {

                *pKeepGoing = PKIX_FALSE;

        }

cleanup:
        PKIX_RETURN(HTTPDEFAULTCLIENT);
}

/*
 * FUNCTION: pkix_pl_HttpDefaultClient_RecvBody
 * DESCRIPTION:
 *
 *  This function processes the contents of the first buffer of a received
 *  HTTP-protocol message for the HttpDefaultClient "client", and stores in
 *  "pKeepGoing" a flag indicating whether processing can continue without
 *  further input.
 *
 * PARAMETERS:
 *  "client"
 *      The address of the HttpDefaultClient object. Must be non-NULL.
 *  "pKeepGoing"
 *      The address at which the Boolean state machine flag is stored to
 *      indicate whether processing can continue without further input.
 *      Must be non-NULL.
 *  "plCtx"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a HttpDefaultClient Error if the function fails in a
 *      non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_HttpDefaultClient_RecvBody(
        PKIX_PL_HttpDefaultClient *client,
        PKIX_Boolean *pKeepGoing,
        void *plCtx)
{
        PKIX_Int32 bytesRead = 0;
        PKIX_Int32 bytesToRead = 0;
        PKIX_PL_Socket_Callback *callbackList = NULL;

        PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_RecvBody");
        PKIX_NULLCHECK_TWO(client, pKeepGoing);

        callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;

        if (client->rcv_http_data_len != HTTP_UNKNOWN_CONTENT_LENGTH) {
            bytesToRead = client->rcv_http_data_len -
                client->filledupBytes;
        } else {
            /* Reading till the EOF. Context length is not known.*/
            /* Check the buffer capacity: increase and
             * reallocate if it is low. */
            int freeBuffSize = client->capacity - client->filledupBytes;
            if (freeBuffSize < HTTP_MIN_AVAILABLE_BUFFER_SIZE) {
                /* New length will be consist of available(downloaded) bytes,
                 * plus remaining capacity, plus new expansion. */
                int currBuffSize = client->capacity;
                /* Try to increase the buffer by 4K */
                unsigned int newLength = currBuffSize + HTTP_DATA_BUFSIZE;
                if (client->maxResponseLen > 0 &&
                    newLength > client->maxResponseLen) {
                        newLength = client->maxResponseLen;
                }
                /* Check if we can grow the buffer and report an error if
                 * new size is not larger than the current size of the buffer.*/
                if (newLength <= client->filledupBytes) {
                    client->rcv_http_data_len = client->filledupBytes;
                    client->connectStatus = HTTP_ERROR;
                    *pKeepGoing = PKIX_FALSE;
                    goto cleanup;
                }
                if (client->capacity < newLength) {
                    client->capacity = newLength;
                    PKIX_CHECK(
                        PKIX_PL_Realloc(client->rcvBuf, newLength,
                                        (void**)&client->rcvBuf, plCtx),
                        PKIX_REALLOCFAILED);
                    freeBuffSize = client->capacity -
                        client->filledupBytes;
                }
            }
            bytesToRead = freeBuffSize;
        }

        /* Use poll callback if waiting on non-blocking IO */
        if (client->connectStatus == HTTP_RECV_BODY_PENDING) {
            PKIX_CHECK(callbackList->pollCallback
                       (client->socket, NULL, &bytesRead, plCtx),
                       PKIX_SOCKETPOLLFAILED);
        } else {
            PKIX_CHECK(callbackList->recvCallback
                       (client->socket,
                        (void *)&(client->rcvBuf[client->filledupBytes]),
                        bytesToRead,
                        &bytesRead,
                        plCtx),
                       PKIX_SOCKETRECVFAILED);
        }

        /* If bytesRead < 0, an error will be thrown by recvCallback, so
         * need to handle >= 0 cases. */

        /* bytesRead == 0 - IO was blocked. */
        if (bytesRead == 0) {
            client->connectStatus = HTTP_RECV_BODY_PENDING;
            *pKeepGoing = PKIX_TRUE;
            goto cleanup;
        }
        
        /* We got something. Did we get it all? */
        client->filledupBytes += bytesRead;

        /* continue if not enough bytes read or if complete size of
         * transfer is unknown */
        if (bytesToRead > bytesRead ||
            client->rcv_http_data_len == HTTP_UNKNOWN_CONTENT_LENGTH) {
            *pKeepGoing = PKIX_TRUE;
            goto cleanup;
        }
        client->connectStatus = HTTP_COMPLETE;
        *pKeepGoing = PKIX_FALSE;

cleanup:
        if (pkixErrorResult && pkixErrorResult->errCode ==
            PKIX_PRRECVREPORTSNETWORKCONNECTIONCLOSED) {
            if (client->rcv_http_data_len == HTTP_UNKNOWN_CONTENT_LENGTH) {
                client->rcv_http_data_len = client->filledupBytes;
                client->connectStatus = HTTP_COMPLETE;
                *pKeepGoing = PKIX_FALSE;
                PKIX_DECREF(pkixErrorResult);
            } else {
                client->connectStatus = HTTP_ERROR;
            }
        }

        PKIX_RETURN(HTTPDEFAULTCLIENT);
}

/*
 * FUNCTION: pkix_pl_HttpDefaultClient_Dispatch
 * DESCRIPTION:
 *
 *  This function is the state machine dispatcher for the HttpDefaultClient
 *  pointed to by "client". Results are returned by changes to various fields
 *  in the context.
 *
 * PARAMETERS:
 *  "client"
 *      The address of the HttpDefaultClient object. Must be non-NULL.
 *  "plCtx"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a HttpDefaultClient Error if the function fails in a
 *      non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_HttpDefaultClient_Dispatch(
        PKIX_PL_HttpDefaultClient *client,
        void *plCtx)
{
        PKIX_UInt32 bytesTransferred = 0;
        PKIX_Boolean keepGoing = PKIX_TRUE;

        PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_Dispatch");
        PKIX_NULLCHECK_ONE(client);

        while (keepGoing) {
                switch (client->connectStatus) {
                case HTTP_CONNECT_PENDING:
                    PKIX_CHECK(pkix_pl_HttpDefaultClient_ConnectContinue
                        (client, &keepGoing, plCtx),
                        PKIX_HTTPDEFAULTCLIENTCONNECTCONTINUEFAILED);
                    break;
                case HTTP_CONNECTED:
                    PKIX_CHECK(pkix_pl_HttpDefaultClient_Send
                        (client, &keepGoing, &bytesTransferred, plCtx),
                        PKIX_HTTPDEFAULTCLIENTSENDFAILED);
                    break;
                case HTTP_SEND_PENDING:
                    PKIX_CHECK(pkix_pl_HttpDefaultClient_SendContinue
                        (client, &keepGoing, &bytesTransferred, plCtx),
                        PKIX_HTTPDEFAULTCLIENTSENDCONTINUEFAILED);
                    break;
                case HTTP_RECV_HDR:
                    PKIX_CHECK(pkix_pl_HttpDefaultClient_RecvHdr
                        (client, &keepGoing, plCtx),
                        PKIX_HTTPDEFAULTCLIENTRECVHDRFAILED);
                    break;
                case HTTP_RECV_HDR_PENDING:
                    PKIX_CHECK(pkix_pl_HttpDefaultClient_RecvHdrContinue
                        (client, &keepGoing, plCtx),
                        PKIX_HTTPDEFAULTCLIENTRECVHDRCONTINUEFAILED);
                    break;
                case HTTP_RECV_BODY:
                case HTTP_RECV_BODY_PENDING:
                    PKIX_CHECK(pkix_pl_HttpDefaultClient_RecvBody
                        (client, &keepGoing, plCtx),
                        PKIX_HTTPDEFAULTCLIENTRECVBODYFAILED);
                    break;
                case HTTP_ERROR:
                case HTTP_COMPLETE:
                    keepGoing = PKIX_FALSE;
                    break;
                case HTTP_NOT_CONNECTED:
                default:
                    PKIX_ERROR(PKIX_HTTPDEFAULTCLIENTINILLEGALSTATE);
                }
        }

cleanup:

        PKIX_RETURN(HTTPDEFAULTCLIENT);
}

/*
 * --HttpClient vtable functions
 * See comments in ocspt.h for the function (wrappers) that return SECStatus.
 * The functions that return PKIX_Error* are the libpkix implementations.
 */

PKIX_Error *
pkix_pl_HttpDefaultClient_CreateSession(
        const char *host,
        PRUint16 portnum,
        SEC_HTTP_SERVER_SESSION *pSession,
        void *plCtx)
{
        PKIX_PL_HttpDefaultClient *client = NULL;

        PKIX_ENTER
                (HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_CreateSession");
        PKIX_NULLCHECK_TWO(host, pSession);

        PKIX_CHECK(pkix_pl_HttpDefaultClient_Create
                (host, portnum, &client, plCtx),
                PKIX_HTTPDEFAULTCLIENTCREATEFAILED);

        *pSession = (SEC_HTTP_SERVER_SESSION)client;

cleanup:

        PKIX_RETURN(HTTPDEFAULTCLIENT);

}

PKIX_Error *
pkix_pl_HttpDefaultClient_KeepAliveSession(
        SEC_HTTP_SERVER_SESSION session,
        PRPollDesc **pPollDesc,
        void *plCtx)
{
        PKIX_ENTER
                (HTTPDEFAULTCLIENT,
                "pkix_pl_HttpDefaultClient_KeepAliveSession");
        PKIX_NULLCHECK_TWO(session, pPollDesc);

        PKIX_CHECK(pkix_CheckType
                ((PKIX_PL_Object *)session,
                PKIX_HTTPDEFAULTCLIENT_TYPE,
                plCtx),
                PKIX_SESSIONNOTANHTTPDEFAULTCLIENT);

        /* XXX Not implemented */

cleanup:

        PKIX_RETURN(HTTPDEFAULTCLIENT);

}

PKIX_Error *
pkix_pl_HttpDefaultClient_RequestCreate(
        SEC_HTTP_SERVER_SESSION session,
        const char *http_protocol_variant, /* usually "http" */
        const char *path_and_query_string,
        const char *http_request_method, 
        const PRIntervalTime timeout, 
        SEC_HTTP_REQUEST_SESSION *pRequest,
        void *plCtx)
{
        PKIX_PL_HttpDefaultClient *client = NULL;
        PKIX_PL_Socket *socket = NULL;
        PKIX_PL_Socket_Callback *callbackList = NULL;
        PRFileDesc *fileDesc = NULL;
        PRErrorCode status = 0;

        PKIX_ENTER
                (HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_RequestCreate");
        PKIX_NULLCHECK_TWO(session, pRequest);

        PKIX_CHECK(pkix_CheckType
                ((PKIX_PL_Object *)session,
                PKIX_HTTPDEFAULTCLIENT_TYPE,
                plCtx),
                PKIX_SESSIONNOTANHTTPDEFAULTCLIENT);

        client = (PKIX_PL_HttpDefaultClient *)session;

        /* We only know how to do http */
        if (PORT_Strncasecmp(http_protocol_variant, "http", 4) != 0) {
                PKIX_ERROR(PKIX_UNRECOGNIZEDPROTOCOLREQUESTED);
        }

        if (PORT_Strncasecmp(http_request_method, "POST", 4) == 0) {
                client->send_http_method = HTTP_POST_METHOD;
        } else if (PORT_Strncasecmp(http_request_method, "GET", 3) == 0) {
                client->send_http_method = HTTP_GET_METHOD;
        } else {
                /* We only know how to do POST and GET */
                PKIX_ERROR(PKIX_UNRECOGNIZEDREQUESTMETHOD);
        }

        if (path_and_query_string) {
            /* "path_and_query_string" is a parsing result by CERT_GetURL
             * function that adds "end of line" to the value. OK to dup
             * the string. */
            client->path = PORT_Strdup(path_and_query_string);
            if (!client->path) {
                PKIX_ERROR(PKIX_ALLOCERROR);
            }
        }

        client->timeout = timeout;

#if 0
	PKIX_CHECK(pkix_HttpCertStore_FindSocketConnection
                (timeout,
                "variation.red.iplanet.com", /* (char *)client->host, */
                2001,   /* client->portnum, */
                &status,
                &socket,
                plCtx),
		PKIX_HTTPCERTSTOREFINDSOCKETCONNECTIONFAILED);
#else
	PKIX_CHECK(pkix_HttpCertStore_FindSocketConnection
                (timeout,
                (char *)client->host,
                client->portnum,
                &status,
                &socket,
                plCtx),
		PKIX_HTTPCERTSTOREFINDSOCKETCONNECTIONFAILED);
#endif

        client->socket = socket;

        PKIX_CHECK(pkix_pl_Socket_GetCallbackList
                (socket, &callbackList, plCtx),
                PKIX_SOCKETGETCALLBACKLISTFAILED);

        client->callbackList = (void *)callbackList;

        PKIX_CHECK(pkix_pl_Socket_GetPRFileDesc
                (socket, &fileDesc, plCtx),
                PKIX_SOCKETGETPRFILEDESCFAILED);

        client->pollDesc.fd = fileDesc;
        client->pollDesc.in_flags = 0;
        client->pollDesc.out_flags = 0;

        client->send_http_data = NULL;
        client->send_http_data_len = 0;
        client->send_http_content_type = NULL;

        client->connectStatus =
                 ((status == 0) ? HTTP_CONNECTED : HTTP_CONNECT_PENDING);

        /* Request object is the same object as Session object */
        PKIX_INCREF(client);
        *pRequest = client;

cleanup:

        PKIX_RETURN(HTTPDEFAULTCLIENT);

}

PKIX_Error *
pkix_pl_HttpDefaultClient_SetPostData(
        SEC_HTTP_REQUEST_SESSION request,
        const char *http_data, 
        const PRUint32 http_data_len,
        const char *http_content_type,
        void *plCtx)
{
        PKIX_PL_HttpDefaultClient *client = NULL;

        PKIX_ENTER
                (HTTPDEFAULTCLIENT,
                "pkix_pl_HttpDefaultClient_SetPostData");
        PKIX_NULLCHECK_ONE(request);

        PKIX_CHECK(pkix_CheckType
                ((PKIX_PL_Object *)request,
                PKIX_HTTPDEFAULTCLIENT_TYPE,
                plCtx),
                PKIX_REQUESTNOTANHTTPDEFAULTCLIENT);

        client = (PKIX_PL_HttpDefaultClient *)request;

        client->send_http_data = http_data;
        client->send_http_data_len = http_data_len;
        client->send_http_content_type = http_content_type;

        /* Caller is allowed to give NULL or empty string for content_type */
        if ((client->send_http_content_type == NULL) ||
            (*(client->send_http_content_type) == '\0')) {
                client->send_http_content_type = "application/ocsp-request";
        }

cleanup:

        PKIX_RETURN(HTTPDEFAULTCLIENT);

}

PKIX_Error *
pkix_pl_HttpDefaultClient_TrySendAndReceive(
        SEC_HTTP_REQUEST_SESSION request,
        PRUint16 *http_response_code, 
        const char **http_response_content_type, 
        const char **http_response_headers, 
        const char **http_response_data, 
        PRUint32 *http_response_data_len, 
        PRPollDesc **pPollDesc,
        SECStatus *pSECReturn,
        void *plCtx)        
{
        PKIX_PL_HttpDefaultClient *client = NULL;
        PKIX_UInt32 postLen = 0;
        PRPollDesc *pollDesc = NULL;
        char *sendbuf = NULL;
        char portstr[16];

        PKIX_ENTER
                (HTTPDEFAULTCLIENT,
                "pkix_pl_HttpDefaultClient_TrySendAndReceive");

        PKIX_NULLCHECK_ONE(request);

        PKIX_CHECK(pkix_CheckType
                ((PKIX_PL_Object *)request,
                PKIX_HTTPDEFAULTCLIENT_TYPE,
                plCtx),
                PKIX_REQUESTNOTANHTTPDEFAULTCLIENT);

        client = (PKIX_PL_HttpDefaultClient *)request;

        if (!pPollDesc && client->timeout == 0) {
            PKIX_ERROR_FATAL(PKIX_NULLARGUMENT);
        }

        if (pPollDesc) {
            pollDesc = *pPollDesc;
        }

        /* if not continuing from an earlier WOULDBLOCK return... */
        if (pollDesc == NULL) {

                if (!((client->connectStatus == HTTP_CONNECTED) ||
                     (client->connectStatus == HTTP_CONNECT_PENDING))) {
                        PKIX_ERROR(PKIX_HTTPCLIENTININVALIDSTATE);
                }

                /* Did caller provide a value for response length? */
                if (http_response_data_len != NULL) {
                        client->pRcv_http_data_len = http_response_data_len;
                        client->maxResponseLen = *http_response_data_len;
                }

                client->rcv_http_response_code = http_response_code;
                client->rcv_http_content_type = http_response_content_type;
                client->rcv_http_headers = http_response_headers;
                client->rcv_http_data = http_response_data;

                /* prepare the message */
                portstr[0] = '\0';
                if (client->portnum != 80) {
                        PR_snprintf(portstr, sizeof(portstr), ":%d", 
                                    client->portnum);
                }
                
                if (client->send_http_method == HTTP_POST_METHOD) {
                        sendbuf = PR_smprintf
                            ("POST %s HTTP/1.0\r\nHost: %s%s\r\n"
                            "Content-Type: %s\r\nContent-Length: %u\r\n\r\n",
                            client->path,
                            client->host,
                            portstr,
                            client->send_http_content_type,
                            client->send_http_data_len);
                        postLen = PORT_Strlen(sendbuf);
                            
                        client->POSTLen = postLen + client->send_http_data_len;

                        /* allocate postBuffer big enough for header + data */
                        PKIX_CHECK(PKIX_PL_Malloc
                                (client->POSTLen,
                                (void **)&(client->POSTBuf),
                                plCtx),
                                PKIX_MALLOCFAILED);

                        /* copy header into postBuffer */
                        PORT_Memcpy(client->POSTBuf, sendbuf, postLen);

                        /* append data after header */
                        PORT_Memcpy(&client->POSTBuf[postLen],
                                    client->send_http_data,
                                    client->send_http_data_len);

                        /* PR_smprintf_free original header buffer */
                        PR_smprintf_free(sendbuf);
                        sendbuf = NULL;
                        
                } else if (client->send_http_method == HTTP_GET_METHOD) {
                        client->GETBuf = PR_smprintf
                            ("GET %s HTTP/1.0\r\nHost: %s%s\r\n\r\n",
                            client->path,
                            client->host,
                            portstr);
                        client->GETLen = PORT_Strlen(client->GETBuf);
                }

        }

        /* continue according to state */
        PKIX_CHECK(pkix_pl_HttpDefaultClient_Dispatch(client, plCtx),
                PKIX_HTTPDEFAULTCLIENTDISPATCHFAILED);

        switch (client->connectStatus) {
                case HTTP_CONNECT_PENDING:
                case HTTP_SEND_PENDING:
                case HTTP_RECV_HDR_PENDING:
                case HTTP_RECV_BODY_PENDING:
                        pollDesc = &(client->pollDesc);
                        *pSECReturn = SECWouldBlock;
                        break;
                case HTTP_ERROR:
                        /* Did caller provide a pointer for length? */
                        if (client->pRcv_http_data_len != NULL) {
                                /* Was error "response too big?" */
                                if (client->rcv_http_data_len !=
                                            HTTP_UNKNOWN_CONTENT_LENGTH &&
                                    client->maxResponseLen >=
                                                client->rcv_http_data_len) {
                                        /* Yes, report needed space */
                                        *(client->pRcv_http_data_len) =
                                                 client->rcv_http_data_len;
                                } else {
                                        /* No, report problem other than size */
                                        *(client->pRcv_http_data_len) = 0;
                                }
                        }

                        pollDesc = NULL;
                        *pSECReturn = SECFailure;
                        break;
                case HTTP_COMPLETE:
                        *(client->rcv_http_response_code) =
                                client->responseCode;
                        if (client->pRcv_http_data_len != NULL) {
                                *http_response_data_len =
                                         client->rcv_http_data_len;
                        }
                        if (client->rcv_http_data != NULL) {
                                *(client->rcv_http_data) = client->rcvBuf;
                        }
                        pollDesc = NULL;
                        *pSECReturn = SECSuccess;
                        break;
                case HTTP_NOT_CONNECTED:
                case HTTP_CONNECTED:
                case HTTP_RECV_HDR:
                case HTTP_RECV_BODY:
                default:
                        pollDesc = NULL;
                        *pSECReturn = SECFailure;
                        PKIX_ERROR(PKIX_HTTPCLIENTININVALIDSTATE);
                        break;
        }

        if (pPollDesc) {
            *pPollDesc = pollDesc;
        }

cleanup:
        if (sendbuf) {
            PR_smprintf_free(sendbuf);
        }

        PKIX_RETURN(HTTPDEFAULTCLIENT);

}

PKIX_Error *
pkix_pl_HttpDefaultClient_Cancel(
        SEC_HTTP_REQUEST_SESSION request,
        void *plCtx)
{
        PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_Cancel");
        PKIX_NULLCHECK_ONE(request);

        PKIX_CHECK(pkix_CheckType
                ((PKIX_PL_Object *)request,
                PKIX_HTTPDEFAULTCLIENT_TYPE,
                plCtx),
                PKIX_REQUESTNOTANHTTPDEFAULTCLIENT);

        /* XXX Not implemented */

cleanup:

        PKIX_RETURN(HTTPDEFAULTCLIENT);

}

SECStatus
pkix_pl_HttpDefaultClient_CreateSessionFcn(
        const char *host,
        PRUint16 portnum,
        SEC_HTTP_SERVER_SESSION *pSession)
{
        PKIX_Error *err = pkix_pl_HttpDefaultClient_CreateSession
                (host, portnum, pSession, plContext);

        if (err) {
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
                return SECFailure;
        }
        return SECSuccess;
}

SECStatus
pkix_pl_HttpDefaultClient_KeepAliveSessionFcn(
        SEC_HTTP_SERVER_SESSION session,
        PRPollDesc **pPollDesc)
{
        PKIX_Error *err = pkix_pl_HttpDefaultClient_KeepAliveSession
                (session, pPollDesc, plContext);

        if (err) {
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
                return SECFailure;
        }
        return SECSuccess;
}

SECStatus
pkix_pl_HttpDefaultClient_FreeSessionFcn(
        SEC_HTTP_SERVER_SESSION session)
{
        PKIX_Error *err =
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)(session), plContext);

        if (err) {
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
                return SECFailure;
        }
        return SECSuccess;
}

SECStatus
pkix_pl_HttpDefaultClient_RequestCreateFcn(
        SEC_HTTP_SERVER_SESSION session,
        const char *http_protocol_variant, /* usually "http" */
        const char *path_and_query_string,
        const char *http_request_method, 
        const PRIntervalTime timeout, 
        SEC_HTTP_REQUEST_SESSION *pRequest)
{
        PKIX_Error *err = pkix_pl_HttpDefaultClient_RequestCreate
                (session,
                http_protocol_variant,
                path_and_query_string,
                http_request_method,
                timeout,
                pRequest,
                plContext);

        if (err) {
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
                return SECFailure;
        }
        return SECSuccess;
}

SECStatus
pkix_pl_HttpDefaultClient_SetPostDataFcn(
        SEC_HTTP_REQUEST_SESSION request,
        const char *http_data, 
        const PRUint32 http_data_len,
        const char *http_content_type)
{
        PKIX_Error *err =
            pkix_pl_HttpDefaultClient_SetPostData(request, http_data,
                                                  http_data_len,
                                                  http_content_type,
                                                  plContext);
        if (err) {
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
                return SECFailure;
        }
        return SECSuccess;
}

SECStatus
pkix_pl_HttpDefaultClient_AddHeaderFcn(
        SEC_HTTP_REQUEST_SESSION request,
        const char *http_header_name, 
        const char *http_header_value)
{
        /* Not supported */
        return SECFailure;
}

SECStatus
pkix_pl_HttpDefaultClient_TrySendAndReceiveFcn(
        SEC_HTTP_REQUEST_SESSION request,
        PRPollDesc **pPollDesc,
        PRUint16 *http_response_code, 
        const char **http_response_content_type, 
        const char **http_response_headers, 
        const char **http_response_data, 
        PRUint32 *http_response_data_len) 
{
        SECStatus rv = SECFailure;

        PKIX_Error *err = pkix_pl_HttpDefaultClient_TrySendAndReceive
                (request,
                http_response_code, 
                http_response_content_type, 
                http_response_headers, 
                http_response_data, 
                http_response_data_len,
                pPollDesc,
                &rv,
                plContext);

        if (err) {
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
                return rv;
        }
        return SECSuccess;
}

SECStatus
pkix_pl_HttpDefaultClient_CancelFcn(
        SEC_HTTP_REQUEST_SESSION request)
{
        PKIX_Error *err = pkix_pl_HttpDefaultClient_Cancel(request, plContext);

        if (err) {
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
                return SECFailure;
        }
        return SECSuccess;
}

SECStatus
pkix_pl_HttpDefaultClient_FreeFcn(
        SEC_HTTP_REQUEST_SESSION request)
{
        PKIX_Error *err =
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)(request), plContext);

        if (err) {
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
                return SECFailure;
        }
        return SECSuccess;
}
