コード例 #1
0
int CHttpControlSocket::FileTransferSend()
{
	LogMessage(Debug_Verbose, _T("CHttpControlSocket::FileTransferSend()"));

	if (!m_pCurOpData)
	{
		LogMessage(__TFILE__, __LINE__, this, Debug_Info, _T("Empty m_pCurOpData"));
		ResetOperation(FZ_REPLY_INTERNALERROR);
		return FZ_REPLY_ERROR;
	}

	CHttpFileTransferOpData *pData = static_cast<CHttpFileTransferOpData *>(m_pCurOpData);

	if (pData->opState == filetransfer_waitfileexists)
	{
		pData->opState = filetransfer_transfer;
		pData->pFile = new wxFile();

		CreateLocalDir(pData->localFile);

		if (!pData->pFile->Open(pData->localFile, wxFile::write))
		{
			LogMessage(::Error, _("Failed to open \"%s\" for writing"), pData->localFile.c_str());
			ResetOperation(FZ_REPLY_ERROR);
			return FZ_REPLY_ERROR;
		}

		int res = InternalConnect(m_pCurrentServer->GetHost(), m_pCurrentServer->GetPort(), m_pCurrentServer->GetProtocol() == HTTPS);
		if (res != FZ_REPLY_OK)
			return res;
	}

	wxString location;
	wxString hostWithPort;
	if (pData->m_newLocation == _T(""))
	{
		if (m_pCurrentServer->GetProtocol() == HTTPS)
			location = _T("https://") + wxString(m_pCurrentServer->FormatHost()) + wxString(pData->remotePath.FormatFilename(pData->remoteFile).c_str());
		else
			location = _T("http://") + wxString(m_pCurrentServer->FormatHost()) + wxString(pData->remotePath.FormatFilename(pData->remoteFile).c_str());
		hostWithPort = wxString::Format(_T("%s:%d"), m_pCurrentServer->FormatHost(true).c_str(), m_pCurrentServer->GetPort());
	}
	else
	{
		location = pData->m_newLocation;
		hostWithPort = pData->m_newHostWithPort;
	}

	wxString action = wxString::Format(_T("GET %s HTTP/1.1"), location.c_str());
	LogMessageRaw(Command, action);

	wxString command = wxString::Format(_T("%s\r\nHost: %s\r\nUser-Agent: %s\r\nConnection: close\r\n\r\n"), action.c_str(), hostWithPort.c_str(), wxString(PACKAGE_STRING, wxConvLocal).c_str());

	const wxWX2MBbuf str = command.mb_str();
	if (!Send(str, strlen(str)))
		return FZ_REPLY_ERROR;

	return FZ_REPLY_WOULDBLOCK;
}
コード例 #2
0
void CControlSocket::ShowStatus(CString status, int type) const
{
	if ( status.Left(5)==_T("PASS ") )
	{
		int len=status.GetLength()-5;
		status=_T("PASS ");
		for (int i=0;i<len;i++)
			status+=_MPT("*");
	}
	else if ( status.Left(5)==_T("ACCT ") )
	{
		int len=status.GetLength()-5;
		status=_T("ACCT ");
		for (int i=0;i<len;i++)
			status+=_MPT("*");
	}
	LogMessageRaw(type, (LPCTSTR)status);
}
コード例 #3
0
void CControlSocket::ShowStatus(CString status, int type) const
{
	if (!COptions::GetOptionVal(OPTION_MPEXT_LOG_SENSITIVE))
	{
		if ( status.Left(5)==_T("PASS ") )
		{
			int len=status.GetLength()-5;
			status=_T("PASS ");
			for (int i=0;i<len;i++)
				status+=_MPT("*");
		}
		else if ( status.Left(5)==_T("ACCT ") )
		{
			int len=status.GetLength()-5;
			status=_T("ACCT ");
			for (int i=0;i<len;i++)
				status+=_MPT("*");
		}
	}
	LogMessageRaw(type, (LPCTSTR)status);
}
コード例 #4
0
int CControlSocket::OnLayerCallback(rde::list<t_callbackMsg>& callbacks)
{
	USES_CONVERSION;

	for (rde::list<t_callbackMsg>::iterator iter = callbacks.begin(); iter != callbacks.end(); iter++)
	{
		if (iter->nType == LAYERCALLBACK_STATECHANGE)
		{
		    if (CAsyncSocketEx::LogStateChange(iter->nParam1, iter->nParam2))
		    {
			    const TCHAR * state2Desc = CAsyncSocketEx::GetStateDesc(iter->nParam2);
			    const TCHAR * state1Desc = CAsyncSocketEx::GetStateDesc(iter->nParam1);
				if (iter->pLayer == m_pProxyLayer)
					LogMessage(__FILE__, __LINE__, this, FZ_LOG_INFO, _T("Proxy layer changed state from %s to %s"), state2Desc, state1Desc);
#ifndef MPEXT_NO_GSS
				else if (iter->pLayer == m_pGssLayer)
					LogMessage(__FILE__, __LINE__, this, FZ_LOG_INFO, _T("m_pGssLayer changed state from %s to %s"), state2Desc, state1Desc);
#endif
				else
					LogMessage(__FILE__, __LINE__, this, FZ_LOG_INFO, _T("Layer @ %d changed state from %s to %s"), iter->pLayer, state2Desc, state1Desc);
			}
		}
		else if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC)
		{
			if (iter->pLayer == m_pProxyLayer)
			{
				switch (iter->nParam1)
				{
				case PROXYERROR_NOERROR:
					ShowStatus(IDS_PROXY_CONNECTED, FZ_LOG_STATUS);
					break;
				case PROXYERROR_NOCONN:
					ShowStatus(IDS_ERRORMSG_PROXY_NOCONN, FZ_LOG_ERROR);
					break;
				case PROXYERROR_REQUESTFAILED:
					ShowStatus(IDS_ERRORMSG_PROXY_REQUESTFAILED, FZ_LOG_ERROR);
					if (iter->str)
						ShowStatus(A2T(iter->str), FZ_LOG_ERROR);
					break;
				case PROXYERROR_AUTHTYPEUNKNOWN:
					ShowStatus(IDS_ERRORMSG_PROXY_AUTHTYPEUNKNOWN, FZ_LOG_ERROR);
					break;
				case PROXYERROR_AUTHFAILED:
					ShowStatus(IDS_ERRORMSG_PROXY_AUTHFAILED, FZ_LOG_ERROR);
					break;
				case PROXYERROR_AUTHNOLOGON:
					ShowStatus(IDS_ERRORMSG_PROXY_AUTHNOLOGON, FZ_LOG_ERROR);
					break;
				case PROXYERROR_CANTRESOLVEHOST:
					ShowStatus(IDS_ERRORMSG_PROXY_CANTRESOLVEHOST, FZ_LOG_ERROR);
					break;
				default:
					LogMessage(__FILE__, __LINE__, this, FZ_LOG_WARNING, _T("Unknown proxy error") );
				}
			}
#ifndef MPEXT_NO_GSS
			else if (iter->pLayer == m_pGssLayer)
			{
				switch (iter->nParam1)
				{
				case GSS_INFO:
					LogMessageRaw(FZ_LOG_INFO, A2CT(iter->str));
					break;
				case GSS_ERROR:
					LogMessageRaw(FZ_LOG_APIERROR, A2CT(iter->str));
					break;
				case GSS_COMMAND:
					ShowStatus(A2CT(iter->str), FZ_LOG_COMMAND);
					break;
				case GSS_REPLY:
					ShowStatus(A2CT(iter->str), FZ_LOG_REPLY);
					break;
				}
			}
#endif
		}

		nb_free(iter->str);
	}

	return 1;
}
コード例 #5
0
int CHttpControlSocket::ParseHeader(CHttpOpData* pData)
{
	// Parse the HTTP header.
	// We do just the neccessary parsing and silently ignore most header fields
	// Redirects are supported though if the server sends the Location field.

	for (;;)
	{
		// Find line ending
		unsigned int i = 0;
		for (i = 0; (i + 1) < m_recvBufferPos; i++)
		{
			if (m_pRecvBuffer[i] == '\r')
			{
				if (m_pRecvBuffer[i + 1] != '\n')
				{
					LogMessage(::Error, _("Malformed reply, server not sending proper line endings"));
					ResetOperation(FZ_REPLY_ERROR);
					return FZ_REPLY_ERROR;
				}
				break;
			}
		}
		if ((i + 1) >= m_recvBufferPos)
		{
			if (m_recvBufferPos == m_recvBufferLen)
			{
				// We don't support header lines larger than 4096
				LogMessage(::Error, _("Too long header line"));
				ResetOperation(FZ_REPLY_ERROR);
				return FZ_REPLY_ERROR;
			}
			return FZ_REPLY_WOULDBLOCK;
		}

		m_pRecvBuffer[i] = 0;
		const wxString& line = wxString(m_pRecvBuffer, wxConvLocal);
		if (line != _T(""))
			LogMessageRaw(Response, line);

		if (pData->m_responseCode == -1)
		{
			pData->m_responseString = line;
			if (m_recvBufferPos < 16 || memcmp(m_pRecvBuffer, "HTTP/1.", 7))
			{
				// Invalid HTTP Status-Line
				LogMessage(::Error, _("Invalid HTTP Response"));
				ResetOperation(FZ_REPLY_ERROR);
				return FZ_REPLY_ERROR;
			}

			if (m_pRecvBuffer[9] < '1' || m_pRecvBuffer[9] > '5' ||
				m_pRecvBuffer[10] < '0' || m_pRecvBuffer[10] > '9' ||
				m_pRecvBuffer[11] < '0' || m_pRecvBuffer[11] > '9')
			{
				// Invalid response code
				LogMessage(::Error, _("Invalid response code"));
				ResetOperation(FZ_REPLY_ERROR);
				return FZ_REPLY_ERROR;
			}

			pData->m_responseCode = (m_pRecvBuffer[9] - '0') * 100 + (m_pRecvBuffer[10] - '0') * 10 + m_pRecvBuffer[11] - '0';

			if (pData->m_responseCode >= 400)
			{
				// Failed request
				ResetOperation(FZ_REPLY_ERROR);
				return FZ_REPLY_ERROR;
			}

			if (pData->m_responseCode == 305)
			{
				// Unsupported redirect
				LogMessage(::Error, _("Unsupported redirect"));
				ResetOperation(FZ_REPLY_ERROR);
				return FZ_REPLY_ERROR;
			}
		}
		else
		{
			if (!i)
			{
				// End of header, data from now on

				// Redirect if neccessary
				if (pData->m_responseCode >= 300)
				{
					if (pData->m_redirectionCount++ == 5)
					{
						LogMessage(::Error, _("Too many redirects"));
						ResetOperation(FZ_REPLY_ERROR);
						return FZ_REPLY_ERROR;
					}

					ResetSocket();
					ResetHttpData(pData);

					wxString host;
					enum ServerProtocol protocol;
					int pos;
					if ((pos = pData->m_newLocation.Find(_T("://"))) != -1)
					{
						protocol = CServer::GetProtocolFromPrefix(pData->m_newLocation.Left(pos));
						host = pData->m_newLocation.Mid(pos + 3);
					}
					else
					{
						protocol = HTTP;
						host = pData->m_newLocation;
					}

					if ((pos = host.Find(_T("/"))) != -1)
						host = host.Left(pos);

					unsigned long port;
					if ((pos = host.Find(':', true)) != -1)
					{
						wxString strport = host.Mid(pos + 1);
						if (!strport.ToULong(&port) || port < 1 || port > 65535)
						{
							if (protocol == HTTPS)
								port = 443;
							else
								port = 80;
						}
						host = host.Left(pos);
					}
					else
					{
						if (protocol == HTTPS)
							port = 443;
						else
							port = 80;
					}

					if (host == _T(""))
					{
						// Unsupported redirect
						LogMessage(::Error, _("Redirection to invalid address"));
						ResetOperation(FZ_REPLY_ERROR);
						return FZ_REPLY_ERROR;
					}
					pData->m_newHostWithPort = wxString::Format(_T("%s:%d"), host.c_str(), (int)port);

					// International domain names
					host = ConvertDomainName(host);

					int res = InternalConnect(host, port, protocol == HTTPS);
					if (res == FZ_REPLY_WOULDBLOCK)
						res |= FZ_REPLY_REDIRECTED;
					return res;
				}

				pData->m_gotHeader = true;

				memmove(m_pRecvBuffer, m_pRecvBuffer + 2, m_recvBufferPos - 2);
				m_recvBufferPos -= 2;

				if (m_recvBufferPos)
				{
					int res;
					if (pData->m_transferEncoding == pData->chunked)
						res = OnChunkedData(pData);
					else
					{
						pData->m_receivedData += m_recvBufferPos;
						res = ProcessData(m_pRecvBuffer, m_recvBufferPos);
						m_recvBufferPos = 0;
					}
					return res;
				}

				return FZ_REPLY_WOULDBLOCK;
			}
			if (m_recvBufferPos > 12 && !memcmp(m_pRecvBuffer, "Location: ", 10))
			{
				pData->m_newLocation = wxString(m_pRecvBuffer + 10, wxConvLocal);
			}
			else if (m_recvBufferPos > 21 && !memcmp(m_pRecvBuffer, "Transfer-Encoding: ", 19))
			{
				if (!strcmp(m_pRecvBuffer + 19, "chunked"))
					pData->m_transferEncoding = CHttpOpData::chunked;
				else if (!strcmp(m_pRecvBuffer + 19, "identity"))
					pData->m_transferEncoding = CHttpOpData::identity;
				else
					pData->m_transferEncoding = CHttpOpData::unknown;
			}
			else if (i > 16 && !memcmp(m_pRecvBuffer, "Content-Length: ", 16))
			{
				pData->m_totalSize = 0;
				char* p = m_pRecvBuffer + 16;
				while (*p)
				{
					if (*p < '0' || *p > '9')
					{
						LogMessage(::Error, _("Malformed header: %s"), _("Invalid Content-Length"));
						ResetOperation(FZ_REPLY_ERROR);
						return FZ_REPLY_ERROR;
					}
					pData->m_totalSize = pData->m_totalSize * 10 + *p++ - '0';
				}
			}
		}

		memmove(m_pRecvBuffer, m_pRecvBuffer + i + 2, m_recvBufferPos - i - 2);
		m_recvBufferPos -= i + 2;

		if (!m_recvBufferPos)
			break;
	}

	return FZ_REPLY_WOULDBLOCK;
}