Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions
nsNSSHttpRequestSession Class Reference

#include <nsNSSCallbacks.h>

Collaboration diagram for nsNSSHttpRequestSession:
Collaboration graph
[legend]

List of all members.

Public Member Functions

SECStatus setPostDataFcn (const char *http_data, const PRUint32 http_data_len, const char *http_content_type)
SECStatus addHeaderFcn (const char *http_header_name, const char *http_header_value)
SECStatus trySendAndReceiveFcn (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 cancelFcn ()
SECStatus freeFcn ()

Static Public Member Functions

static SECStatus createFcn (SEC_HTTP_SERVER_SESSION session, const char *http_protocol_variant, const char *path_and_query_string, const char *http_request_method, const PRIntervalTime timeout, SEC_HTTP_REQUEST_SESSION *pRequest)

Public Attributes

nsCString mURL
nsCString mRequestMethod
PRBool mHasPostData
nsCString mPostData
nsCString mPostContentType
PRIntervalTime mTimeoutInterval
nsCOMPtr< nsHTTPListenermListener

Protected Member Functions

 nsNSSHttpRequestSession ()
 ~nsNSSHttpRequestSession ()
SECStatus internal_send_receive_attempt (PRBool &retryable_error, 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)

Detailed Description

Definition at line 102 of file nsNSSCallbacks.h.


Constructor & Destructor Documentation

Definition at line 503 of file nsNSSCallbacks.cpp.

Here is the caller graph for this function:

Definition at line 510 of file nsNSSCallbacks.cpp.

{
}

Member Function Documentation

SECStatus nsNSSHttpRequestSession::addHeaderFcn ( const char *  http_header_name,
const char *  http_header_value 
)

Definition at line 246 of file nsNSSCallbacks.cpp.

{
  return SECFailure; // not yet implemented

  // All http code needs to be postponed to the UI thread.
  // Once this gets implemented, we need to add a string list member to
  // nsNSSHttpRequestSession and queue up the headers,
  // so they can be added in HandleHTTPDownloadPLEvent.
  //
  // The header will need to be set using 
  //   mHttpChannel->SetRequestHeader(nsDependentCString(http_header_name), 
  //                                  nsDependentCString(http_header_value), 
  //                                  PR_FALSE)));
}

Definition at line 489 of file nsNSSCallbacks.cpp.

{
  // As of today, only the blocking variant of the http interface
  // has been implemented. Implementing cancelFcn will be necessary
  // as soon as we implement the nonblocking variant.
  return SECSuccess;
}
SECStatus nsNSSHttpRequestSession::createFcn ( SEC_HTTP_SERVER_SESSION  session,
const char *  http_protocol_variant,
const char *  path_and_query_string,
const char *  http_request_method,
const PRIntervalTime  timeout,
SEC_HTTP_REQUEST_SESSION pRequest 
) [static]

Definition at line 201 of file nsNSSCallbacks.cpp.

{
  if (!session || !http_protocol_variant || !path_and_query_string || 
      !http_request_method || !pRequest)
    return SECFailure;

  nsNSSHttpServerSession* hss = NS_STATIC_CAST(nsNSSHttpServerSession*, session);
  if (!hss)
    return SECFailure;

  nsNSSHttpRequestSession *rs = new nsNSSHttpRequestSession;
  if (!rs)
    return SECFailure;

  rs->mTimeoutInterval = timeout;

  rs->mURL.Append(nsDependentCString(http_protocol_variant));
  rs->mURL.AppendLiteral("://");
  rs->mURL.Append(hss->mHost);
  rs->mURL.AppendLiteral(":");
  rs->mURL.AppendInt(hss->mPort);
  rs->mURL.Append(path_and_query_string);

  rs->mRequestMethod = nsDependentCString(http_request_method);

  *pRequest = (void*)rs;
  return SECSuccess;
}

Here is the call graph for this function:

Definition at line 497 of file nsNSSCallbacks.cpp.

{
  delete this;
  return SECSuccess;
}
SECStatus nsNSSHttpRequestSession::internal_send_receive_attempt ( PRBool retryable_error,
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 
) [protected]

Definition at line 347 of file nsNSSCallbacks.cpp.

{
  if (pPollDesc) *pPollDesc = nsnull;
  if (http_response_code) *http_response_code = 0;
  if (http_response_content_type) *http_response_content_type = 0;
  if (http_response_headers) *http_response_headers = 0;
  if (http_response_data) *http_response_data = 0;

  PRUint32 acceptableResultSize = 0;

  if (http_response_data_len)
  {
    acceptableResultSize = *http_response_data_len;
    *http_response_data_len = 0;
  }
  
  nsCOMPtr<nsIEventQueue> uiQueue = nsNSSEventGetUIEventQueue();
  if (!uiQueue)
    return SECFailure;

  if (!mListener)
    return SECFailure;

  if (NS_FAILED(mListener->InitLocks()))
    return SECFailure;

  PRLock *waitLock = mListener->mLock;
  PRCondVar *waitCondition = mListener->mCondition;
  volatile PRBool &waitFlag = mListener->mWaitFlag;
  waitFlag = PR_TRUE;

  nsHTTPDownloadEvent *event = new nsHTTPDownloadEvent;
  if (!event)
    return SECFailure;

  event->mListener = mListener;
  event->mRequestSession = this;

  PL_InitEvent(event, nsnull, (PLHandleEventProc)HandleHTTPDownloadPLEvent, 
                              (PLDestroyEventProc)DestroyHTTPDownloadPLEvent);
  nsresult rv = uiQueue->PostEvent(event);
  if (NS_FAILED(rv))
  {
    event->mResponsibleForDoneSignal = PR_FALSE;
    delete event;
    return SECFailure;
  }

  PRBool request_canceled = PR_FALSE;
  PRBool aborted_wait = PR_FALSE;

  {
    nsAutoLock locker(waitLock);

    const PRIntervalTime start_time = PR_IntervalNow();
    const PRIntervalTime wait_interval = CONDITION_WAIT_TIME;

    while (waitFlag)
    {
      PR_WaitCondVar(waitCondition, wait_interval);
      
      if (!waitFlag)
        break;

      if (!request_canceled)
      {
        if ((PRIntervalTime)(PR_IntervalNow() - start_time) > mTimeoutInterval)
        {
          request_canceled = PR_TRUE;
          // but we'll to continue to wait for waitFlag
          
          nsCancelHTTPDownloadEvent *cancelevent = new nsCancelHTTPDownloadEvent;
          PL_InitEvent(cancelevent, nsnull, (PLHandleEventProc)HandleCancelHTTPDownloadPLEvent, 
                                            (PLDestroyEventProc)DestroyCancelHTTPDownloadPLEvent);
          rv = uiQueue->PostEvent(cancelevent);
          if (NS_FAILED(rv))
          {
            NS_WARNING("cannot post cancel event");
            delete cancelevent;
            aborted_wait = PR_TRUE;
            break;
          }
        }
      }
    }
  }

  if (aborted_wait)
  {
    // we couldn't cancel it, let's no longer reference it
    nsSSLThread::rememberPendingHTTPRequest(nsnull);
  }

  if (request_canceled)
    return SECFailure;

  if (NS_FAILED(mListener->mResultCode))
  {
    if (mListener->mResultCode == NS_ERROR_CONNECTION_REFUSED
        ||
        mListener->mResultCode == NS_ERROR_NET_RESET)
    {
      retryable_error = PR_TRUE;
    }
    return SECFailure;
  }

  if (http_response_code)
    *http_response_code = mListener->mHttpResponseCode;

  if (mListener->mHttpRequestSucceeded && http_response_data && http_response_data_len) {

    *http_response_data_len = mListener->mResultLen;
  
    // acceptableResultSize == 0 means: any size is acceptable
    if (acceptableResultSize != 0
        &&
        acceptableResultSize < mListener->mResultLen)
    {
      return SECFailure;
    }

    // return data by reference, result data will be valid 
    // until "this" gets destroyed by NSS
    *http_response_data = (const char*)mListener->mResultData;
  }

  if (mListener->mHttpRequestSucceeded && http_response_content_type) {
    if (mListener->mHttpResponseContentType.Length()) {
      *http_response_content_type = mListener->mHttpResponseContentType.get();
    }
  }

  return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus nsNSSHttpRequestSession::setPostDataFcn ( const char *  http_data,
const PRUint32  http_data_len,
const char *  http_content_type 
)

Definition at line 235 of file nsNSSCallbacks.cpp.

{
  mHasPostData = PR_TRUE;
  mPostData.Assign(http_data, http_data_len);
  mPostContentType.Assign(http_content_type);

  return SECSuccess;
}
SECStatus nsNSSHttpRequestSession::trySendAndReceiveFcn ( 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 
)

Definition at line 264 of file nsNSSCallbacks.cpp.

{
  PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
         ("nsNSSHttpRequestSession::trySendAndReceiveFcn to %s\n", mURL.get()));

  if (nsIThread::IsMainThread())
  {
    nsresult rv;
    nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
    if (NS_FAILED(rv))
      return SECFailure;

    nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
    if (wwatch){
      nsCOMPtr<nsIPrompt> prompter;
      wwatch->GetNewPrompter(0, getter_AddRefs(prompter));

      nsString message;
      nssComponent->GetPIPNSSBundleString("OCSPDeadlock", message);

      if(prompter) {
        nsPSMUITracker tracker;
        if (!tracker.isUIForbidden()) {
          prompter->Alert(0, message.get());
        }
      }
    }

    return SECFailure;
  }

  const int max_retries = 5;
  int retry_count = 0;
  PRBool retryable_error = PR_FALSE;
  SECStatus result_sec_status = SECFailure;

  do
  {
    if (retry_count > 0)
    {
      if (retryable_error)
      {
        PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
               ("nsNSSHttpRequestSession::trySendAndReceiveFcn - sleeping and retrying: %d of %d\n",
                retry_count, max_retries));
      }

      PR_Sleep( PR_MillisecondsToInterval(300) * retry_count );
    }

    ++retry_count;
    retryable_error = PR_FALSE;

    result_sec_status =
      internal_send_receive_attempt(retryable_error, pPollDesc, http_response_code,
                                    http_response_content_type, http_response_headers,
                                    http_response_data, http_response_data_len);
  }
  while (retryable_error &&
         retry_count < max_retries);

#ifdef PR_LOGGING
  if (retry_count > 1)
  {
    if (retryable_error)
      PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
             ("nsNSSHttpRequestSession::trySendAndReceiveFcn - still failing, giving up...\n"));
    else
      PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
             ("nsNSSHttpRequestSession::trySendAndReceiveFcn - success at attempt %d\n",
              retry_count));
  }
#endif

  return result_sec_status;
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 132 of file nsNSSCallbacks.h.

Definition at line 138 of file nsNSSCallbacks.h.

Definition at line 134 of file nsNSSCallbacks.h.

Definition at line 133 of file nsNSSCallbacks.h.

Definition at line 130 of file nsNSSCallbacks.h.

Definition at line 136 of file nsNSSCallbacks.h.

Definition at line 129 of file nsNSSCallbacks.h.


The documentation for this class was generated from the following files: