Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(413)

Unified Diff: nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c
diff --git a/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c b/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c
deleted file mode 100644
index 9954f0ca689b0d43bd7b4f8e657fd12559952b72..0000000000000000000000000000000000000000
--- a/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c
+++ /dev/null
@@ -1,1654 +0,0 @@
-/* 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.
- * "plContext"
- * 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 *plContext)
-{
- 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, plContext),
- 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, plContext),
- 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, plContext),
- 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.
- * "plContext"
- * 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 *plContext)
-{
- 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,
- plContext),
- 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 plContext argument in its
- * function calls. Save it here.
- */
- client->plContext = plContext;
-
- *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 *plContext)
-{
- PKIX_PL_HttpDefaultClient *client = NULL;
-
- PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_HTTPDEFAULTCLIENT_TYPE, plContext),
- PKIX_OBJECTNOTANHTTPDEFAULTCLIENT);
-
- client = (PKIX_PL_HttpDefaultClient *)object;
-
- if (client->rcvHeaders) {
- PKIX_PL_Free(client->rcvHeaders, plContext);
- 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, plContext);
- client->POSTBuf = NULL;
- }
- if (client->rcvBuf != NULL) {
- PKIX_PL_Free(client->rcvBuf, plContext);
- 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 *plContext)
-{
- 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.
- * "plContext"
- * 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 *plContext)
-{
- 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, plContext),
- 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.
- * "plContext"
- * 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 *plContext)
-{
- 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,
- plContext),
- 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.
- * "plContext"
- * 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 *plContext)
-{
- 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, plContext),
- 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.
- * "plContext"
- * 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 *plContext)
-{
- 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),
- plContext),
- 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,
- plContext),
- PKIX_SOCKETRECVFAILED);
-
- if (bytesRead > 0) {
- /* client->filledupBytes will be adjusted by
- * pkix_pl_HttpDefaultClient_HdrCheckComplete */
- PKIX_CHECK(
- pkix_pl_HttpDefaultClient_HdrCheckComplete(client, bytesRead,
- pKeepGoing,
- plContext),
- 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.
- * "plContext"
- * 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 *plContext)
-{
- 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, plContext),
- PKIX_SOCKETPOLLFAILED);
-
- if (bytesRead > 0) {
- client->filledupBytes += bytesRead;
-
- PKIX_CHECK(pkix_pl_HttpDefaultClient_HdrCheckComplete
- (client, bytesRead, pKeepGoing, plContext),
- 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.
- * "plContext"
- * 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 *plContext)
-{
- 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, plContext),
- 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, plContext),
- PKIX_SOCKETPOLLFAILED);
- } else {
- PKIX_CHECK(callbackList->recvCallback
- (client->socket,
- (void *)&(client->rcvBuf[client->filledupBytes]),
- bytesToRead,
- &bytesRead,
- plContext),
- 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.
- * "plContext"
- * 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 *plContext)
-{
- 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, plContext),
- PKIX_HTTPDEFAULTCLIENTCONNECTCONTINUEFAILED);
- break;
- case HTTP_CONNECTED:
- PKIX_CHECK(pkix_pl_HttpDefaultClient_Send
- (client, &keepGoing, &bytesTransferred, plContext),
- PKIX_HTTPDEFAULTCLIENTSENDFAILED);
- break;
- case HTTP_SEND_PENDING:
- PKIX_CHECK(pkix_pl_HttpDefaultClient_SendContinue
- (client, &keepGoing, &bytesTransferred, plContext),
- PKIX_HTTPDEFAULTCLIENTSENDCONTINUEFAILED);
- break;
- case HTTP_RECV_HDR:
- PKIX_CHECK(pkix_pl_HttpDefaultClient_RecvHdr
- (client, &keepGoing, plContext),
- PKIX_HTTPDEFAULTCLIENTRECVHDRFAILED);
- break;
- case HTTP_RECV_HDR_PENDING:
- PKIX_CHECK(pkix_pl_HttpDefaultClient_RecvHdrContinue
- (client, &keepGoing, plContext),
- PKIX_HTTPDEFAULTCLIENTRECVHDRCONTINUEFAILED);
- break;
- case HTTP_RECV_BODY:
- case HTTP_RECV_BODY_PENDING:
- PKIX_CHECK(pkix_pl_HttpDefaultClient_RecvBody
- (client, &keepGoing, plContext),
- 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 *plContext)
-{
- 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, plContext),
- 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 *plContext)
-{
- PKIX_ENTER
- (HTTPDEFAULTCLIENT,
- "pkix_pl_HttpDefaultClient_KeepAliveSession");
- PKIX_NULLCHECK_TWO(session, pPollDesc);
-
- PKIX_CHECK(pkix_CheckType
- ((PKIX_PL_Object *)session,
- PKIX_HTTPDEFAULTCLIENT_TYPE,
- plContext),
- 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 *plContext)
-{
- 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,
- plContext),
- 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,
- plContext),
- PKIX_HTTPCERTSTOREFINDSOCKETCONNECTIONFAILED);
-#else
- PKIX_CHECK(pkix_HttpCertStore_FindSocketConnection
- (timeout,
- (char *)client->host,
- client->portnum,
- &status,
- &socket,
- plContext),
- PKIX_HTTPCERTSTOREFINDSOCKETCONNECTIONFAILED);
-#endif
-
- client->socket = socket;
-
- PKIX_CHECK(pkix_pl_Socket_GetCallbackList
- (socket, &callbackList, plContext),
- PKIX_SOCKETGETCALLBACKLISTFAILED);
-
- client->callbackList = (void *)callbackList;
-
- PKIX_CHECK(pkix_pl_Socket_GetPRFileDesc
- (socket, &fileDesc, plContext),
- 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 *plContext)
-{
- 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,
- plContext),
- 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 *plContext)
-{
- 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,
- plContext),
- 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),
- plContext),
- 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, plContext),
- 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 *plContext)
-{
- PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_Cancel");
- PKIX_NULLCHECK_ONE(request);
-
- PKIX_CHECK(pkix_CheckType
- ((PKIX_PL_Object *)request,
- PKIX_HTTPDEFAULTCLIENT_TYPE,
- plContext),
- 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;
-}

Powered by Google App Engine
This is Rietveld 408576698