Ejemplo n.º 1
0
bool HTTPClient::Init(void* _ptr) {
	if(_ptr) {
		is_raise_error_multi_handle = true;
		code_multi = *(CURLMcode*)_ptr;
		return true;
	}
	if(is_raise_error_multi_handle)
		return true;
	
	//디비에서 URL이랑 매치되는 필드가져오기
	sqlite3* _db = NULL;
	char* _db_message = NULL;
	HTTP_DEBUG((sqlite3_open(HTTPManager::Share()->GetDBPath().c_str(), &_db)),
			   "sqlite 디비 열기에 실패하였습니다." << opened_file << "\nError Message:" << sqlite3_errmsg(_db) << "\n");
	std::string _query = "SELECT * FROM request WHERE url='" + request.url + "' LIMIT 1";
	HTTP_DEBUG((sqlite3_exec(_db, _query.c_str(), SQLMatchURLCallback, this, &_db_message)),
			   "sqllite 디비 검색에 실패하였습니다." << "\nError Message:" << _db_message);
	HTTP_DEBUG((sqlite3_close(_db)),
			   "sqlite 디비 닫기에 실패하였습니다." << "\nError Message:" << sqlite3_errmsg(_db) << "\n");
	
	if(db_id.length()) {
		if(db_expires > HTTP::CurrentTime()) {
			//저장된것 사용
			cache_type = HTTPResponse::CacheType_Expires;
		} else if(db_max_age > 0) {
			if(last_updated - db_last_updated < db_max_age) {
				//저장된것 사용
				cache_type = HTTPResponse::CacheType_Expires;
			} else {
				//연결(이후 Last-Modified로 캐쉬 체크)
				cache_type = HTTPResponse::CacheType_Last_Modified;
			}
		} else {
			//연결(이후 Last-Modified로 캐쉬 체크)
			cache_type = HTTPResponse::CacheType_Last_Modified;
		}
	} else {
		//처음 다운
		cache_type = HTTPResponse::CacheType_None;
	}
	
	if(!request.use_cache)
		cache_type = HTTPResponse::CacheType_None;
	
	//파일 준비
	ReadyFile();

#ifdef ANDROID_NDK
    if (is_https)
        return true;
#endif
    
	//연결이 필요한경우는 curl생성
	if(cache_type != HTTPResponse::CacheType_Expires)
		curl = curl_easy_init();
	
	if(curl) {
		curl_easy_setopt(curl, CURLOPT_URL, request.GetURL().c_str());
		
		ReadyHeader();
		ReadyBody();
		
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);
		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HTTPClient::ReadBody);
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
		curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, ReadHeader);
		curl_easy_setopt(curl, CURLOPT_WRITEHEADER, this);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
		
		curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
		curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, HTTPClient::Progress);
		curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this);
		
		curl_multi_add_handle(HTTPManager::Share()->GetCURLMulti(), curl);
	}
	
	return true;
}
Ejemplo n.º 2
0
void CGnuUpdateSock::OnReceive(int nErrorCode)
{
	// Receive Data
	byte* pBuff = new byte[8000];
	int BuffLength = Receive(pBuff, 4096);

	// Check for errors
	switch (BuffLength)
	{
	case 0:
		m_Error = "No Data";
		Close();
		delete [] pBuff;
		return;
		break;
	case SOCKET_ERROR:
		m_Error = "Socket Error";
		Close();
		delete [] pBuff;
		return;
		break;
	}

	// React to different download states
	if(m_Status == TRANSFER_RECEIVING)
	{
		Download(pBuff, BuffLength);
	}
	else if(m_Status == TRANSFER_CONNECTED)
	{
		pBuff[BuffLength] = '\0';
		
		m_Header += CString(pBuff);
		
		if(m_Header.Find("\r\n\r\n") != -1)
		{
			CString Handshake = m_Header;
			CString FirstLine = Handshake.Mid(0, Handshake.Find("\r\n"));

			// Check HTTP header
			int  HttpCode   = 0;
			char okBuff[10] = "";
			::sscanf((LPCTSTR) FirstLine, "%s %d", okBuff, &HttpCode);

			if(200 <= HttpCode && HttpCode < 300)
			{
				Handshake.MakeLower();

				int FileBegin = Handshake.Find("\r\n\r\n") + 4;
				if(FileBegin == 3)
				{
					m_Error = "Bad HTTP Response";
					Close();
				}

				// New download
				else
				{	
					int pos = Handshake.Find("\r\ncontent-length:");

					if(pos != -1)
						sscanf((LPCTSTR) Handshake.Mid(pos), "\r\ncontent-length: %ld\r\n", &m_FileSize);

					if(m_FileSize)
					{
						m_Status = TRANSFER_RECEIVING;
						ReadyFile();
						
						if(BuffLength - FileBegin > 0)
							Download(&pBuff[FileBegin], BuffLength - FileBegin);
					}
					else
					{
						m_Error = "Bad File Size";
						Close();
					}
				}
			}
			else if(300 <= HttpCode && HttpCode < 400)
			{

				// If file moved
				if(HttpCode == 301)
				{
					CParsedHeaders ParsedHeaders(m_Header);

					CString Location = ParsedHeaders.FindHeader("Location");
					if( !Location.IsEmpty() )
						m_pUpdate->AddServer(Location);
				}
				
				Close();
			}
			else if(400 <= HttpCode && HttpCode < 500)
			{
				m_Error = "File Not Found";
				Close();
			}
			else if(500 <= HttpCode && HttpCode < 600)
			{
				m_Error = "Server Busy";
				Close();
			}
			else
			{
				m_Error = "Bad HTTP Response";
				Close();
			}
		}
	}
	else
	{
		m_Error = "Wrong State";
		Close();
	}

	delete [] pBuff;

	CAsyncSocketEx::OnReceive(nErrorCode);
}