void vmsWinSockHttpTrafficCollector::OnDataSent(SOCKET s, const char *pData, int nLen) { LOGFN ("vmsWinSockHttpTrafficCollector::OnDataSent"); EnterCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector); int nIndex = m_pHttpTraffic->FindDialogIndexBySocket (s); vmsHttpTrafficCollector::HttpDialogPtr spDlg; if (nIndex != -1) { spDlg = m_pHttpTraffic->m_vDialogsInProgress [nIndex]; if (spDlg->enState >= vmsHttpTrafficCollector::HttpDialog::RECEIVING_RESPONSE_HEADERS) { m_pHttpTraffic->CloseDialog (spDlg); spDlg = NULL; nIndex = -1; } } LeaveCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector); if (nIndex == -1) { if (nLen < 5) { LOGsnl (" too small size"); return; } if (strnicmp (pData, "GET ", 4) && strnicmp (pData, "POST ", 5)) { LOGsnl (" not a GET or POST request"); char *p = new char [nLen + 1]; memcpy (p, pData, nLen); p [nLen] = 0; LOG (" (contains: %s)", p); delete [] p; return; } if (strstrn (pData, "HTTP/1.", nLen) == NULL) { LOGsnl (" HTTP/1. not found"); return; } spDlg = m_pHttpTraffic->CreateHttpDialogStore (); LOGsnl (" new dialog store is created."); #ifdef _DEBUG spDlg->enProvider = vmsHttpTrafficCollector::HttpDialog::Provider::PROV_WINSOCK; #endif spDlg->s = s; spDlg->enState = vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_HEADERS; EnterCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector); m_pHttpTraffic->m_vDialogsInProgress.push_back (spDlg); LeaveCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector); } switch (spDlg->enState) { case vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_HEADERS: { LPCSTR pszHdrEnd = strstrn (pData, "\r\n\r\n", nLen); if (pszHdrEnd == NULL) spDlg->strRequestHeaders.append (pData, nLen); else spDlg->strRequestHeaders.append (pData, pszHdrEnd-pData+4); if (pszHdrEnd != NULL) { m_pHttpTraffic->onHttpRequestHdrsAvailable (spDlg); m_pHttpTraffic->ExtractRequestUrlFromSocket (spDlg); pszHdrEnd += 4; spDlg->enState = vmsHttpTrafficCollector::HttpDialog::REQUEST_HEADERS_SENT; if (pszHdrEnd-pData < nLen) { spDlg->enState = vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_BODY; int l = nLen-(pszHdrEnd-pData); if (l <= vmsHttpTrafficCollector::RequestBodyMaxSize) { spDlg->vbRequestBody.resize (l); if (l) CopyMemory (&spDlg->vbRequestBody[0], pszHdrEnd, l); } else { m_pHttpTraffic->DeleteDialogFromListByID (spDlg->nID); return; } } } break; } case vmsHttpTrafficCollector::HttpDialog::REQUEST_HEADERS_SENT: spDlg->enState = vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_BODY; case vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_BODY: { int l = spDlg->vbRequestBody.size (); if (l + nLen <= vmsHttpTrafficCollector::RequestBodyMaxSize) { spDlg->vbRequestBody.resize (l + nLen); CopyMemory (&spDlg->vbRequestBody[l], pData, nLen); } else { m_pHttpTraffic->DeleteDialogFromListByID (spDlg->nID); return; } break; } default: assert (false); return; } }
void vmsHttpFlvTrafficAnalyzer::ExtractTitleFromXml(const vmsHttpTrafficCollector::HttpDialog *pDlg, wstring &wstrTitle, const vmsHttpTrafficCollector::HttpDialog* pFlvDlg) { extern LPCSTR strstrni (LPCSTR pszSrc, LPCSTR pszSrch, int lenSrc); extern LPCSTR strstrn (LPCSTR pszSrc, LPCSTR pszSrch, int lenSrc); wstrTitle = L""; assert (pDlg != NULL); if (!pDlg) return; assert (pDlg->enCT == vmsHttpTrafficCollector::HttpDialog::XML); if (pDlg->vbResponseBody.empty ()) return; LPCSTR pszXml = (LPCSTR)&pDlg->vbResponseBody [0]; int iXmlLen = pDlg->vbResponseBody.size (); LPCSTR pszXml2 = strstrni (pszXml, "encoding=\"", iXmlLen); if (!pszXml2) return; pszXml2 += 10; iXmlLen -= pszXml2 - pszXml; pszXml = pszXml2; if (iXmlLen < 5) return; if (strnicmp (pszXml, "utf-8", 5)) return; USES_CONVERSION; tstring tstrRequestUrl = A2CT (pFlvDlg->strRequestUrl.c_str ()); string strUrl = vmsXmlHelper::toUtf8noEncode (tstrRequestUrl); pszXml2 = strstrn (pszXml, strUrl.c_str (), iXmlLen); if (!pszXml2) { strUrl = vmsXmlHelper::toUtf8 (tstrRequestUrl); pszXml2 = strstrn (pszXml, strUrl.c_str (), iXmlLen); if (!pszXml2) { strUrl = pFlvDlg->strRequestUrl; pszXml2 = strstrn (pszXml, strUrl.c_str (), iXmlLen); } } LPCSTR pszVideoSectionTag = pszXml; if (pszXml2) { bool bAsAttr = pszXml2 [-1] != '>'; if (bAsAttr) { while (pszXml2 > pszXml && *pszXml2 != '"') pszXml2--; pszXml2--; if (pszXml2 > pszXml) { bool bInQ = false; while (pszXml2 > pszXml) { if (*pszXml2 == '"') bInQ = !bInQ; else if (*pszXml2 == '<' && bInQ == false) break; pszXml2--; } if (pszXml2 > pszXml) pszVideoSectionTag = pszXml2; } } else { while (pszXml2 > pszXml && *pszXml2 != '<') pszXml2--; pszXml2--; if (pszXml2 > pszXml) { bool bInT = false; while (pszXml2 > pszXml) { if (*pszXml2 == '<') { if (bInT) { bInT = false; } else { if (pszXml2 [1] == '/') { bInT = true; } else { break; } } } pszXml2--; } if (pszXml2 > pszXml) pszVideoSectionTag = pszXml2; } } } int iXmlLen2 = iXmlLen - (pszVideoSectionTag - pszXml); LPCSTR apszTags [] = {"title=\"", "<title>", "name=\"", "<name>"}; int iTag; LPCSTR pszTitle = NULL; do { for (iTag = 0; iTag < sizeof (apszTags)/sizeof (LPCSTR) && pszTitle == NULL; iTag++) pszTitle = strstrni (pszVideoSectionTag, apszTags [iTag], iXmlLen2); if (!pszTitle) { if (pszVideoSectionTag != pszXml) { pszVideoSectionTag = pszXml; iXmlLen2 = iXmlLen; } else { return; } } } while (pszTitle == NULL); pszTitle += strlen (apszTags [iTag]); LPCSTR pszTitleE = pszTitle; int iXmlLen3 = iXmlLen - (pszTitle - pszXml); char chEnd = pszTitle [-1] == '>' ? '<' : '"'; while (*pszTitleE != chEnd && iXmlLen3) { pszTitleE++; iXmlLen3--; } if (!iXmlLen3) return; string strTitle; strTitle.assign (pszTitle, pszTitleE-pszTitle); int n = MultiByteToWideChar (CP_UTF8, 0, strTitle.c_str (), -1, NULL, 0); assert (n != 0); LPWSTR pwsz = new WCHAR [n+1]; *pwsz = 0; MultiByteToWideChar (CP_UTF8, 0, strTitle.c_str (), -1, pwsz, n); wstrTitle = pwsz; delete [] pwsz; }
void vmsWinSockHttpTrafficCollector::OnDataRcvd(SOCKET s, const char *pData, int nLen) { LOGFN ("vmsWinSockHttpTrafficCollector::OnDataRcvd"); EnterCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector); int nIndex = m_pHttpTraffic->FindDialogIndexBySocket (s); if (nIndex == -1) { LOGsnl (" no dialog found for the specified socket"); LeaveCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector); return; } vmsHttpTrafficCollector::HttpDialogPtr spDlg = m_pHttpTraffic->m_vDialogsInProgress [nIndex]; LeaveCriticalSection (&m_pHttpTraffic->m_csModifyDialogsVector); assert (spDlg != NULL); if (!nLen) { if (spDlg->enState < vmsHttpTrafficCollector::HttpDialog::RESPONSE_HEADERS_RCVD) return; if (spDlg->nContentLength != _UI64_MAX) return; m_pHttpTraffic->MoveDialogToCompleted (spDlg); return; } switch (spDlg->enState) { case vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_HEADERS: LOGsnl (" invalid dialog state"); assert (false); return; case vmsHttpTrafficCollector::HttpDialog::REQUEST_HEADERS_SENT: case vmsHttpTrafficCollector::HttpDialog::SENDING_REQUEST_BODY: spDlg->enState = vmsHttpTrafficCollector::HttpDialog::RECEIVING_RESPONSE_HEADERS; case vmsHttpTrafficCollector::HttpDialog::RECEIVING_RESPONSE_HEADERS: { assert (spDlg->strResponseHeaders.empty () == false || strncmp (pData, "HTTP/", 5) == 0); LPCSTR pszHdrEnd = strstrn (pData, "\r\n\r\n", nLen); if (pszHdrEnd == NULL) spDlg->strResponseHeaders.append (pData, nLen); else spDlg->strResponseHeaders.append (pData, pszHdrEnd-pData+4); if (pszHdrEnd != NULL) { pszHdrEnd += 4; spDlg->enState = vmsHttpTrafficCollector::HttpDialog::RESPONSE_HEADERS_RCVD; m_pHttpTraffic->onHttpResponseHdrsAvailable (spDlg); if (!m_pHttpTraffic->isNeedBody (spDlg)) { m_pHttpTraffic->MoveDialogToCompleted (spDlg); } else if (pszHdrEnd-pData < nLen) { spDlg->enState = vmsHttpTrafficCollector::HttpDialog::RECEIVING_RESPONSE_BODY; int l = nLen-(pszHdrEnd-pData); spDlg->vbResponseBody.resize (l); if (l) CopyMemory (&spDlg->vbResponseBody[0], pszHdrEnd, l); } } break; } case vmsHttpTrafficCollector::HttpDialog::RESPONSE_HEADERS_RCVD: assert (spDlg->bSaveResponseBody || (spDlg->dwFlags & vmsHttpTrafficCollector::HttpDialog::CHECK_REAL_CONTENT_TYPE) != 0); spDlg->enState = vmsHttpTrafficCollector::HttpDialog::RECEIVING_RESPONSE_BODY; case vmsHttpTrafficCollector::HttpDialog::RECEIVING_RESPONSE_BODY: assert (spDlg->bSaveResponseBody || (spDlg->dwFlags & vmsHttpTrafficCollector::HttpDialog::CHECK_REAL_CONTENT_TYPE) != 0); int l; l = spDlg->vbResponseBody.size (); spDlg->vbResponseBody.resize (l + nLen); CopyMemory (&spDlg->vbResponseBody [l], pData, nLen); break; case vmsHttpTrafficCollector::HttpDialog::DONE: break; default: assert (false); return; } m_pHttpTraffic->onDataReceived (spDlg); }