Beispiel #1
0
int main(int argc, char** argv)
{
	std::map<std::string, std::string> args = ProcessArgs(argc, argv);

	if (args.size() != 5 || !ValidateArgs(args))
	{
		ShowHelp();
		return -5;
	}

	DesuraId id(args["-i"].c_str(), args["-t"].c_str());

	if (!Login(args["-u"], args["-p"]))
		return -1;

	if (!CreateMcf(id, args["-f"]))
		return -2;

	if (!StartUpload(id))
		return -3;

	if (!UploadMcf())
		return -4;

	return 0;
}
Beispiel #2
0
	virtual int performAction(std::vector<std::string> &args)
	{
		DesuraId id(args[3].c_str(), args[4].c_str());

		if (!Login(args[0], args[1]))
			return -1;

		if (!CreateMcf(id, args[2]))
			return -2;

		if (!StartUpload(id))
			return -3;

		if (!UploadMcf())
			return -4;

		return 0;
	}
Beispiel #3
0
void CGnuUpload::Send_HttpOK()
{	
	if((CGnuUpload*) m_pShell->m_Socket != this)
		return;


	CString HttpOK;

	//HTTP Version
	if (m_pShell->m_HTTPVersion == "HTTP/1.1")
		HttpOK =  "HTTP/1.1 ";
	else
		HttpOK =  "HTTP ";

	//200 or 206
	if (m_pShell->m_StartPos == 0 && m_pShell->m_StopPos == m_pShell->m_FileLength)
		HttpOK +=  "200 OK\r\n";
	else
		HttpOK +=  "206 Partial Content\r\n";

	// Server
	HttpOK += "Server: " + m_pNet->m_pCore->GetUserAgent() + "\r\n";
	
	// Content-Type
	HttpOK += "Content-type: application/octet-stream\r\n";	//I think octet-stream is more correct than binary
	//HttpOK += "Content-type: application/zip\r\n";

	// Accept-Ranges
	HttpOK += "Accept-Ranges: bytes\r\n";

	// Conent-Range, it is "bytes x-y/z" not "bytes=x-y/z"
	HttpOK += "Content-Range: bytes " + NumtoStr(m_pShell->m_StartPos) + "-" + NumtoStr(m_pShell->m_StopPos - 1) + "/" + NumtoStr(m_pShell->m_FileLength) + "\r\n";
	
	// Content-Length
	HttpOK += "Content-Length: " + NumtoStr(m_pShell->m_StopPos - m_pShell->m_StartPos) + "\r\n";

	// Connection
	if (m_pShell->m_KeepAlive)
		HttpOK += "Connection: Keep-Alive\r\n";	//Even on 1.1 where keep-alive is assumed
	else if (m_pShell->m_HTTPVersion == "HTTP/1.1")
		HttpOK += "Connection: Close\r\n";		//Only in 1.1. Close is assumed in 1.0


	std::map<int, CGnuDownloadShell*>::iterator itPart;

	// X-Available-Ranges
	if (m_pShell->m_IsPartial)
	{	
		itPart = m_pTrans->m_DownloadMap.find(m_pShell->m_PartialID);

		if(itPart != m_pTrans->m_DownloadMap.end())
			HttpOK += "X-Available-Ranges: bytes " + itPart->second->AvailableRangesCommaSeparated() + "\r\n";
	}

	// X-Gnutella-Content-URN
	if (!m_pShell->m_Sha1Hash.IsEmpty())
	{
		if( m_pShell->m_Network == NETWORK_GNUTELLA )
			HttpOK += "X-Gnutella-Content-URN: urn:sha1:" + m_pShell->m_Sha1Hash + "\r\n";
		else if( m_pShell->m_Network == NETWORK_G2 )
			HttpOK += "Content-URN: urn:sha1:" + m_pShell->m_Sha1Hash + "\r\n";

		// X-TigerTree-Path
		if (!m_pShell->m_TigerHash.IsEmpty())
		{
			CString Client = m_pShell->m_RemoteClient;
			Client.MakeLower();

			// handle a million implementations
			if( Client.Find("dna") != -1)
				HttpOK += "X-TigerTree-Path: /gnutella/tigertree/v3?urn:tree:tiger/:" + m_pShell->m_TigerHash + "\r\n";
			else if( Client.Find("bearshare") != -1 || Client.Find("shareaza") != -1)
				HttpOK += "X-Thex-URI: /gnutella/thex/v1?urn:tree:tiger/:" + m_pShell->m_TigerHash + "\r\n";
			else
				HttpOK += "X-Thex-URI: /uri-res/N2X?urn:sha1:" + m_pShell->m_Sha1Hash + ";" + m_pShell->m_TigerHash + "\r\n";
		}

		// X-Alt
		if (!m_pShell->m_IsPartial)
			HttpOK += m_pShare->GetShareAltLocHeader(m_pShell->m_Sha1Hash, m_pShell->m_Host);
		else
		{
			itPart = m_pTrans->m_DownloadMap.find(m_pShell->m_PartialID);

			if(itPart != m_pTrans->m_DownloadMap.end())
				HttpOK += itPart->second->GetAltLocHeader( m_pShell->m_Host );
		}
	}

	// X-Push-Proxy
	if(m_Push && m_pShell->m_Network == NETWORK_GNUTELLA && m_pNet->m_pGnu)
		HttpOK += m_pNet->m_pGnu->GetPushProxyHeader();

	// X-Filename
	if(m_pShell->m_RequestURI.Left(9) == "/uri-res/")
		HttpOK += "X-Filename: " + m_pShell->m_Name + "\r\n";

	// Authentication
	if( !m_Authorized )
	{
		if(m_pNet->m_pCore->m_dnaCore->m_dnaEvents)
			m_pNet->m_pCore->m_dnaCore->m_dnaEvents->UploadAuthenticate(m_pShell->m_UploadID);
 
		if(m_pShell->m_Challenge == "ERROR")
		{
			Close();
			return;
		}

		if(!m_pShell->m_Challenge.IsEmpty() && !m_pShell->m_ChallengeAnswer.IsEmpty())
			HttpOK += "X-Auth-Challenge: " + m_pShell->m_Challenge + "\r\n";
		else
			m_Authorized = true;
	}

	// End header
	HttpOK += "\r\n";

	// Send header
	m_pSocket->Send(HttpOK, HttpOK.GetLength());

	m_pShell->m_Handshake += HttpOK;


	if(m_Authorized)
		StartUpload();
}
Beispiel #4
0
void CGnuUpload::OnReceive(int nErrorCode) 
{
	byte pBuff[6000];

	int dwBuffLength = m_pSocket->Receive(pBuff, 4096);

	switch (dwBuffLength)
	{
	case 0:
		m_pShell->m_Error = "Bad Push";
		Close();
		return;
		break;
	case SOCKET_ERROR:
		m_pShell->m_Error = "Bad Push";
		Close();
		return;
		break;
	}

	pBuff[dwBuffLength] = 0;
	CString Header(pBuff);


	// Clear old GetRequest when new one comes in
	if(m_GetRequest.Find("\r\n\r\n") != -1)
	{
		m_GetRequest = "";
		m_pShell->m_Handshake  = "";
	}

	m_pShell->m_Handshake += Header;
	m_GetRequest += Header;


	// New Upload
	if(m_GetRequest.Find("\r\n\r\n") != -1)
	{
		if(m_GetRequest.Left(4) == "GET " || m_GetRequest.Left(5) == "HEAD ")
		{	
			// Get Node info
			CString Host;
			UINT    nPort;
			m_pSocket->GetPeerName(Host, nPort);
			

			// Check if it's a blocked Host 
			if (m_pPrefs->BlockedIP(StrtoIP(Host)) == true) 
			{ 
				m_pShell->m_Error = "Blocked"; 
				Send_ClientBlock(Host); 
				Close(); 
			} 
			else 
			{ 
				// Set Variables 
				m_pShell->m_Host = StrtoIP(Host); 
				m_pShell->m_Port = 0; 
				m_pShell->m_RequsetPending = true;
			}

		}
		else if( m_GetRequest.Left(4) == "AUTH" && !m_pShell->m_Challenge.IsEmpty() )
		{		
			CParsedHeaders ParsedHeaders(m_pShell->m_Handshake);
			
			if(m_pShell->m_ChallengeAnswer.Compare( ParsedHeaders.FindHeader("X-Auth-Response") ) == 0 )
			{
				m_Authorized = true;
				StartUpload();
			}
			else
			{
				m_pShell->m_Error = "Authentication Failed";
				Close();
			}
		}

		else
		{
			m_pShell->m_Error = "Bad Push";
			Close();
		}
	}
}
Beispiel #5
0
// Process the first fragment of input from the client.
// Return true if the session should be kept open.
bool Webserver::ProcessFirstFragment(HttpSession& session, const char* command, bool isOnlyFragment)
{
	// Process connect messages first
	if (StringEquals(command, "connect") && GetKeyValue("password") != nullptr)
	{
		OutputBuffer *response;
		if (OutputBuffer::Allocate(response))
		{
			if (session.isAuthenticated || reprap.CheckPassword(GetKeyValue("password")))
			{
				// Password is OK, see if we can update the current RTC date and time
				const char *timeVal = GetKeyValue("time");
				if (timeVal != nullptr && !platform->IsDateTimeSet())
				{
					struct tm timeInfo;
					memset(&timeInfo, 0, sizeof(timeInfo));
					if (strptime(timeVal, "%Y-%m-%dT%H:%M:%S", &timeInfo) != nullptr)
					{
						time_t newTime = mktime(&timeInfo);
						platform->SetDateTime(newTime);
					}
				}

				// Client has logged in
				session.isAuthenticated = true;
				response->printf("{\"err\":0,\"sessionTimeout\":%u,\"boardType\":\"%s\"}", httpSessionTimeout, platform->GetBoardString());
			}
			else
			{
				// Wrong password
				response->copy("{\"err\":1}");
			}
			network->SendReply(session.ip, 200 | rcJson, response);
		}
		else
		{
			// If we failed to allocate an output buffer, send back an error string
			network->SendReply(session.ip, 200 | rcJson, "{\"err\":2}");
		}
		return false;
	}

	if (StringEquals(command, "disconnect"))
	{
		network->SendReply(session.ip, 200 | rcJson, "{\"err\":0}");
		DeleteSession(session.ip);
		return false;
	}

	// Try to authorise the user automatically to retain compatibility with the old web interface
	if (!session.isAuthenticated && reprap.NoPasswordSet())
	{
		session.isAuthenticated = true;
	}

	// If the client is still not authenticated, stop here
	if (!session.isAuthenticated)
	{
		network->SendReply(session.ip, 500, "Not authorized");
		return false;
	}

	if (StringEquals(command, "reply"))
	{
		SendGCodeReply(session);
		return false;
	}

	// rr_configfile sends the config as plain text well
	if (StringEquals(command, "configfile"))
	{
		const char *configPath = platform->GetMassStorage()->CombineName(platform->GetSysDir(), platform->GetConfigFile());
		char fileName[FILENAME_LENGTH];
		strncpy(fileName, configPath, FILENAME_LENGTH);

		SendFile(fileName, session);
		return false;
	}

	if (StringEquals(command, "download") && GetKeyValue("name") != nullptr)
	{
		SendFile(GetKeyValue("name"), session);
		return false;
	}

	if (StringEquals(command, "upload"))
	{
		const char* nameVal = GetKeyValue("name");
		const char* lengthVal = GetKeyValue("length");
		const char* timeVal = GetKeyValue("time");
		if (nameVal != nullptr && lengthVal != nullptr)
		{
			// Try to obtain the last modified time
			time_t fileLastModified = 0;
			struct tm timeInfo;
			memset(&timeInfo, 0, sizeof(timeInfo));
			if (timeVal != nullptr && strptime(timeVal, "%Y-%m-%dT%H:%M:%S", &timeInfo) != nullptr)
			{
				fileLastModified = mktime(&timeInfo);
			}

			// Deal with file upload request
			uint32_t fileLength = atol(lengthVal);
			StartUpload(session, nameVal, fileLength, fileLastModified);
			if (session.uploadState == uploading)
			{
				if (isOnlyFragment)
				{
					FinishUpload(session);
					return false;
				}
				else
				{
					network->DiscardMessage();		// no reply needed yet
					return true;		// expecting more data
				}
			}
		}

		network->SendReply(session.ip, 200 | rcJson, "{\"err\":1}");	// TODO return the cause of the error
		return false;
	}

	if (StringEquals(command, "move"))
	{
		const char* response =  "{\"err\":1}";		// assume failure
		const char* const oldVal = GetKeyValue("old");
		const char* const newVal = GetKeyValue("new");
		if (oldVal != nullptr && newVal != nullptr)
		{
			const bool success = platform->GetMassStorage()->Rename(oldVal, newVal);
			if (success)
			{
				response =  "{\"err\":0}";
			}
		}
		network->SendReply(session.ip, 200 | rcJson, response);
		return false;
	}

	if (StringEquals(command, "mkdir"))
	{
		const char* response =  "{\"err\":1}";		// assume failure
		const char* dirVal = GetKeyValue("dir");
		if (dirVal != nullptr)
		{
			bool ok = (platform->GetMassStorage()->MakeDirectory(dirVal));
			if (ok)
			{
				response =  "{\"err\":0}";
			}
		}
		network->SendReply(session.ip, 200 | rcJson, response);
		return false;
	}

	if (StringEquals(command, "delete"))
	{
		const char* response =  "{\"err\":1}";		// assume failure
		const char* nameVal = GetKeyValue("name");
		if (nameVal != nullptr)
		{
			bool ok = platform->GetMassStorage()->Delete("0:/", nameVal);
			if (ok)
			{
				response =  "{\"err\":0}";
			}
		}
		network->SendReply(session.ip, 200 | rcJson, response);
		return false;
	}

	// The remaining commands use an OutputBuffer for the response
	OutputBuffer *response = nullptr;
	if (StringEquals(command, "status"))
	{
		const char* typeVal = GetKeyValue("type");
		if (typeVal != nullptr)
		{
			// New-style JSON status responses
			int type = atoi(typeVal);
			if (type < 1 || type > 3)
			{
				type = 1;
			}

			response = reprap.GetStatusResponse(type, ResponseSource::HTTP);
		}
		else
		{
			response = reprap.GetLegacyStatusResponse(1, 0);
		}
	}
	else if (StringEquals(command, "gcode"))
	{
		const char* gcodeVal = GetKeyValue("gcode");
		if (gcodeVal != nullptr)
		{
			RegularGCodeInput * const httpInput = reprap.GetGCodes()->GetHTTPInput();
			httpInput->Put(HTTP_MESSAGE, gcodeVal);
			if (OutputBuffer::Allocate(response))
			{
				response->printf("{\"buff\":%u}", httpInput->BufferSpaceLeft());
			}
		}
		else
		{
			network->SendReply(session.ip, 200 | rcJson, "{\"err\":1}");
			return false;
		}
	}
	else if (StringEquals(command, "filelist") && GetKeyValue("dir") != nullptr)
	{
		response = reprap.GetFilelistResponse(GetKeyValue("dir"));
	}
	else if (StringEquals(command, "files"))
	{
		const char* dir = GetKeyValue("dir");
		if (dir == nullptr)
		{
			dir = platform->GetGCodeDir();
		}
		const char* const flagDirsVal = GetKeyValue("flagDirs");
		const bool flagDirs = flagDirsVal != nullptr && atoi(flagDirsVal) == 1;
		response = reprap.GetFilesResponse(dir, flagDirs);
	}
	else if (StringEquals(command, "fileinfo"))
	{
		const char* const nameVal = GetKeyValue("name");
		if (reprap.GetPrintMonitor()->GetFileInfoResponse(nameVal, response))
		{
			processingDeferredRequest = false;
		}
		else
		{
			processingDeferredRequest = true;
		}
	}
	else if (StringEquals(command, "config"))
	{
		response = reprap.GetConfigResponse();
	}
	else
	{
		platform->MessageF(HOST_MESSAGE, "KnockOut request: %s not recognised\n", command);
		network->SendReply(session.ip, 400, "Unknown rr_ command");
		return false;
	}

	if (response != nullptr)
	{
		network->SendReply(session.ip, 200 | rcJson, response);
	}
	else if (!processingDeferredRequest)
	{
		network->SendReply(session.ip, 500, "No buffer available");
	}
	return processingDeferredRequest;
}