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; }
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); }