bool CMimeParser::ProcessMultipart(CString RawData, const CString& Boundary, CVectorTable<CStringTable>& Fields) { //cout << "expected boundary: [" << "--" + Boundary << "]" << endl; CString OneLine; RawData.ExtractLine(&OneLine); //cout << " found boundary: [" << OneLine << "]" << endl; CString PrefixedBoundary; while (OneLine.GetLength()) { //cout << OneLine << endl; PrefixedBoundary = g_strDashDash; PrefixedBoundary.Append(Boundary); if (OneLine == PrefixedBoundary) { CStringTable Table; CString Name, Value; RawData.ExtractLine(&OneLine); while (OneLine.GetLength()) { if (ParseLine(OneLine, Name, Value, Table)) { //Fields.Add(Name, Table); // _L_DEBUG(3, cout << "---------------------" << endl); // _L_DEBUG(3, cout << "Content disposition: " << Table.GetValue("Content-Disposition") << endl); // _L_DEBUG(3, cout << " Name: " << Table.GetValue("name") << endl); // _L_DEBUG(3, cout << " Content type: " << Table.GetValue("Content-type") << endl); // _L_DEBUG(3, cout << " Filename: " << Table.GetValue("Filename") << endl); } else return false; RawData.ExtractLine(&OneLine); } int NextBoundaryPosition = RawData.Pos(PrefixedBoundary); if (NextBoundaryPosition == -1) NextBoundaryPosition = RawData.GetLength(); Table.Add(g_strValue, CString(RawData.GetBuffer(), NextBoundaryPosition-2)); Fields.Add(Table.GetValue(g_strName), Table); RawData.Delete(0, NextBoundaryPosition); // _L_DEBUG(3, cout << " Value: " << Table.GetValue(g_strValue) << endl); RawData.ExtractLine(&OneLine); } else return false; } return true; }
int CHttpRequest::ExecuteGet(bool Recurse) { bool bContinueExecuteGet = false; bool bKeepAlive = false; Trace(tagHttp, levInfo, ("CHttpRequest - ExecuteGet")); unsigned int nCredentialsIndex = 0; bool Result; do { if (! bKeepAlive) { Result = CreateSocket(); if (! Result) { return -1; } } bContinueExecuteGet = false; // process authentication CString AuthHeader; switch(m_ServerAuthState.GetLeg()) { case AUTHENTICATION_STATE_NONE: break; case AUTHENTICATION_STATE_PRECHALENGE: case AUTHENTICATION_STATE_CHALENGE: if (! m_ServerAuthState.GetNextHeader(& AuthHeader, nCredentialsIndex)) return m_RStatusValue; break; } ClearResults(false); // add the auth header if (AuthHeader.GetLength()) SetHttpField(g_strHttpAuthorization, AuthHeader); /* create socket and get results */ CStringTable Connection; if (!m_HttpFields.FindAndCopy(g_strHttpConnection, Connection) || ! Connection.GetValue(g_strHttpConnection).GetLength()) { SetHttpField(g_strHttpConnection, "Keep-Alive"); } Result = GetHTTP((float) 1.0); // 406: no acceptable objects found (NT4/ISM) // if (!Result || (m_RStatusValue == 406)) { // ClearResults(false); // Result = CreateSocket() && GetHTTP((float) 0.9); // if (! Result) { // return -1; // } // } Trace(tagHttp, levInfo, ("CHttpRequest - ExecuteGet {%d/%d}", Result, m_RStatusValue)); if (! Result) { return -1; } CString l_RedirectLoc; CUrl ResolvedUrl; switch(m_RStatusValue) { case 407: // $(TODO) break; case 401: // any valid authentication stage if (m_ServerAuthState.GetLeg() == AUTHENTICATION_STATE_NONE) { // we need to send credentials m_ServerAuthState.SetLeg(AUTHENTICATION_STATE_PRECHALENGE); bContinueExecuteGet = true; } else if (m_ServerAuthState.GetLeg() == AUTHENTICATION_STATE_CHALENGE) { nCredentialsIndex ++; // equal, because we do want to run once without username/password credentials if (nCredentialsIndex <= m_ServerAuthState.GetSize()) { bContinueExecuteGet = true; } m_ServerAuthState.SetLeg(AUTHENTICATION_STATE_PRECHALENGE); bKeepAlive = false; } else if (m_ServerAuthState.GetLeg() == AUTHENTICATION_STATE_PRECHALENGE) { m_ServerAuthState.SetLeg(AUTHENTICATION_STATE_CHALENGE); bContinueExecuteGet = true; bKeepAlive = true; } break; case 301: /* redirections */ case 302: case 303: case 307: l_RedirectLoc = m_RFields.FindElement(g_strHttpLocation).GetValue(g_strHttpLocation); if (! l_RedirectLoc.GetLength()) { Trace(tagHttp, levInfo, ("CHttpRequest - GetHTTP - %d redirection without a Location: header.", m_RStatusValue)); break; } // HTTP 1.1 - Temporary Redirect is 302 and 307 // m_RRedirections is relevant for final URL address // that could be retrieved ResolvedUrl = m_Url.Resolve(l_RedirectLoc); l_RedirectLoc = ResolvedUrl.GetHttpAll(); if (m_FollowRedirections && m_RRedirections.Contains(l_RedirectLoc)) { // avoid circular redirections Trace(tagHttp, levInfo, ("CHttpRequest - GetHTTP - circular redirection %s", l_RedirectLoc.GetBuffer())); return m_RStatusValue; } else m_RRedirections.Add(l_RedirectLoc); if (!m_FollowRedirections) return m_RStatusValue; if (m_ClientSocket.GetVerbose()) cout << "\n\t[" << l_RedirectLoc << "]"; ClearResults(false); m_Url.SetUrl(l_RedirectLoc); bContinueExecuteGet = true; break; case 305: /* use proxy */ l_RedirectLoc = m_RFields.FindElement(g_strHttpLocation).GetValue(g_strHttpLocation); if (! l_RedirectLoc.GetLength()) break; // HTTP 1.1 - Temporary Redirect is 302 and 307 // m_RRedirections is relevant for final URL address // that could be retrieved ClearResults(false); m_Proxy.SetUrl(l_RedirectLoc); bContinueExecuteGet = true; break; }; Trace(tagHttp, levInfo, ("CHttpRequest - GetHTTP - %d", m_RStatusValue)); } while (bContinueExecuteGet); return m_RStatusValue; }