Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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);
}