REQUEST_NOTIFICATION_STATUS CNodeHttpModule::OnAsyncCompletion( IHttpContext* pHttpContext, DWORD dwNotification, BOOL fPostNotification, IHttpEventProvider* pProvider, IHttpCompletionInfo* pCompletionInfo) { if (NULL != pCompletionInfo && NULL != pHttpContext) { CNodeHttpStoredContext* ctx = (CNodeHttpStoredContext*)pHttpContext->GetModuleContextContainer()->GetModuleContext(this->applicationManager->GetModuleId()); ctx->IncreasePendingAsyncOperationCount(); WCHAR message[256]; wsprintfW(message, L"iisnode enters CNodeHttpModule::OnAsyncCompletion callback with request notification status of %d", ctx->GetRequestNotificationStatus()); this->applicationManager->GetEventProvider()->Log(message, WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId()); ASYNC_CONTEXT* async = ctx->GetAsyncContext(); if (NULL != async->completionProcessor) { async->completionProcessor(pCompletionInfo->GetCompletionStatus(), pCompletionInfo->GetCompletionBytes(), ctx->GetOverlapped()); } wsprintfW(message, L"iisnode leaves CNodeHttpModule::OnAsyncCompletion callback with request notification status of %d", ctx->GetRequestNotificationStatus()); this->applicationManager->GetEventProvider()->Log(message, WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId()); if (0 == ctx->DecreasePendingAsyncOperationCount()) // decreases ref count increased on entering OnAsyncCompletion { return ctx->GetRequestNotificationStatus(); } else { return RQ_NOTIFICATION_PENDING; } } return RQ_NOTIFICATION_CONTINUE; }
REQUEST_NOTIFICATION_STATUS CNodeHttpModule::OnAsyncCompletion( IHttpContext* pHttpContext, DWORD dwNotification, BOOL fPostNotification, IHttpEventProvider* pProvider, IHttpCompletionInfo* pCompletionInfo) { if (NULL != pCompletionInfo && NULL != pHttpContext) { CNodeHttpStoredContext* ctx = (CNodeHttpStoredContext*)pHttpContext->GetModuleContextContainer()->GetModuleContext(this->applicationManager->GetModuleId()); if (ctx->GetIsUpgrade()) { IHttpCompletionInfo2* pCompletionInfo2 = (IHttpCompletionInfo2*)pCompletionInfo; if (1 == pCompletionInfo2->GetCompletedOperation()) { // This is completion of the read request for incoming bytes of an opaque byte stream after 101 Switching protocol response was sent ctx = ctx->GetUpgradeContext(); } } ctx->IncreasePendingAsyncOperationCount(); this->applicationManager->GetEventProvider()->Log( L"iisnode enters CNodeHttpModule::OnAsyncCompletion callback", WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId()); ASYNC_CONTEXT* async = ctx->GetAsyncContext(); if (NULL != async->completionProcessor) { DWORD bytesCompleted = pCompletionInfo->GetCompletionBytes(); if (async->completionProcessor == CProtocolBridge::SendResponseBodyCompleted) { bytesCompleted = async->bytesCompleteted; async->bytesCompleteted = 0; } async->completionProcessor(pCompletionInfo->GetCompletionStatus(), bytesCompleted, ctx->GetOverlapped()); async->RunSynchronousContinuations(); } long value = ctx->DecreasePendingAsyncOperationCount(); REQUEST_NOTIFICATION_STATUS result = ctx->GetRequestNotificationStatus(); if(ctx->GetIsUpgrade() && value == 0) { // // when the pending async count reaches 0, // need to return RQ_NOTIFICATION_CONTINUE // to indicate websocket connection close. // result = RQ_NOTIFICATION_CONTINUE; } switch (result) { default: this->applicationManager->GetEventProvider()->Log( L"iisnode leaves CNodeHttpModule::OnAsyncCompletion", WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId()); break; case RQ_NOTIFICATION_CONTINUE: this->applicationManager->GetEventProvider()->Log( L"iisnode leaves CNodeHttpModule::OnAsyncCompletion with RQ_NOTIFICATION_CONTINUE", WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId()); break; case RQ_NOTIFICATION_FINISH_REQUEST: this->applicationManager->GetEventProvider()->Log( L"iisnode leaves CNodeHttpModule::OnAsyncCompletion with RQ_NOTIFICATION_FINISH_REQUEST", WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId()); break; case RQ_NOTIFICATION_PENDING: this->applicationManager->GetEventProvider()->Log( L"iisnode leaves CNodeHttpModule::OnAsyncCompletion with RQ_NOTIFICATION_PENDING", WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId()); break; }; return result; } return RQ_NOTIFICATION_CONTINUE; }