Example #1
0
int CRealControlSocket::ContinueConnect()
{
	wxString host;
	unsigned int port = 0;

	const int proxy_type = m_pEngine->GetOptions()->GetOptionVal(OPTION_PROXY_TYPE);
	if (proxy_type > CProxySocket::unknown && proxy_type < CProxySocket::proxytype_count && !m_pCurrentServer->GetBypassProxy())
	{
		LogMessage(::Status, _("Connecting to %s through proxy"), m_pCurrentServer->FormatHost().c_str());

		host = m_pEngine->GetOptions()->GetOption(OPTION_PROXY_HOST);
		port = m_pEngine->GetOptions()->GetOptionVal(OPTION_PROXY_PORT);

		delete m_pBackend;
		m_pProxyBackend = new CProxySocket(this, m_pSocket, this);
		m_pBackend = m_pProxyBackend;
		int res = m_pProxyBackend->Handshake((enum CProxySocket::ProxyType)proxy_type,
											 m_pCurrentServer->GetHost(), m_pCurrentServer->GetPort(),
											  m_pEngine->GetOptions()->GetOption(OPTION_PROXY_USER),
											  m_pEngine->GetOptions()->GetOption(OPTION_PROXY_PASS));

		if (res != EINPROGRESS)
		{
			LogMessage(::Error, _("Could not start proxy handshake: %s"), CSocket::GetErrorDescription(res).c_str());
			DoClose();
			return FZ_REPLY_ERROR;
		}
	}
	else
	{
		if (m_pCurOpData && m_pCurOpData->opId == cmd_connect)
		{
			CConnectOpData* pData = (CConnectOpData*)m_pCurOpData;
			host = ConvertDomainName(pData->host);
			port = pData->port;
		}
		if (host == _T(""))
		{
			host = m_pCurrentServer->GetHost();
			port = m_pCurrentServer->GetPort();
		}
	}
	if (!IsIpAddress(host))
		LogMessage(Status, _("Resolving address of %s"), host.c_str());

	int res = m_pSocket->Connect(host, port);

	// Treat success same as EINPROGRESS, we wait for connect notification in any case
	if (res && res != EINPROGRESS)
	{
		LogMessage(::Error, _("Could not connect to server: %s"), CSocket::GetErrorDescription(res).c_str());
		DoClose();
		return FZ_REPLY_ERROR;
	}

	return FZ_REPLY_WOULDBLOCK;
}
Example #2
0
int CRealControlSocket::ContinueConnect()
{
	wxString host;
	unsigned int port = 0;

	const int proxy_type = engine_.GetOptions().GetOptionVal(OPTION_PROXY_TYPE);
	if (proxy_type > CProxySocket::unknown && proxy_type < CProxySocket::proxytype_count && !m_pCurrentServer->GetBypassProxy()) {
		LogMessage(MessageType::Status, _("Connecting to %s through %s proxy"), m_pCurrentServer->FormatHost(), CProxySocket::Name(static_cast<CProxySocket::ProxyType>(proxy_type)));

		host = engine_.GetOptions().GetOption(OPTION_PROXY_HOST);
		port = engine_.GetOptions().GetOptionVal(OPTION_PROXY_PORT);

		delete m_pBackend;
		m_pProxyBackend = new CProxySocket(this, m_pSocket, this);
		m_pBackend = m_pProxyBackend;
		int res = m_pProxyBackend->Handshake((enum CProxySocket::ProxyType)proxy_type,
											m_pCurrentServer->GetHost(), m_pCurrentServer->GetPort(),
											engine_.GetOptions().GetOption(OPTION_PROXY_USER),
											engine_.GetOptions().GetOption(OPTION_PROXY_PASS));

		if (res != EINPROGRESS) {
			LogMessage(MessageType::Error, _("Could not start proxy handshake: %s"), CSocket::GetErrorDescription(res));
			DoClose();
			return FZ_REPLY_ERROR;
		}
	}
	else {
		if (m_pCurOpData && m_pCurOpData->opId == Command::connect) {
			CConnectOpData* pData(static_cast<CConnectOpData*>(m_pCurOpData));
			host = ConvertDomainName(pData->host);
			port = pData->port;
		}
		if (host.empty()) {
			host = m_pCurrentServer->GetHost();
			port = m_pCurrentServer->GetPort();
		}
	}
	if (fz::get_address_type(host.ToStdWstring()) == fz::address_type::unknown) {
		LogMessage(MessageType::Status, _("Resolving address of %s"), host);
	}

	int res = m_pSocket->Connect(fz::to_native(host), port);

	// Treat success same as EINPROGRESS, we wait for connect notification in any case
	if (res && res != EINPROGRESS) {
		LogMessage(MessageType::Error, _("Could not connect to server: %s"), CSocket::GetErrorDescription(res));
		DoClose();
		return FZ_REPLY_ERROR;
	}

	return FZ_REPLY_WOULDBLOCK;
}
Example #3
0
int CRealControlSocket::Connect(const CServer &server)
{
	SetWait(true);

	if (server.GetEncodingType() == ENCODING_CUSTOM)
		m_pCSConv = new wxCSConv(server.GetCustomEncoding());

	if (m_pCurrentServer)
		delete m_pCurrentServer;
	m_pCurrentServer = new CServer(server);

	// International domain names
	m_pCurrentServer->SetHost(ConvertDomainName(server.GetHost()), server.GetPort());

	return ContinueConnect();
}
Example #4
0
int CRealControlSocket::Connect(const CServer &server)
{
	SetWait(true);

	if (server.GetEncodingType() == ENCODING_CUSTOM)
	{
		LogMessage(MessageType::Debug_Info, _T("Using custom encoding: %s"), server.GetCustomEncoding());
		m_pCSConv = new wxCSConv(server.GetCustomEncoding());
	}

	delete m_pCurrentServer;
	m_pCurrentServer = new CServer(server);

	// International domain names
	m_pCurrentServer->SetHost(ConvertDomainName(server.GetHost()), server.GetPort());

	return ContinueConnect();
}
BOOL CControlSocket::Connect(CString hostAddress, UINT nHostPort)
{
	hostAddress = ConvertDomainName(hostAddress);

	//Don't resolve host asynchronously when using proxies
	if (m_pProxyLayer)
	{
		//If using proxies, we can't use ident -> won't be reachable from outside
		
		return CAsyncSocketEx::Connect(hostAddress, nHostPort);
	}
	BOOL res = CAsyncSocketEx::Connect(hostAddress, nHostPort);
	int nLastError = WSAGetLastError();
	if (res || nLastError==WSAEWOULDBLOCK)
	{
#ifndef MPEXT_NO_IDENT
		if (COptions::GetOptionVal(OPTION_IDENT))
			m_pIdentControl = new CIdentServerControl(this);
#endif
		WSASetLastError(nLastError);
	}
	
	return res;
}
Example #6
0
int CRealControlSocket::Connect(const CServer &server)
{
	SetWait(true);

	if (server.GetEncodingType() == ENCODING_CUSTOM)
		m_pCSConv = new wxCSConv(server.GetCustomEncoding());

	if (m_pCurrentServer)
		delete m_pCurrentServer;
	m_pCurrentServer = new CServer(server);

	CConnectOpData* pData;
	if (!m_pCurOpData || m_pCurOpData->opId != cmd_connect)
		pData = 0;
	else
		pData = static_cast<CConnectOpData *>(m_pCurOpData);
	
	const wxString& host = pData ? pData->host : server.GetHost();
	if (!IsIpAddress(host))
	{
		LogMessage(Status, _("Resolving IP-Address for %s"), host.c_str());
		CAsyncHostResolver *resolver = new CAsyncHostResolver(m_pEngine, ConvertDomainName(host));
		m_pEngine->AddNewAsyncHostResolver(resolver);

		resolver->Create();
		resolver->Run();
	}
	else
	{
		wxIPV4address addr;
		addr.Hostname(host);
		return ContinueConnect(&addr);
	}

	return FZ_REPLY_WOULDBLOCK;
}
Example #7
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;
}