//static void XPCJSRuntime::WatchdogMain(void *arg) { XPCJSRuntime* self = static_cast<XPCJSRuntime*>(arg); // Lock lasts until we return AutoLockJSGC lock(self->mJSRuntime); PRIntervalTime sleepInterval; while (self->mWatchdogThread) { // Sleep only 1 second if recently (or currently) active; otherwise, hibernate if (self->mLastActiveTime == -1 || PR_Now() - self->mLastActiveTime <= 2*PR_USEC_PER_SEC) sleepInterval = PR_TicksPerSecond(); else { sleepInterval = PR_INTERVAL_NO_TIMEOUT; self->mWatchdogHibernating = PR_TRUE; } #ifdef DEBUG PRStatus status = #endif PR_WaitCondVar(self->mWatchdogWakeup, sleepInterval); JS_ASSERT(status == PR_SUCCESS); JSContext* cx = nsnull; while((cx = js_NextActiveContext(self->mJSRuntime, cx))) { JS_TriggerOperationCallback(cx); } } /* Wake up the main thread waiting for the watchdog to terminate. */ PR_NotifyCondVar(self->mWatchdogWakeup); }
//static void XPCJSRuntime::WatchdogMain(void *arg) { XPCJSRuntime* self = static_cast<XPCJSRuntime*>(arg); // Lock lasts until we return AutoLockJSGC lock(self->mJSRuntime); while (self->mWatchdogThread) { #ifdef DEBUG PRStatus status = #endif PR_WaitCondVar(self->mWatchdogWakeup, PR_TicksPerSecond()); JS_ASSERT(status == PR_SUCCESS); JSContext* cx = nsnull; while((cx = js_NextActiveContext(self->mJSRuntime, cx))) { JS_TriggerOperationCallback(cx); } } /* Wake up the main thread waiting for the watchdog to terminate. */ PR_NotifyCondVar(self->mWatchdogWakeup); }
static PRIntn pt_TimedWait( pthread_cond_t *cv, pthread_mutex_t *ml, PRIntervalTime timeout) { int rv; struct timeval now; struct timespec tmo; PRUint32 ticks = PR_TicksPerSecond(); tmo.tv_sec = (PRInt32)(timeout / ticks); tmo.tv_nsec = (PRInt32)(timeout - (tmo.tv_sec * ticks)); tmo.tv_nsec = (PRInt32)PR_IntervalToMicroseconds(PT_NANOPERMICRO * tmo.tv_nsec); /* pthreads wants this in absolute time, off we go ... */ (void)GETTIMEOFDAY(&now); /* that one's usecs, this one's nsecs - grrrr! */ tmo.tv_sec += now.tv_sec; tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec); tmo.tv_sec += tmo.tv_nsec / PT_BILLION; tmo.tv_nsec %= PT_BILLION; rv = pthread_cond_timedwait(cv, ml, &tmo); /* NSPR doesn't report timeouts */ #ifdef _PR_DCETHREADS if (rv == -1) return (errno == EAGAIN) ? 0 : errno; else return rv; #else return (rv == ETIMEDOUT) ? 0 : rv; #endif } /* pt_TimedWait */
/* * FUNCTION: pkix_pl_HttpCertStore_CreateRequestSession * DESCRIPTION: * * This function takes elements from the HttpCertStoreContext pointed to by * "context" (path, client, and serverSession) and creates a RequestSession. * See the HTTPClient API described in ocspt.h for further details. * * PARAMETERS: * "context" * The address of the HttpCertStoreContext. 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 HttpCertStore Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_HttpCertStore_CreateRequestSession( PKIX_PL_HttpCertStoreContext *context, void *plContext) { const SEC_HttpClientFcnV1 *hcv1 = NULL; SECStatus rv = SECFailure; char *pathString = NULL; PKIX_ENTER (HTTPCERTSTORECONTEXT, "pkix_pl_HttpCertStore_CreateRequestSession"); PKIX_NULLCHECK_TWO(context, context->serverSession); pathString = PR_smprintf("%s", context->path); if (context->client->version == 1) { hcv1 = &(context->client->fcnTable.ftable1); if (context->requestSession != NULL) { PKIX_PL_NSSCALL(HTTPCERTSTORECONTEXT, hcv1->freeFcn, (context->requestSession)); context->requestSession = 0; } PKIX_PL_NSSCALLRV (HTTPCERTSTORECONTEXT, rv, hcv1->createFcn, (context->serverSession, "http", pathString, "GET", PR_TicksPerSecond() * 60, &(context->requestSession))); if (rv != SECSuccess) { if (pathString != NULL) { PORT_Free(pathString); } PKIX_ERROR(PKIX_HTTPSERVERERROR); } } else { PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT); } cleanup: PKIX_RETURN(HTTPCERTSTORECONTEXT); }
_pt_wait(PRThread *thread, PRIntervalTime timeout) { int rv; struct timeval now; struct timespec tmo; PRUint32 ticks = PR_TicksPerSecond(); if (timeout != PR_INTERVAL_NO_TIMEOUT) { tmo.tv_sec = timeout / ticks; tmo.tv_nsec = timeout - (tmo.tv_sec * ticks); tmo.tv_nsec = PR_IntervalToMicroseconds(PT_NANOPERMICRO * tmo.tv_nsec); /* pthreads wants this in absolute time, off we go ... */ (void)GETTIMEOFDAY(&now); /* that one's usecs, this one's nsecs - grrrr! */ tmo.tv_sec += now.tv_sec; tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec); tmo.tv_sec += tmo.tv_nsec / PT_BILLION; tmo.tv_nsec %= PT_BILLION; } pthread_mutex_lock(&thread->md.pthread_mutex); thread->md.wait--; if (thread->md.wait < 0) { if (timeout != PR_INTERVAL_NO_TIMEOUT) { rv = pthread_cond_timedwait(&thread->md.pthread_cond, &thread->md.pthread_mutex, &tmo); } else rv = pthread_cond_wait(&thread->md.pthread_cond, &thread->md.pthread_mutex); if (rv != 0) { thread->md.wait++; } } else rv = 0; pthread_mutex_unlock(&thread->md.pthread_mutex); return (rv == 0) ? PR_SUCCESS : PR_FAILURE; }
int main(int argc, const char **argv) { if (argc != 3) usage(argv[0]); try { WikiDumpParser parser(argv[1], argv[2]); PRThread *runner = 0; { MonitorBlock sync(&parser); runner = PR_CreateThread(PR_USER_THREAD, myThreadStart, &parser, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); sync.wait(); } size_t ticksPerSecond = PR_TicksPerSecond(); float progress; do { progress = parser.getProgress(); std::cout << progress << std::endl; PR_Sleep(1 * ticksPerSecond); } while (progress > 0 && progress < 1); PR_JoinThread(runner); if (progress == -1) { std::cerr << parser.errMsg() << std::endl; return 1; } //parser.parse(); } catch (std::exception &e) { std::cerr << "error: " << e.what() << std::endl; } catch (...) { std::cerr << "error: ..." << std::endl; } return 0; }
void NotifyExpired(Object* aObj) { LogAction(aObj, "Expired"); PRIntervalTime now = PR_IntervalNow(); uint32_t timeDiffMS = (now - aObj->mLastUsed)*1000/PR_TicksPerSecond(); // See the comment for NotifyExpired in nsExpirationTracker.h for these // bounds uint32_t lowerBoundMS = (K-1)*periodMS - slackMS; uint32_t upperBoundMS = K*(periodMS + sleepPeriodMS) + slackMS; if (logging) { printf("Checking: %d-%d = %d [%d,%d]\n", now, aObj->mLastUsed, timeDiffMS, lowerBoundMS, upperBoundMS); } if (timeDiffMS < lowerBoundMS || timeDiffMS > upperBoundMS) { EXPECT_TRUE(timeDiffMS < periodMS && aObj->mExpired); } aObj->Touch(); aObj->mExpired = true; DoRandomOperation(); DoRandomOperation(); DoRandomOperation(); }
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) { if (!session || !http_protocol_variant || !path_and_query_string || !http_request_method || !pRequest) return SECFailure; nsNSSHttpServerSession* hss = static_cast<nsNSSHttpServerSession*>(session); if (!hss) return SECFailure; nsNSSHttpRequestSession *rs = new nsNSSHttpRequestSession; if (!rs) return SECFailure; rs->mTimeoutInterval = timeout; // Use a maximum timeout value of 10 seconds because of bug 404059. // FIXME: Use a better approach once 406120 is ready. PRUint32 maxBug404059Timeout = PR_TicksPerSecond() * 10; if (timeout > maxBug404059Timeout) { rs->mTimeoutInterval = maxBug404059Timeout; } 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; }
nsresult TimeStamp::Startup() { if (gInitialized) return NS_OK; const char *envp; APIRET rc; // Use the same variable as NSPR's os2inrval.c does to let the user disable the // high-resolution timer (it is known that it doesn't work well on some hardware) if ((envp = getenv("NSPR_OS2_NO_HIRES_TIMER")) != NULL) { if (atoi(envp) != 1) { // Attempt to use the high-res timer rc = DosTmrQueryFreq(&gTicksPerSec); if (rc == NO_ERROR) gUseHighResTimer = true; } } if (!gUseHighResTimer) { // TimeStamp has to use bare PRLock instead of mozilla::Mutex // because TimeStamp can be used very early in startup. gTimeStampLock = PR_NewLock(); if (!gTimeStampLock) return NS_ERROR_OUT_OF_MEMORY; gRolloverCount = 1; gLastNow = 0; gTicksPerSec = PR_TicksPerSecond(); } gTicksPerSecDbl = gTicksPerSec; gTicksPerMsDbl = gTicksPerSecDbl / 1000.0; gInitialized = true; sFirstTimeStamp = TimeStamp::Now(); sProcessCreation = TimeStamp(); return NS_OK; }
void VideoSourceCanvas::Grabber(void *data) { nsresult rv; PRUint32 wr; VideoSourceCanvas *vs = static_cast<VideoSourceCanvas*>(data); int isize = vs->GetFrameSize(); int fsize = vs->width * vs->height * 4; char *i420 = (char *)PR_Calloc(isize, 1); PRUint8 *rgb32 = (PRUint8 *)PR_Calloc(fsize, 1); PRTime epoch_c; PRFloat64 epoch; PRIntervalTime ticks = PR_TicksPerSecond() / 30; while (vs->running) { PR_Sleep(ticks); if (vs->is_rec == PR_FALSE) continue; rv = vs->vCanvas->GetImageData_explicit( 0, 0, vs->width, vs->height, rgb32, fsize ); if (NS_FAILED(rv)) continue; RGB32toI420(vs->width, vs->height, (const char *)rgb32, i420); epoch_c = PR_Now(); epoch = (PRFloat64)(epoch_c / MICROSECONDS); epoch += ((PRFloat64)(epoch_c % MICROSECONDS)) / MICROSECONDS; rv = vs->output->Write((const char *)&epoch, sizeof(PRFloat64), &wr); rv = vs->output->Write((const char *)&isize, sizeof(PRUint32), &wr); rv = vs->output->Write((const char *)i420, isize, &wr); } PR_Free(i420); PR_Free(rgb32); return; }
static void TestConversions(void) { PRIntervalTime ticks = PR_TicksPerSecond(); if (debug_mode) { PR_fprintf(output, "PR_TicksPerSecond: %ld\n\n", ticks); PR_fprintf(output, "PR_SecondsToInterval(1): %ld\n", PR_SecondsToInterval(1)); PR_fprintf(output, "PR_MillisecondsToInterval(1000): %ld\n", PR_MillisecondsToInterval(1000)); PR_fprintf(output, "PR_MicrosecondsToInterval(1000000): %ld\n\n", PR_MicrosecondsToInterval(1000000)); PR_fprintf(output, "PR_SecondsToInterval(3): %ld\n", PR_SecondsToInterval(3)); PR_fprintf(output, "PR_MillisecondsToInterval(3000): %ld\n", PR_MillisecondsToInterval(3000)); PR_fprintf(output, "PR_MicrosecondsToInterval(3000000): %ld\n\n", PR_MicrosecondsToInterval(3000000)); PR_fprintf(output, "PR_IntervalToSeconds(%ld): %ld\n", ticks, PR_IntervalToSeconds(ticks)); PR_fprintf(output, "PR_IntervalToMilliseconds(%ld): %ld\n", ticks, PR_IntervalToMilliseconds(ticks)); PR_fprintf(output, "PR_IntervalToMicroseconds(%ld): %ld\n\n", ticks, PR_IntervalToMicroseconds(ticks)); ticks *= 3; PR_fprintf(output, "PR_IntervalToSeconds(%ld): %ld\n", ticks, PR_IntervalToSeconds(ticks)); PR_fprintf(output, "PR_IntervalToMilliseconds(%ld): %ld\n", ticks, PR_IntervalToMilliseconds(ticks)); PR_fprintf(output, "PR_IntervalToMicroseconds(%ld): %ld\n\n", ticks, PR_IntervalToMicroseconds(ticks)); } /*end debug mode */ } /* TestConversions */
TimeDuration TimeDuration::FromMilliseconds(double aMilliseconds) { static double kTicksPerMs = double(PR_TicksPerSecond()) / 1000.0; return TimeDuration::FromTicks(aMilliseconds * kTicksPerMs); }
double TimeDuration::ToSeconds() const { return double(mValue)/PR_TicksPerSecond(); }
PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) { #ifdef BSD_SELECT fd_set rd, wt, ex; #else int rd, wt, ex; int* socks; unsigned long msecs; int i, j; #endif PRFileDesc *bottom; PRPollDesc *pd, *epd; PRInt32 maxfd = -1, ready, err; PRIntervalTime remaining, elapsed, start; #ifdef BSD_SELECT struct timeval tv, *tvp = NULL; FD_ZERO(&rd); FD_ZERO(&wt); FD_ZERO(&ex); #else rd = 0; wt = 0; ex = 0; socks = (int) PR_MALLOC( npds * 3 * sizeof(int) ); if (!socks) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return -1; } #endif ready = 0; for (pd = pds, epd = pd + npds; pd < epd; pd++) { PRInt16 in_flags_read = 0, in_flags_write = 0; PRInt16 out_flags_read = 0, out_flags_write = 0; if ((NULL != pd->fd) && (0 != pd->in_flags)) { if (pd->in_flags & PR_POLL_READ) { in_flags_read = (pd->fd->methods->poll)( pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); } if (pd->in_flags & PR_POLL_WRITE) { in_flags_write = (pd->fd->methods->poll)( pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); } if ((0 != (in_flags_read & out_flags_read)) || (0 != (in_flags_write & out_flags_write))) { /* this one's ready right now */ if (0 == ready) { /* * We will have to return without calling the * system poll/select function. So zero the * out_flags fields of all the poll descriptors * before this one. */ PRPollDesc *prev; for (prev = pds; prev < pd; prev++) { prev->out_flags = 0; } } ready += 1; pd->out_flags = out_flags_read | out_flags_write; } else { pd->out_flags = 0; /* pre-condition */ /* make sure this is an NSPR supported stack */ bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); PR_ASSERT(NULL != bottom); /* what to do about that? */ if ((NULL != bottom) && (_PR_FILEDESC_OPEN == bottom->secret->state)) { if (0 == ready) { PRInt32 osfd = bottom->secret->md.osfd; if (osfd > maxfd) maxfd = osfd; if (in_flags_read & PR_POLL_READ) { pd->out_flags |= _PR_POLL_READ_SYS_READ; #ifdef BSD_SELECT FD_SET(osfd, &rd); #else socks[rd] = osfd; rd++; #endif } if (in_flags_read & PR_POLL_WRITE) { pd->out_flags |= _PR_POLL_READ_SYS_WRITE; #ifdef BSD_SELECT FD_SET(osfd, &wt); #else socks[npds+wt] = osfd; wt++; #endif } if (in_flags_write & PR_POLL_READ) { pd->out_flags |= _PR_POLL_WRITE_SYS_READ; #ifdef BSD_SELECT FD_SET(osfd, &rd); #else socks[rd] = osfd; rd++; #endif } if (in_flags_write & PR_POLL_WRITE) { pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; #ifdef BSD_SELECT FD_SET(osfd, &wt); #else socks[npds+wt] = osfd; wt++; #endif } if (pd->in_flags & PR_POLL_EXCEPT) { #ifdef BSD_SELECT FD_SET(osfd, &ex); #else socks[npds*2+ex] = osfd; ex++; #endif } } } else { if (0 == ready) { PRPollDesc *prev; for (prev = pds; prev < pd; prev++) { prev->out_flags = 0; } } ready += 1; /* this will cause an abrupt return */ pd->out_flags = PR_POLL_NVAL; /* bogii */ } } } else { pd->out_flags = 0; } } if (0 != ready) { #ifndef BSD_SELECT PR_Free(socks); #endif return ready; /* no need to block */ } remaining = timeout; start = PR_IntervalNow(); retry: #ifdef BSD_SELECT if (timeout != PR_INTERVAL_NO_TIMEOUT) { PRInt32 ticksPerSecond = PR_TicksPerSecond(); tv.tv_sec = remaining / ticksPerSecond; tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond ); tvp = &tv; } ready = bsdselect(maxfd + 1, &rd, &wt, &ex, tvp); #else switch (timeout) { case PR_INTERVAL_NO_WAIT: msecs = 0; break; case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break; default: msecs = PR_IntervalToMilliseconds(remaining); } /* compact array */ for( i = rd, j = npds; j < npds+wt; i++,j++ ) socks[i] = socks[j]; for( i = rd+wt, j = npds*2; j < npds*2+ex; i++,j++ ) socks[i] = socks[j]; ready = os2_select(socks, rd, wt, ex, msecs); #endif if (ready == -1 && errno == EINTR) { if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry; else { elapsed = (PRIntervalTime) (PR_IntervalNow() - start); if (elapsed > timeout) ready = 0; /* timed out */ else { remaining = timeout - elapsed; goto retry; } } } /* ** Now to unravel the select sets back into the client's poll ** descriptor list. Is this possibly an area for pissing away ** a few cycles or what? */ if (ready > 0) { ready = 0; for (pd = pds, epd = pd + npds; pd < epd; pd++) { PRInt16 out_flags = 0; if ((NULL != pd->fd) && (0 != pd->in_flags)) { PRInt32 osfd; bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); PR_ASSERT(NULL != bottom); osfd = bottom->secret->md.osfd; #ifdef BSD_SELECT if (FD_ISSET(osfd, &rd)) #else if( IsSocketSet(osfd, socks, 0, rd) ) #endif { if (pd->out_flags & _PR_POLL_READ_SYS_READ) out_flags |= PR_POLL_READ; if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) out_flags |= PR_POLL_WRITE; } #ifdef BSD_SELECT if (FD_ISSET(osfd, &wt)) #else if( IsSocketSet(osfd, socks, rd, wt) ) #endif { if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) out_flags |= PR_POLL_READ; if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) out_flags |= PR_POLL_WRITE; } #ifdef BSD_SELECT if (FD_ISSET(osfd, &ex)) #else if( IsSocketSet(osfd, socks, rd+wt, ex) ) #endif { out_flags |= PR_POLL_EXCEPT; } } pd->out_flags = out_flags; if (out_flags) ready++; } PR_ASSERT(ready > 0); } else if (ready < 0) { err = _MD_ERRNO(); if (err == EBADF) { /* Find the bad fds */ int optval; int optlen = sizeof(optval); ready = 0; for (pd = pds, epd = pd + npds; pd < epd; pd++) { pd->out_flags = 0; if ((NULL != pd->fd) && (0 != pd->in_flags)) { bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET, SO_TYPE, (char *) &optval, &optlen) == -1) { PR_ASSERT(sock_errno() == ENOTSOCK); if (sock_errno() == ENOTSOCK) { pd->out_flags = PR_POLL_NVAL; ready++; } } } } PR_ASSERT(ready > 0); } else _PR_MD_MAP_SELECT_ERROR(err); } #ifndef BSD_SELECT PR_Free(socks); #endif return ready; }
static PRInt32 NativeThreadSelect( PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) { /* * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL(). */ fd_set rd, wt, ex; PRFileDesc *bottom; PRPollDesc *pd, *epd; PRInt32 maxfd = -1, ready, err; PRIntervalTime remaining, elapsed, start; struct timeval tv, *tvp = NULL; FD_ZERO(&rd); FD_ZERO(&wt); FD_ZERO(&ex); ready = 0; for (pd = pds, epd = pd + npds; pd < epd; pd++) { PRInt16 in_flags_read = 0, in_flags_write = 0; PRInt16 out_flags_read = 0, out_flags_write = 0; if ((NULL != pd->fd) && (0 != pd->in_flags)) { if (pd->in_flags & PR_POLL_READ) { in_flags_read = (pd->fd->methods->poll)( pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); } if (pd->in_flags & PR_POLL_WRITE) { in_flags_write = (pd->fd->methods->poll)( pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); } if ((0 != (in_flags_read & out_flags_read)) || (0 != (in_flags_write & out_flags_write))) { /* this one's ready right now */ if (0 == ready) { /* * We will have to return without calling the * system poll/select function. So zero the * out_flags fields of all the poll descriptors * before this one. */ PRPollDesc *prev; for (prev = pds; prev < pd; prev++) { prev->out_flags = 0; } } ready += 1; pd->out_flags = out_flags_read | out_flags_write; } else { pd->out_flags = 0; /* pre-condition */ /* make sure this is an NSPR supported stack */ bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); PR_ASSERT(NULL != bottom); /* what to do about that? */ if ((NULL != bottom) && (_PR_FILEDESC_OPEN == bottom->secret->state)) { if (0 == ready) { PRInt32 osfd = bottom->secret->md.osfd; if (osfd > maxfd) maxfd = osfd; if (in_flags_read & PR_POLL_READ) { pd->out_flags |= _PR_POLL_READ_SYS_READ; FD_SET(osfd, &rd); } if (in_flags_read & PR_POLL_WRITE) { pd->out_flags |= _PR_POLL_READ_SYS_WRITE; FD_SET(osfd, &wt); } if (in_flags_write & PR_POLL_READ) { pd->out_flags |= _PR_POLL_WRITE_SYS_READ; FD_SET(osfd, &rd); } if (in_flags_write & PR_POLL_WRITE) { pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; FD_SET(osfd, &wt); } if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex); } } else { if (0 == ready) { PRPollDesc *prev; for (prev = pds; prev < pd; prev++) { prev->out_flags = 0; } } ready += 1; /* this will cause an abrupt return */ pd->out_flags = PR_POLL_NVAL; /* bogii */ } } } else { pd->out_flags = 0; } } if (0 != ready) return ready; /* no need to block */ remaining = timeout; start = PR_IntervalNow(); retry: if (timeout != PR_INTERVAL_NO_TIMEOUT) { PRInt32 ticksPerSecond = PR_TicksPerSecond(); tv.tv_sec = remaining / ticksPerSecond; tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond ); tvp = &tv; } ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp); if (ready == -1 && errno == EINTR) { if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry; else { elapsed = (PRIntervalTime) (PR_IntervalNow() - start); if (elapsed > timeout) ready = 0; /* timed out */ else { remaining = timeout - elapsed; goto retry; } } } /* ** Now to unravel the select sets back into the client's poll ** descriptor list. Is this possibly an area for pissing away ** a few cycles or what? */ if (ready > 0) { ready = 0; for (pd = pds, epd = pd + npds; pd < epd; pd++) { PRInt16 out_flags = 0; if ((NULL != pd->fd) && (0 != pd->in_flags)) { PRInt32 osfd; bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); PR_ASSERT(NULL != bottom); osfd = bottom->secret->md.osfd; if (FD_ISSET(osfd, &rd)) { if (pd->out_flags & _PR_POLL_READ_SYS_READ) out_flags |= PR_POLL_READ; if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) out_flags |= PR_POLL_WRITE; } if (FD_ISSET(osfd, &wt)) { if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) out_flags |= PR_POLL_READ; if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) out_flags |= PR_POLL_WRITE; } if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT; } pd->out_flags = out_flags; if (out_flags) ready++; } PR_ASSERT(ready > 0); } else if (ready < 0) { err = _MD_ERRNO(); if (err == EBADF) { /* Find the bad fds */ ready = 0; for (pd = pds, epd = pd + npds; pd < epd; pd++) { pd->out_flags = 0; if ((NULL != pd->fd) && (0 != pd->in_flags)) { bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1) { pd->out_flags = PR_POLL_NVAL; ready++; } } } PR_ASSERT(ready > 0); } else _PR_MD_MAP_SELECT_ERROR(err); } return ready; } /* NativeThreadSelect */
PRFloat64 StatsManagerUtil::getResponseTime(StatsProfileBucket& profile) { return ((PRFloat64) (PRInt64) (profile.ticksDispatch + profile.ticksFunction)) / ((PRInt64) profile.countRequests * PR_TicksPerSecond()); }
int main(int32_t argc, char *argv[]) { if (test_common_init(&argc, &argv) != 0) return -1; bool allTestsPassed = true; ScopedXPCOM xpcom; if (NS_FAILED(xpcom.rv)) return -1; { nsresult rv0; nsCOMPtr<nsICookieService> cookieService = do_GetService(kCookieServiceCID, &rv0); if (NS_FAILED(rv0)) return -1; nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(kPrefServiceCID, &rv0); if (NS_FAILED(rv0)) return -1; InitPrefs(prefBranch); bool rv[20]; nsCString cookie; /* The basic idea behind these tests is the following: * * we set() some cookie, then try to get() it in various ways. we have * several possible tests we perform on the cookie string returned from * get(): * * a) check whether the returned string is null (i.e. we got no cookies * back). this is used e.g. to ensure a given cookie was deleted * correctly, or to ensure a certain cookie wasn't returned to a given * host. * b) check whether the returned string exactly matches a given string. * this is used where we want to make sure our cookie service adheres to * some strict spec (e.g. ordering of multiple cookies), or where we * just know exactly what the returned string should be. * c) check whether the returned string contains/does not contain a given * string. this is used where we don't know/don't care about the * ordering of multiple cookies - we just want to make sure the cookie * string contains them all, in some order. * * the results of each individual testing operation from CheckResult() is * stored in an array of bools, which is then checked against the expected * outcomes (all successes), by PrintResult(). the overall result of all * tests to date is kept in |allTestsPassed|, for convenient display at the * end. * * Interpreting the output: * each setting/getting operation will print output saying exactly what * it's doing and the outcome, respectively. this information is only * useful for debugging purposes; the actual result of the tests is * printed at the end of each block of tests. this will either be "all * tests passed" or "tests X Y Z failed", where X, Y, Z are the indexes * of rv (i.e. zero-based). at the conclusion of all tests, the overall * passed/failed result is printed. * * NOTE: this testsuite is not yet comprehensive or complete, and is * somewhat contrived - still under development, and needs improving! */ // *** basic tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning basic tests...\n"); // test some basic variations of the domain & path SetACookie(cookieService, "http://www.basic.com", nullptr, "test=basic", nullptr); GetACookie(cookieService, "http://www.basic.com", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=basic"); GetACookie(cookieService, "http://www.basic.com/testPath/testfile.txt", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=basic"); GetACookie(cookieService, "http://www.basic.com./", nullptr, getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_BE_NULL); GetACookie(cookieService, "http://www.basic.com.", nullptr, getter_Copies(cookie)); rv[3] = CheckResult(cookie.get(), MUST_BE_NULL); GetACookie(cookieService, "http://www.basic.com./testPath/testfile.txt", nullptr, getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); GetACookie(cookieService, "http://www.basic2.com/", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.basic.com", nullptr, "test=basic; max-age=-1", nullptr); GetACookie(cookieService, "http://www.basic.com/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_BE_NULL); allTestsPassed = PrintResult(rv, 7) && allTestsPassed; // *** domain tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning domain tests...\n"); // test some variations of the domain & path, for different domains of // a domain cookie SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com", nullptr); GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); GetACookie(cookieService, "http://domain.com.", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_BE_NULL); GetACookie(cookieService, "http://www.domain.com", nullptr, getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com; max-age=-1", nullptr); GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.domain.com", nullptr); GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); GetACookie(cookieService, "http://www.domain.com", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); GetACookie(cookieService, "http://bah.domain.com", nullptr, getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.domain.com; max-age=-1", nullptr); GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie)); rv[8] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.foo.domain.com", nullptr); GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); rv[9] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=moose.com", nullptr); GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); rv[10] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com.", nullptr); GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); rv[11] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=..domain.com", nullptr); GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); rv[12] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=..domain.com.", nullptr); GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); rv[13] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=taco; path=\"/bogus\"", nullptr); GetACookie(cookieService, "http://path.net/path/file", nullptr, getter_Copies(cookie)); rv[14] = CheckResult(cookie.get(), MUST_EQUAL, "test=taco"); SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=taco; max-age=-1", nullptr); GetACookie(cookieService, "http://path.net/path/file", nullptr, getter_Copies(cookie)); rv[15] = CheckResult(cookie.get(), MUST_BE_NULL); allTestsPassed = PrintResult(rv, 16) && allTestsPassed; // *** path tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning path tests...\n"); // test some variations of the domain & path, for different paths of // a path cookie SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path", nullptr); GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); GetACookie(cookieService, "http://path.net/path/hithere.foo", nullptr, getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); GetACookie(cookieService, "http://path.net/path?hithere/foo", nullptr, getter_Copies(cookie)); rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); GetACookie(cookieService, "http://path.net/path2", nullptr, getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); GetACookie(cookieService, "http://path.net/path2/", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path; max-age=-1", nullptr); GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path/", nullptr); GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie)); rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path/; max-age=-1", nullptr); GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie)); rv[9] = CheckResult(cookie.get(), MUST_BE_NULL); // note that a site can set a cookie for a path it's not on. // this is an intentional deviation from spec (see comments in // nsCookieService::CheckPath()), so we test this functionality too SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/foo/", nullptr); GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie)); rv[10] = CheckResult(cookie.get(), MUST_BE_NULL); GetACookie(cookieService, "http://path.net/foo", nullptr, getter_Copies(cookie)); rv[11] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/foo/; max-age=-1", nullptr); GetACookie(cookieService, "http://path.net/foo/", nullptr, getter_Copies(cookie)); rv[12] = CheckResult(cookie.get(), MUST_BE_NULL); // bug 373228: make sure cookies with paths longer than 1024 bytes, // and cookies with paths or names containing tabs, are rejected. // the following cookie has a path > 1024 bytes explicitly specified in the cookie SetACookie(cookieService, "http://path.net/", nullptr, "test=path; path=/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr); GetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", nullptr, getter_Copies(cookie)); rv[13] = CheckResult(cookie.get(), MUST_BE_NULL); // the following cookie has a path > 1024 bytes implicitly specified by the uri path SetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr, "test=path", nullptr); GetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr, getter_Copies(cookie)); rv[14] = CheckResult(cookie.get(), MUST_BE_NULL); // the following cookie includes a tab in the path SetACookie(cookieService, "http://path.net/", nullptr, "test=path; path=/foo\tbar/", nullptr); GetACookie(cookieService, "http://path.net/foo\tbar/", nullptr, getter_Copies(cookie)); rv[15] = CheckResult(cookie.get(), MUST_BE_NULL); // the following cookie includes a tab in the name SetACookie(cookieService, "http://path.net/", nullptr, "test\ttabs=tab", nullptr); GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie)); rv[16] = CheckResult(cookie.get(), MUST_BE_NULL); // the following cookie includes a tab in the value - allowed SetACookie(cookieService, "http://path.net/", nullptr, "test=tab\ttest", nullptr); GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie)); rv[17] = CheckResult(cookie.get(), MUST_EQUAL, "test=tab\ttest"); SetACookie(cookieService, "http://path.net/", nullptr, "test=tab\ttest; max-age=-1", nullptr); GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie)); rv[18] = CheckResult(cookie.get(), MUST_BE_NULL); allTestsPassed = PrintResult(rv, 19) && allTestsPassed; // *** expiry & deletion tests // XXX add server time str parsing tests here sBuffer = PR_sprintf_append(sBuffer, "*** Beginning expiry & deletion tests...\n"); // test some variations of the expiry time, // and test deletion of previously set cookies SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=-1", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=0", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=bad", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[3] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=\"Thu, 10 Apr 1980 16:33:12 GMT", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=\"Thu, 10 Apr 1980 16:33:12 GMT\"", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=-20", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[9] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr); SetACookie(cookieService, "http://expireme.org/", nullptr, "newtest=expiry; max-age=60", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[10] = CheckResult(cookie.get(), MUST_CONTAIN, "test=expiry"); rv[11] = CheckResult(cookie.get(), MUST_CONTAIN, "newtest=expiry"); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=differentvalue; max-age=0", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[12] = CheckResult(cookie.get(), MUST_EQUAL, "newtest=expiry"); SetACookie(cookieService, "http://expireme.org/", nullptr, "newtest=evendifferentvalue; max-age=0", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[13] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://foo.expireme.org/", nullptr, "test=expiry; domain=.expireme.org; max-age=60", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[14] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"); SetACookie(cookieService, "http://bar.expireme.org/", nullptr, "test=differentvalue; domain=.expireme.org; max-age=0", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[15] = CheckResult(cookie.get(), MUST_BE_NULL); allTestsPassed = PrintResult(rv, 16) && allTestsPassed; // *** multiple cookie tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning multiple cookie tests...\n"); // test the setting of multiple cookies, and test the order of precedence // (a later cookie overwriting an earlier one, in the same header string) SetACookie(cookieService, "http://multiple.cookies/", nullptr, "test=multiple; domain=.multiple.cookies \n test=different \n test=same; domain=.multiple.cookies \n newtest=ciao \n newtest=foo; max-age=-6 \n newtest=reincarnated", nullptr); GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=multiple"); rv[1] = CheckResult(cookie.get(), MUST_CONTAIN, "test=different"); rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "test=same"); rv[3] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=ciao"); rv[4] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=foo"); rv[5] = CheckResult(cookie.get(), MUST_CONTAIN, "newtest=reincarnated"); SetACookie(cookieService, "http://multiple.cookies/", nullptr, "test=expiry; domain=.multiple.cookies; max-age=0", nullptr); GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=same"); SetACookie(cookieService, "http://multiple.cookies/", nullptr, "\n test=different; max-age=0 \n", nullptr); GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=different"); SetACookie(cookieService, "http://multiple.cookies/", nullptr, "newtest=dead; max-age=0", nullptr); GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie)); rv[8] = CheckResult(cookie.get(), MUST_BE_NULL); allTestsPassed = PrintResult(rv, 9) && allTestsPassed; // *** parser tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning parser tests...\n"); // test the cookie header parser, under various circumstances. SetACookie(cookieService, "http://parser.test/", nullptr, "test=parser; domain=.parser.test; ;; ;=; ,,, ===,abc,=; abracadabra! max-age=20;=;;", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=parser"); SetACookie(cookieService, "http://parser.test/", nullptr, "test=parser; domain=.parser.test; max-age=0", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://parser.test/", nullptr, "test=\"fubar! = foo;bar\\\";\" parser; domain=.parser.test; max-age=6\nfive; max-age=2.63,", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "test=\"fubar! = foo"); rv[3] = CheckResult(cookie.get(), MUST_CONTAIN, "five"); SetACookie(cookieService, "http://parser.test/", nullptr, "test=kill; domain=.parser.test; max-age=0 \n five; max-age=0", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); // test the handling of VALUE-only cookies (see bug 169091), // i.e. "six" should assume an empty NAME, which allows other VALUE-only // cookies to overwrite it SetACookie(cookieService, "http://parser.test/", nullptr, "six", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "six"); SetACookie(cookieService, "http://parser.test/", nullptr, "seven", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "seven"); SetACookie(cookieService, "http://parser.test/", nullptr, " =eight", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "eight"); SetACookie(cookieService, "http://parser.test/", nullptr, "test=six", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[9] = CheckResult(cookie.get(), MUST_CONTAIN, "test=six"); allTestsPassed = PrintResult(rv, 10) && allTestsPassed; // *** path ordering tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning path ordering tests...\n"); // test that cookies are returned in path order - longest to shortest. // if the header doesn't specify a path, it's taken from the host URI. SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test1=path; path=/one/two/three", nullptr); SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test2=path; path=/one \n test3=path; path=/one/two/three/four \n test4=path; path=/one/two \n test5=path; path=/one/two/", nullptr); SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/", nullptr, "test6=path", nullptr); SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/six/", nullptr, "test7=path; path=", nullptr); SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test8=path; path=/", nullptr); GetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/six/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test7=path; test6=path; test3=path; test1=path; test5=path; test4=path; test2=path; test8=path"); allTestsPassed = PrintResult(rv, 1) && allTestsPassed; // *** httponly tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning httponly tests...\n"); // Since this cookie is NOT set via http, setting it fails SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; httponly"); GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_BE_NULL); // Since this cookie is set via http, it can be retrieved SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr); GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly"); // ... but not by web content GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_BE_NULL); // Non-Http cookies should not replace HttpOnly cookies SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr); SetACookieNoHttp(cookieService, "http://httponly.test/", "test=not-httponly"); GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly"); // ... and, if an HttpOnly cookie already exists, should not be set at all GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); // Non-Http cookies should not delete HttpOnly cookies SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr); SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; max-age=-1"); GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly"); // ... but HttpOnly cookies should SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly; max-age=-1", nullptr); GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_BE_NULL); // Non-Httponly cookies can replace HttpOnly cookies when set over http SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr); SetACookie(cookieService, "http://httponly.test/", nullptr, "test=not-httponly", nullptr); GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=not-httponly"); // scripts should not be able to set httponly cookies by replacing an existing non-httponly cookie SetACookie(cookieService, "http://httponly.test/", nullptr, "test=not-httponly", nullptr); SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; httponly"); GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie)); rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=not-httponly"); allTestsPassed = PrintResult(rv, 9) && allTestsPassed; // *** nsICookieManager{2} interface tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning nsICookieManager{2} interface tests...\n"); nsCOMPtr<nsICookieManager> cookieMgr = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv0); if (NS_FAILED(rv0)) return -1; nsCOMPtr<nsICookieManager2> cookieMgr2 = do_QueryInterface(cookieMgr); if (!cookieMgr2) return -1; // first, ensure a clean slate rv[0] = NS_SUCCEEDED(cookieMgr->RemoveAll()); // add some cookies rv[1] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("cookiemgr.test"), // domain NS_LITERAL_CSTRING("/foo"), // path NS_LITERAL_CSTRING("test1"), // name NS_LITERAL_CSTRING("yes"), // value false, // is secure false, // is httponly true, // is session INT64_MAX)); // expiry time rv[2] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("cookiemgr.test"), // domain NS_LITERAL_CSTRING("/foo"), // path NS_LITERAL_CSTRING("test2"), // name NS_LITERAL_CSTRING("yes"), // value false, // is secure true, // is httponly true, // is session PR_Now() / PR_USEC_PER_SEC + 2)); // expiry time rv[3] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("new.domain"), // domain NS_LITERAL_CSTRING("/rabbit"), // path NS_LITERAL_CSTRING("test3"), // name NS_LITERAL_CSTRING("yes"), // value false, // is secure false, // is httponly true, // is session INT64_MAX)); // expiry time // confirm using enumerator nsCOMPtr<nsISimpleEnumerator> enumerator; rv[4] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator))); int32_t i = 0; bool more; nsCOMPtr<nsICookie2> expiredCookie, newDomainCookie; while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) { nsCOMPtr<nsISupports> cookie; if (NS_FAILED(enumerator->GetNext(getter_AddRefs(cookie)))) break; ++i; // keep tabs on the second and third cookies, so we can check them later nsCOMPtr<nsICookie2> cookie2(do_QueryInterface(cookie)); if (!cookie2) break; nsAutoCString name; cookie2->GetName(name); if (name == NS_LITERAL_CSTRING("test2")) expiredCookie = cookie2; else if (name == NS_LITERAL_CSTRING("test3")) newDomainCookie = cookie2; } rv[5] = i == 3; // check the httpOnly attribute of the second cookie is honored GetACookie(cookieService, "http://cookiemgr.test/foo/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_CONTAIN, "test2=yes"); GetACookieNoHttp(cookieService, "http://cookiemgr.test/foo/", getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test2=yes"); // check CountCookiesFromHost() uint32_t hostCookies = 0; rv[8] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) && hostCookies == 2; // check CookieExists() using the third cookie bool found; rv[9] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && found; // remove the cookie, block it, and ensure it can't be added again rv[10] = NS_SUCCEEDED(cookieMgr->Remove(NS_LITERAL_CSTRING("new.domain"), // domain NS_LITERAL_CSTRING("test3"), // name NS_LITERAL_CSTRING("/rabbit"), // path true)); // is blocked rv[11] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && !found; rv[12] = NS_SUCCEEDED(cookieMgr2->Add(NS_LITERAL_CSTRING("new.domain"), // domain NS_LITERAL_CSTRING("/rabbit"), // path NS_LITERAL_CSTRING("test3"), // name NS_LITERAL_CSTRING("yes"), // value false, // is secure false, // is httponly true, // is session INT64_MIN)); // expiry time rv[13] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && !found; // sleep four seconds, to make sure the second cookie has expired PR_Sleep(4 * PR_TicksPerSecond()); // check that both CountCookiesFromHost() and CookieExists() count the // expired cookie rv[14] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) && hostCookies == 2; rv[15] = NS_SUCCEEDED(cookieMgr2->CookieExists(expiredCookie, &found)) && found; // double-check RemoveAll() using the enumerator rv[16] = NS_SUCCEEDED(cookieMgr->RemoveAll()); rv[17] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator))) && NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && !more; allTestsPassed = PrintResult(rv, 18) && allTestsPassed; // *** eviction and creation ordering tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning eviction and creation ordering tests...\n"); // test that cookies are // a) returned by order of creation time (oldest first, newest last) // b) evicted by order of lastAccessed time, if the limit on cookies per host (50) is reached nsAutoCString name; nsAutoCString expected; for (int32_t i = 0; i < 60; ++i) { name = NS_LITERAL_CSTRING("test"); name.AppendInt(i); name += NS_LITERAL_CSTRING("=creation"); SetACookie(cookieService, "http://creation.ordering.tests/", nullptr, name.get(), nullptr); if (i >= 10) { expected += name; if (i < 59) expected += NS_LITERAL_CSTRING("; "); } } GetACookie(cookieService, "http://creation.ordering.tests/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_EQUAL, expected.get()); allTestsPassed = PrintResult(rv, 1) && allTestsPassed; // XXX the following are placeholders: add these tests please! // *** "noncompliant cookie" tests // *** IP address tests // *** speed tests sBuffer = PR_sprintf_append(sBuffer, "\n*** Result: %s!\n\n", allTestsPassed ? "all tests passed" : "TEST(S) FAILED"); } if (!allTestsPassed) { // print the entire log printf("%s", sBuffer); return 1; } PR_smprintf_free(sBuffer); sBuffer = nullptr; return 0; }
/* * Destroy a Repl_Objset. * Arguments: * o: the object set to be destroyed * maxwait: the maximum time to wait for all object refcnts to * go to zero. * panic_fn: a function to be called if, after waiting "maxwait" * seconds, not all object refcnts are zero. * The caller must ensure that no one else holds references to the * set or any objects it contains. */ void repl_objset_destroy(Repl_Objset **o, time_t maxwait, FNFree panic_fn) { Repl_Objset_object *co = NULL; time_t now, stop_time; int really_gone; int loopcount; void *cookie; PR_ASSERT(NULL != o); PR_ASSERT(NULL != *o); time(&now); stop_time = now + maxwait; /* * Loop over the objects until they all are actually gone, * or until maxwait seconds have passed. */ really_gone = 0; loopcount = 0; while (now < stop_time) { void *cookie; PR_Lock((*o)->lock); if ((co = llistGetFirst((*o)->objects, &cookie)) == NULL) { really_gone = 1; PR_Unlock((*o)->lock); break; } while (NULL != co) { /* Set the deleted flag so the object isn't returned by iterator */ co->flags |= REPL_OBJSET_OBJ_FLAG_DELETED; if (0 == co->refcnt) { /* Remove the object */ co = removeCurrentObjectAndGetNextNolock ((*o), co, cookie); } else co = llistGetNext((*o)->objects, &cookie); } PR_Unlock((*o)->lock); time(&now); if (loopcount > 0) { DS_Sleep(PR_TicksPerSecond()); } loopcount++; } if (!really_gone) { if (NULL != panic_fn) { /* * Call the "aargh, this thing won't go away" panic * function for each remaining object. */ PR_Lock((*o)->lock); co = llistGetFirst((*o)->objects, &cookie); while (NULL != co) { panic_fn(co->data); co = llistGetNext((*o)->objects, &cookie); } PR_Unlock((*o)->lock); } } else { /* Free the linked list */ llistDestroy(&(*o)->objects, (*o)->destructor); PR_DestroyLock((*o)->lock); slapi_ch_free((void **)o); } }
int main(int argc, char **argv) { setvbuf(stdout, NULL, _IOLBF, 0); #ifdef XP_UNIX unlimit(); #endif fprintf(stdout, "\n"); unsigned long limit = 0; // no thread limit by default char *addr = NULL; PRBool log = PR_FALSE; LogLevel logLevel = LOGINFO; PLOptState *options; PRBool secure = PR_FALSE; PRBool NSTests = PR_FALSE; // don't execute Netscape tests by default PtrList<char> protlist; // list of security protocols PtrList<char> configlist; // list of configurations RegexList regexlist; // list of Sun tests/regex to load RegexList regexcludelist; // list of Sun tests/regex to exclude char* suitename = "suite1"; PRInt32 concurrent = 0; // number of concurrent threads for each test. 0 means sequential, single-threaded PRInt32 delay = 0; PRInt32 split = 0; PRInt32 timeout = 0; // leave timeout unchanged by default char* cert=NULL; char* certpwd=NULL; char* cipherString = NULL; char* version = "ENTERPRISE"; PRInt32 release = 41; PRInt32 hsp = 0; // SSL handshake period PRBool performance = PR_FALSE; PRInt32 maxtm = 0; PRUint16 af = PR_AF_INET; PRInt32 displayperiod=0; PRBool loop = PR_FALSE; Logger::logInitialize(logLevel); options = PL_CreateOptState(argc, argv, "X:C:h:H:l:c:d:n:w46r:sx:p:o:t:a:e:k:Ng:v:R:QPE:T:L:"); long repeat = 1; while ( PL_GetNextOpt(options) == PL_OPT_OK) { switch(options->option) { case 'L': loop = PR_TRUE; if (options->value) displayperiod = (PRInt32) atoi(options->value); break; case 'E': if (options->value) protlist.insert(strdup(options->value)); break; case 'T': if (options->value) maxtm = (PRInt32) atoi(options->value); break; case 'H': if (options->value) hsp = (PRInt32) atoi(options->value); break; case 'v': if (options->value) version = uppercase(strdup(options->value)); break; case 'g': if (options->value) configlist.insert(strdup(options->value)); break; case 'x': if (options->value) regexlist.add(options->value); break; case 'X': if (options->value) regexcludelist.add(options->value); break; case 'w': log = PR_TRUE; break; case 'r': if (options->value) repeat = atol(options->value); break; case 'e': if (options->value) timeout = atol(options->value); break; case 'o': if (options->value) split = atol(options->value); break; case 't': if (options->value) delay = atol(options->value); break; case 'd': if (options->value) suitename = strdup(options->value); break; case 'a': if (options->value) arch = strdup(options->value); break; case 'N': NSTests = PR_TRUE; break; case 'h': if (options->value) addr = strdup(options->value); break; case 'p': if (options->value) concurrent = atol(options->value); else concurrent = 1; // 1 thread per test break; case 'P': performance = PR_TRUE; // meaure performance only break; case 'l': if (options->value) logLevel = (LogLevel)atoi(options->value); break; case 'R': if (options->value) release = (PRInt32) atoi(options->value); break; case 's': secure = PR_TRUE; break; case 'n': if (options->value) cert = strdup(options->value); break; case 'k': if (options->value) certpwd = strdup(options->value); break; case 'c': if (options->value) { cipherString = strdup(options->value); if (PR_TRUE != EnableCipher(cipherString)) { Logger::logError(LOGINFO, "Invalid cipher specified.\n"); }; } break; case 'C': if (options->value) limit = atol(options->value); else limit = 0; // no thread limit break; case 'Q': printCipherOptions(); break; case '6': af = PR_AF_INET6; break; case '4': af = PR_AF_INET; break; }; }; SecurityProtocols secprots; if (PR_TRUE == secure) { NSString str; str.append(suitename); str.append("/certs/client"); secure = InitSecurity((char*)str.data(), cert, certpwd); if (PR_TRUE != secure) Logger::logError(LOGINFO, "Unable to initialize security.\n"); if (protlist.entries()) { secprots = protlist; }; }; PL_DestroyOptState(options); Logger::logInitialize(logLevel); nstime_init(); if (!addr) { usage(argv[0]); return -1; }; HttpServer server(addr, af); server.setSSL(secure); if (PR_FALSE == NSTests) { if (alltests) alltests->clear(); // cancel all the Netscape tests if (!regexlist.length()) regexlist.add(".*"); }; if (!configlist.entries()) configlist.insert("COMMON"); // if no config is specified, select default COMMON configuration Engine::globaltimeout = PR_TicksPerSecond()*timeout; SunTestSuite suite(configlist, suitename, regexlist, regexcludelist, arch, version, release, log, PR_TicksPerSecond()*timeout, split, delay, hsp, secprots, maxtm); PRInt32 percent = suite.runTests(server, concurrent, repeat, limit, performance, loop, displayperiod); return percent; };
/* * FUNCTION: pkix_pl_OcspResponse_Create * DESCRIPTION: * * This function transmits the OcspRequest pointed to by "request" and obtains * an OcspResponse, which it stores at "pOcspResponse". If the HTTPClient * supports non-blocking I/O this function may store a non-NULL value at * "pNBIOContext" (the WOULDBLOCK condition). In that case the caller should * make a subsequent call with the same value in "pNBIOContext" and * "pOcspResponse" to resume the operation. Additional WOULDBLOCK returns may * occur; the caller should persist until a return occurs with NULL stored at * "pNBIOContext". * * If a SEC_HttpClientFcn "responder" is supplied, it is used as the client * to which the OCSP query is sent. If none is supplied, the default responder * is used. * * If an OcspResponse_VerifyCallback "verifyFcn" is supplied, it is used to * verify the Cert received from the responder as the signer. If none is * supplied, the default verification function is used. * * The contents of "request" are ignored on calls subsequent to a WOULDBLOCK * return, and the caller is permitted to supply NULL. * * PARAMETERS * "request" * Address of the OcspRequest for which a response is desired. * "responder" * Address, if non-NULL, of the SEC_HttpClientFcn to be sent the OCSP * query. * "verifyFcn" * Address, if non-NULL, of the OcspResponse_VerifyCallback function to be * used to verify the Cert of the OCSP responder. * "pNBIOContext" * Address at which platform-dependent information is stored for handling * of non-blocking I/O. Must be non-NULL. * "pOcspResponse" * The address where the created OcspResponse 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 an OcspResponse Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_pl_OcspResponse_Create( PKIX_PL_OcspRequest *request, void *responder, PKIX_PL_OcspResponse_VerifyCallback verifyFcn, void **pNBIOContext, PKIX_PL_OcspResponse **pResponse, void *plContext) { void *nbioContext = NULL; PKIX_PL_OcspResponse *ocspResponse = NULL; const SEC_HttpClientFcn *httpClient = NULL; const SEC_HttpClientFcnV1 *hcv1 = NULL; SECStatus rv = SECFailure; char *location = NULL; char *hostname = NULL; char *path = NULL; PRUint16 port = 0; SEC_HTTP_SERVER_SESSION serverSession = NULL; SEC_HTTP_REQUEST_SESSION requestSession = NULL; SECItem *encodedRequest = NULL; PRUint16 responseCode = 0; char *responseData = NULL; PRUint32 responseDataLen = 0; PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Create"); PKIX_NULLCHECK_TWO(pNBIOContext, pResponse); nbioContext = *pNBIOContext; *pNBIOContext = NULL; if (nbioContext != NULL) { ocspResponse = *pResponse; PKIX_NULLCHECK_ONE(ocspResponse); httpClient = ocspResponse->httpClient; serverSession = ocspResponse->serverSession; requestSession = ocspResponse->requestSession; PKIX_NULLCHECK_THREE(httpClient, serverSession, requestSession); } else { PKIX_NULLCHECK_ONE(request); PKIX_CHECK(pkix_pl_OcspRequest_GetEncoded (request, &encodedRequest, plContext), PKIX_OCSPREQUESTGETENCODEDFAILED); /* prepare initial message to HTTPClient */ /* Is there a default responder and is it enabled? */ if (!responder) { PKIX_PL_NSSCALLRV (OCSPRESPONSE, responder, (void *)SEC_GetRegisteredHttpClient, ()); } httpClient = (const SEC_HttpClientFcn *)responder; if (httpClient && (httpClient->version == 1)) { hcv1 = &(httpClient->fcnTable.ftable1); PKIX_CHECK(pkix_pl_OcspRequest_GetLocation (request, &location, plContext), PKIX_OCSPREQUESTGETLOCATIONFAILED); /* parse location -> hostname, port, path */ PKIX_PL_NSSCALLRV(OCSPRESPONSE, rv, CERT_ParseURL, (location, &hostname, &port, &path)); if ((hostname == NULL) || (path == NULL)) { PKIX_ERROR(PKIX_URLPARSINGFAILED); } PKIX_PL_NSSCALLRV (OCSPRESPONSE, rv, hcv1->createSessionFcn, (hostname, port, &serverSession)); if (rv != SECSuccess) { PKIX_ERROR(PKIX_OCSPSERVERERROR); } PKIX_PL_NSSCALLRV (OCSPRESPONSE, rv, hcv1->createFcn, (serverSession, "http", path, "POST", PR_TicksPerSecond() * 60, &requestSession)); if (rv != SECSuccess) { PKIX_ERROR(PKIX_OCSPSERVERERROR); } PKIX_PL_NSSCALLRV (OCSPRESPONSE, rv, hcv1->setPostDataFcn, (requestSession, (char *)encodedRequest->data, encodedRequest->len, "application/ocsp-request")); if (rv != SECSuccess) { PKIX_ERROR(PKIX_OCSPSERVERERROR); } /* create a PKIX_PL_OcspResponse object */ PKIX_CHECK(PKIX_PL_Object_Alloc (PKIX_OCSPRESPONSE_TYPE, sizeof (PKIX_PL_OcspResponse), (PKIX_PL_Object **)&ocspResponse, plContext), PKIX_COULDNOTCREATEOBJECT); PKIX_INCREF(request); ocspResponse->request = request; ocspResponse->httpClient = httpClient; ocspResponse->serverSession = serverSession; ocspResponse->requestSession = requestSession; ocspResponse->verifyFcn = verifyFcn; ocspResponse->handle = CERT_GetDefaultCertDB(); ocspResponse->encodedResponse = NULL; ocspResponse->arena = NULL; ocspResponse->producedAt = 0; ocspResponse->producedAtDate = NULL; ocspResponse->pkixSignerCert = NULL; ocspResponse->nssOCSPResponse = NULL; ocspResponse->signerCert = NULL; } }