REQUEST_NOTIFICATION_STATUS CNodeHttpModule::OnExecuteRequestHandler( IN IHttpContext* pHttpContext, IN IHttpEventProvider* pProvider) { HRESULT hr; CNodeHttpStoredContext* ctx = NULL; CheckError(this->applicationManager->Initialize(pHttpContext)); this->applicationManager->GetEventProvider()->Log(L"iisnode received a new http request", WINEVENT_LEVEL_INFO); CheckError(this->applicationManager->Dispatch(pHttpContext, pProvider, &ctx)); this->applicationManager->GetEventProvider()->Log(L"iisnode dispatched new http request", WINEVENT_LEVEL_INFO, ctx->GetActivityId()); ASYNC_CONTEXT* async = ctx->GetAsyncContext(); async->RunSynchronousContinuations(); REQUEST_NOTIFICATION_STATUS result; if (0 == ctx->DecreasePendingAsyncOperationCount()) // decreases ref count set to 1 in the ctor of CNodeHttpStoredContext { result = ctx->GetRequestNotificationStatus(); } else { result = RQ_NOTIFICATION_PENDING; } switch (result) { default: this->applicationManager->GetEventProvider()->Log( L"iisnode leaves CNodeHttpModule::OnExecuteRequestHandler", WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId()); break; case RQ_NOTIFICATION_CONTINUE: this->applicationManager->GetEventProvider()->Log( L"iisnode leaves CNodeHttpModule::OnExecuteRequestHandler with RQ_NOTIFICATION_CONTINUE", WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId()); break; case RQ_NOTIFICATION_FINISH_REQUEST: this->applicationManager->GetEventProvider()->Log( L"iisnode leaves CNodeHttpModule::OnExecuteRequestHandler with RQ_NOTIFICATION_FINISH_REQUEST", WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId()); break; case RQ_NOTIFICATION_PENDING: this->applicationManager->GetEventProvider()->Log( L"iisnode leaves CNodeHttpModule::OnExecuteRequestHandler with RQ_NOTIFICATION_PENDING", WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId()); break; }; return result; Error: CNodeEventProvider* log = this->applicationManager->GetEventProvider(); if (log) { if (ctx) { log->Log(L"iisnode failed to process a new http request", WINEVENT_LEVEL_INFO, ctx->GetActivityId()); } else { log->Log(L"iisnode failed to process a new http request", WINEVENT_LEVEL_INFO); } } if (ERROR_NOT_ENOUGH_QUOTA == hr) { CProtocolBridge::SendEmptyResponse(pHttpContext, 503, CNodeConstants::IISNODE_ERROR_NOT_ENOUGH_QUOTA, _T("Service Unavailable"), hr); } else if (ERROR_FILE_NOT_FOUND == hr) { CProtocolBridge::SendEmptyResponse(pHttpContext, 404, 0, _T("Not Found"), hr); } else if (ERROR_NOT_SUPPORTED == hr) { if (log) { log->Log(L"iisnode rejected websocket connection request", WINEVENT_LEVEL_INFO); } CProtocolBridge::SendEmptyResponse(pHttpContext, 501, 0, _T("Not Implemented"), hr); } else if (!CProtocolBridge::SendIisnodeError(pHttpContext, hr)) { CProtocolBridge::SendEmptyResponse( pHttpContext, 500, CNodeConstants::IISNODE_ERROR_ON_EXECUTE_REQ_HANDLER, _T("Internal Server Error"), hr ); } return RQ_NOTIFICATION_FINISH_REQUEST; }
REQUEST_NOTIFICATION_STATUS CNodeHttpModule::OnExecuteRequestHandler( IN IHttpContext* pHttpContext, IN IHttpEventProvider* pProvider) { HRESULT hr; CNodeHttpStoredContext* ctx = NULL; CheckError(this->applicationManager->Initialize(pHttpContext)); this->applicationManager->GetEventProvider()->Log(L"iisnode received a new http request", WINEVENT_LEVEL_INFO); // reject websocket connections since iisnode does not support them // http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17#page-17 PCSTR upgrade = pHttpContext->GetRequest()->GetHeader(HttpHeaderUpgrade, NULL); ErrorIf(upgrade && 0 == strcmp("websocket", upgrade), ERROR_NOT_SUPPORTED); CheckError(this->applicationManager->Dispatch(pHttpContext, pProvider, &ctx)); if (0 == ctx->DecreasePendingAsyncOperationCount()) // decreases ref count set to 1 in the ctor of CNodeHttpStoredContext { return ctx->GetRequestNotificationStatus(); } else { return RQ_NOTIFICATION_PENDING; } Error: CNodeEventProvider* log = this->applicationManager->GetEventProvider(); if (log) { log->Log(L"iisnode failed to process a new http request", WINEVENT_LEVEL_INFO); } if (ERROR_NOT_ENOUGH_QUOTA == hr) { CProtocolBridge::SendEmptyResponse(pHttpContext, 503, _T("Service Unavailable"), hr); } else if (ERROR_FILE_NOT_FOUND == hr) { CProtocolBridge::SendEmptyResponse(pHttpContext, 404, _T("Not Found"), hr); } else if (ERROR_NOT_SUPPORTED == hr) { if (log) { log->Log(L"iisnode rejected websocket connection request", WINEVENT_LEVEL_INFO); } CProtocolBridge::SendEmptyResponse(pHttpContext, 501, _T("Not Implemented"), hr); } else if (IISNODE_ERROR_UNRECOGNIZED_DEBUG_COMMAND == hr) { CProtocolBridge::SendSyncResponse( pHttpContext, 200, "OK", hr, TRUE, "Unrecognized debugging command. Supported commands are ?debug (default), ?brk, and ?kill."); } else if (IISNODE_ERROR_UNABLE_TO_FIND_DEBUGGING_PORT == hr) { CProtocolBridge::SendSyncResponse( pHttpContext, 200, "OK", hr, TRUE, "The debugger was unable to acquire a TCP port to establish communication with the debugee. " "This may be due to lack of free TCP ports in the range specified in the system.webServer/iisnode/@debuggerPortRange configuration " "section, or due to lack of permissions to create TCP listeners by the identity of the IIS worker process."); } else if (IISNODE_ERROR_UNABLE_TO_CONNECT_TO_DEBUGEE == hr) { CProtocolBridge::SendSyncResponse( pHttpContext, 200, "OK", hr, TRUE, "The debugger was unable to connect to the the debugee. " "This may be due to the debugee process terminating during startup (e.g. due to an unhandled exception) or " "failing to establish a TCP listener on the debugging port. "); } else { CProtocolBridge::SendEmptyResponse(pHttpContext, 500, _T("Internal Server Error"), hr); } return RQ_NOTIFICATION_FINISH_REQUEST; }