DWORD CHttpServer::HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pECB) { DWORD dwRet = HSE_STATUS_SUCCESS; BOOL bDefault = FALSE; LPTSTR pszPostBuffer = NULL; LPTSTR pszQuery; LPTSTR pszCommand = NULL; int nMethodRet; LPTSTR pstrLastChar; DWORD cbStream = 0; BYTE* pbStream = NULL; CHttpServerContext ctxtCall(pECB); pECB->dwHttpStatusCode = 0; ISAPIASSERT(NULL != pServer); if (pServer == NULL) { dwRet = HSE_STATUS_ERROR; goto CleanUp; } // get the query if (_tcsicmp(pECB->lpszMethod, szGet) == 0) { pszQuery = pECB->lpszQueryString; } else if (_tcsicmp(pECB->lpszMethod, szPost) == 0) { pszCommand = pECB->lpszQueryString; pszPostBuffer = new TCHAR[pECB->cbAvailable + 1]; pszQuery = GetQuery(&ctxtCall, pszPostBuffer, pECB->cbAvailable); } else { ISAPITRACE1("Error: Unrecognized method: %s\n", pECB->lpszMethod); dwRet = HSE_STATUS_ERROR; goto CleanUp; } // trim junk that some browsers put at the very end pstrLastChar = pszQuery + _tcslen(pszQuery) -1; while ((*pstrLastChar == ' ' || *pstrLastChar == '\n' || *pstrLastChar == '\r') && pstrLastChar > pszQuery) { *pstrLastChar-- = '\0'; } // do something about it if (!pServer->InitInstance(&ctxtCall)) dwRet = HSE_STATUS_ERROR; else { pECB->dwHttpStatusCode = HTTP_STATUS_OK; try { nMethodRet = pServer->CallFunction(&ctxtCall, pszQuery, pszCommand); } catch (...) { ISAPITRACE1("Error: command %s caused an unhandled exception!\n", pszQuery); nMethodRet = callNoStackSpace; } // was an error caused by trying to dispatch? if (nMethodRet != callOK && pECB->dwHttpStatusCode == HTTP_STATUS_OK) { dwRet = HSE_STATUS_ERROR; switch (nMethodRet) { case callNoStream: pECB->dwHttpStatusCode = HTTP_STATUS_NO_CONTENT; break; case callParamRequired: case callBadParamCount: case callBadParam: pECB->dwHttpStatusCode = HTTP_STATUS_BAD_REQUEST; break; case callBadCommand: pECB->dwHttpStatusCode = HTTP_STATUS_NOT_IMPLEMENTED; break; case callNoStackSpace: default: pECB->dwHttpStatusCode = HTTP_STATUS_SERVER_ERROR; break; } } // if there was no error or the user said they handled // the error, prepare to spit out the generated HTML if (nMethodRet == callOK || OnParseError(&ctxtCall, nMethodRet) == TRUE) { cbStream = ctxtCall.m_pStream->GetStreamSize(); pbStream = ctxtCall.m_pStream->Detach(); } } CleanUp: // if there was an error, return an appropriate status TCHAR szResponse[64]; BuildStatusCode(szResponse, pECB->dwHttpStatusCode); DWORD dwSize = cbStream - ctxtCall.m_dwEndOfHeaders; BYTE* pbContent = NULL; BYTE cSaved; if (pbStream != NULL) { cSaved = pbStream[ctxtCall.m_dwEndOfHeaders]; pbStream[ctxtCall.m_dwEndOfHeaders] = '\0'; pbContent = &pbStream[ctxtCall.m_dwEndOfHeaders]; } if (!ctxtCall.ServerSupportFunction( HSE_REQ_SEND_RESPONSE_HEADER, szResponse, 0, (LPDWORD) pbStream)) { pECB->dwHttpStatusCode = HTTP_STATUS_SERVER_ERROR; dwRet = HSE_STATUS_ERROR; #ifdef _DEBUG DWORD dwCause = ::GetLastError(); ISAPITRACE1("Error: Unable to write headers: %8.8X!\n", dwCause); #endif } else { if (pbContent != NULL) { // write a newline to separate content from headers *pbContent = cSaved; DWORD dwNewLineSize = 2; if (!ctxtCall.WriteClient(_T("\r\n"), &dwNewLineSize, 0) || !ctxtCall.WriteClient(pbContent, &dwSize, 0)) { dwRet = HSE_STATUS_ERROR; pECB->dwHttpStatusCode = HTTP_STATUS_SERVER_ERROR; ISAPITRACE("Error: Unable to write content body!\n"); } } else ISAPITRACE("Error: No body content!\n"); } if (pbStream != NULL) ctxtCall.m_pStream->Free(pbStream); if (dwRet == HSE_STATUS_SUCCESS) pECB->dwHttpStatusCode = HTTP_STATUS_OK; if (pszPostBuffer != NULL) delete [] pszPostBuffer; return dwRet; }
void IndexLoader::OnObject(json::JsonObject *obj) { // Array order is: // 1. pack id // 2. pack hash // 3. title // 4. min player count // 5. max player count // 6. mission count int cExpected = 6; // Must be array of strings. bool error = false; if (obj->type() != json::JSONTYPE_ARRAY) { error = true; } const json::JsonArray *a = (const json::JsonArray *)obj; if (!error) { if (a->GetCount() != cExpected) { error = true; } } if (!error) { for (int i = 0; i < a->GetCount(); i++) { if (a->GetObject(i)->type() != json::JSONTYPE_STRING) { error = true; } } } IndexEntry entry; const json::JsonString *s; // id if (!error) { s = (const json::JsonString *)a->GetObject(0); if (!base::Format::ToDword(s->GetString(), 10, &entry.packid.id)) { error = true; } } // hash if (!error) { s = (const json::JsonString *)a->GetObject(1); if (s->GetLength() != 32) { error = true; } if (!base::Format::FromHex(s->GetString(), entry.packid.hash, sizeof(entry.packid.hash))) { error = true; } } // title if (!error) { s = (const json::JsonString *)a->GetObject(2); entry.title = s->GetString(); } // min players if (!error) { s = (const json::JsonString *)a->GetObject(3); if (!base::Format::ToInteger(s->GetString(), 10, &entry.cPlayersMin)) { error = true; } } // max players if (!error) { s = (const json::JsonString *)a->GetObject(4); if (!base::Format::ToInteger(s->GetString(), 10, &entry.cPlayersMax)) { error = true; } } // mission count if (!error) { s = (const json::JsonString *)a->GetObject(5); if (!base::Format::ToInteger(s->GetString(), 10, &entry.cMissions)) { error = true; } } delete obj; if (error) { OnParseError(); return; } entry.inIndex = true; index_.push_back(entry); }