//ensure you set up WRITE and DELETE permission for user ref'd by "myuser" void TransferFile(LPTSTR lpFile, LPTSTR lpServer) { HINTERNET hSession = InternetOpen("BL_FTPCLIENT/1.0", INTERNET_OPEN_TYPE_DIRECT,0,0,0); InternetSetStatusCallback(hSession,&MyStatusCallback); HINTERNET hConnect = InternetConnect(hSession, lpServer, INTERNET_DEFAULT_FTP_PORT, "myuser", "mypassword", INTERNET_SERVICE_FTP,0,1); FtpPutFile(hConnect, lpFile, lpFile, FTP_TRANSFER_TYPE_BINARY, 0); InternetCloseHandle(hConnect); InternetCloseHandle(hSession); return; }
bool FWinInetConnection::ShutdownConnection() { UE_LOG(LogHttp, Log, TEXT("Closing internet connection")); { FScopeLock ScopeLock(&FHttpManager::RequestLock); bStaticConnectionInitialized = false; if (InternetHandle != NULL) { // Clear the callback if still set InternetSetStatusCallback(InternetHandle, NULL); // shut down WinINet if (!InternetCloseHandle(InternetHandle)) { UE_LOG(LogHttp, Warning, TEXT("InternetCloseHandle failed on the FHttpRequestWinInet: %s"), *InternetTranslateError(GetLastError())); return false; } InternetHandle = NULL; } } return true; }
CBHttpRequest::CBHttpRequest(void) : m_hConnection(NULL), m_hFile(NULL), m_nReadyState(0), m_dwDataAvailable(0), m_uulTotalBytes(0), m_dwStatus(0), m_eventComplete(TRUE), m_dwReqID(0), m_dwFlags(INTERNET_FLAG_RELOAD | INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS) { if(m_hSession == NULL) { DWORD dataSize; HKEY hKey; LONG result; dataSize = sizeof(strUserAgent); result = ::RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 0, KEY_QUERY_VALUE, &hKey); if(result == ERROR_SUCCESS) { result = ::RegQueryValueEx(hKey, "User Agent", NULL, NULL,(LPBYTE) strUserAgent, &dataSize); RegCloseKey(hKey); } m_hSession = InternetOpen(strUserAgent, PRE_CONFIG_INTERNET_ACCESS, NULL, NULL, INTERNET_FLAG_ASYNC); InternetSetStatusCallback(m_hSession, (INTERNET_STATUS_CALLBACK)&staticStatusCallback); } }
static inline HINTERNET createInternetHandle(const String& userAgent, bool asynchronous) { String userAgentString = userAgent; HINTERNET internetHandle = InternetOpenW(userAgentString.charactersWithNullTermination(), INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, asynchronous ? INTERNET_FLAG_ASYNC : 0); if (asynchronous) InternetSetStatusCallback(internetHandle, &ResourceHandle::internetStatusCallback); return internetHandle; }
bool FWinInetConnection::InitConnection() { // Make sure previous connection is closed ShutdownConnection(); UE_LOG(LogHttp, Log, TEXT("Initializing WinInet connection")); // Check and log the connected state so we can report early errors. ::DWORD ConnectedFlags; BOOL bConnected = InternetGetConnectedState(&ConnectedFlags, 0); FString ConnectionType; ConnectionType += (ConnectedFlags & INTERNET_CONNECTION_CONFIGURED) ? TEXT("Configured ") : TEXT(""); ConnectionType += (ConnectedFlags & INTERNET_CONNECTION_LAN) ? TEXT("LAN ") : TEXT(""); ConnectionType += (ConnectedFlags & INTERNET_CONNECTION_MODEM) ? TEXT("Modem ") : TEXT(""); ConnectionType += (ConnectedFlags & INTERNET_CONNECTION_MODEM_BUSY) ? TEXT("Modem Busy ") : TEXT(""); ConnectionType += (ConnectedFlags & INTERNET_CONNECTION_OFFLINE) ? TEXT("Offline ") : TEXT(""); ConnectionType += (ConnectedFlags & INTERNET_CONNECTION_PROXY) ? TEXT("Proxy Server ") : TEXT(""); ConnectionType += (ConnectedFlags & INTERNET_RAS_INSTALLED) ? TEXT("RAS Installed ") : TEXT(""); UE_LOG(LogHttp, Log, TEXT("Connected State: %s. Flags: (%s)"), bConnected ? TEXT("Good") : TEXT("Bad"), *ConnectionType); if (InternetAttemptConnect(0) != ERROR_SUCCESS) { UE_LOG(LogHttp, Warning, TEXT("InternetAttemptConnect failed: %s\n"), *InternetTranslateError(GetLastError())); return false; } // setup net connection InternetHandle = InternetOpen( *FString::Printf(TEXT("game=%s, engine=UE4, version=%d"), FApp::GetGameName(), GEngineNetVersion), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC); if (InternetHandle == NULL) { UE_LOG(LogHttp, Warning, TEXT("Failed WinHttpOpen: %s"), *InternetTranslateError(GetLastError())); return false; } { FScopeLock ScopeLock(&FHttpManager::RequestLock); bStaticConnectionInitialized = true; } // Register callback to update based on WinInet connection state InternetSetStatusCallback(InternetHandle, InternetStatusCallbackWinInet); return true; }
CMyAsyncHttp::~CMyAsyncHttp() { CMyDebug::Log(TAG,2,0,"~CMyAsyncHttp"); if(m_HttpState!=HTTP_STOP&&m_HttpState!=HTTP_FINISH) { //在析构前停止未完成的请求 TerminateHttp(); } if(m_Session) { InternetSetStatusCallback(m_Session,(INTERNET_STATUS_CALLBACK)NULL); ::InternetCloseHandle(m_Session); } if(m_SelfThread.isRun()) m_SelfThread.ExitThreadDirect(); }
/* initialize private data */ static BOOL wininet_init( struct soap * soap, struct wininet_data * a_pData, DWORD a_dwRequestFlags ) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "wininet %p: init private data\n", soap )); memset( a_pData, 0, sizeof(struct wininet_data) ); a_pData->dwRequestFlags = a_dwRequestFlags; /* start our internet session */ a_pData->hInternet = InternetOpenA( "gSOAP", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 ); if ( !a_pData->hInternet ) { soap->error = GetLastError(); DBGLOG(TEST, SOAP_MESSAGE(fdebug, "wininet %p: init, error %d (%s) in InternetOpen\n", soap, soap->error, wininet_error_message(soap,soap->error) )); wininet_free_error_message( a_pData ); return FALSE; } /* set the timeouts, if any of these fail the error isn't fatal */ wininet_set_timeout( soap, a_pData, "connect", INTERNET_OPTION_CONNECT_TIMEOUT, soap->connect_timeout ); wininet_set_timeout( soap, a_pData, "receive", INTERNET_OPTION_RECEIVE_TIMEOUT, soap->recv_timeout ); wininet_set_timeout( soap, a_pData, "send", INTERNET_OPTION_SEND_TIMEOUT, soap->send_timeout ); /* set up the callback function so we get notifications */ InternetSetStatusCallback( a_pData->hInternet, wininet_callback ); /* set all of our callbacks */ soap->fopen = wininet_connect; soap->fposthdr = wininet_post_header; soap->fsend = wininet_fsend; soap->frecv = wininet_frecv; soap->fclose = wininet_disconnect; return TRUE; }
// // Checks if the Internet status callback set not by us and replaces it by our own function. // BOOL SetCallback( HANDLE hRequest, PHANDLE_CONTEXT Ctx ) { BOOL Ret = FALSE; PVOID Callback = NULL; ULONG cLen = sizeof(PVOID); if (InternetQueryOption(hRequest, INTERNET_OPTION_CALLBACK, &Callback, &cLen)) { if (Callback != &my_InternetStatusCallback) { Ctx->Callback = Callback; ASSERT((LONG_PTR)Ctx->Callback >= 0); // User-mode address if (InternetSetStatusCallback(hRequest, &my_InternetStatusCallback) == Callback) Ret = TRUE; } } return(Ret); }
CMyAsyncHttp::CMyAsyncHttp() { m_TaskThread =NULL; m_ThreadPool =NULL; m_TimeOut =MAX_WAIT_TIME; m_TaskArg.iAcceptType =&m_AcceptType; m_TaskArg.iCharset =&m_Charset; m_TaskArg.iEncode =&m_Encode; m_TaskArg.iHttpHeader =&m_HttpHeader; m_TaskArg.iHttpState =&m_HttpState; m_TaskArg.iPassword =&m_Password; m_TaskArg.iUserName =&m_UserName; m_TaskArg.iRefer =&m_Refer; m_TaskArg.iPath =&m_Path; m_TaskArg.iUrl =&m_Url; m_TaskArg.iVerb =&m_Verb; m_TaskArg.iTaskRunTarget1 =&m_TaskThread; m_TaskArg.iTaskRunTarget2 =&m_ThreadPool; m_TaskArg.iConnect =&m_Connect; m_TaskArg.iExtraData =&m_ExtraData; m_TaskArg.iFinishNotify =&m_FinishNotify; m_TaskArg.iHttp =&m_Http; m_TaskArg.iIOStream =&m_Data; m_TaskArg.iNotifyEvent =&m_Notify; m_TaskArg.iSession =&m_Session; m_TaskArg.iStatusCode =&m_StatusCode; m_TaskArg.iStreamLen =&m_DataLen; m_TaskArg.iTerminateEvent =&m_TerminateEvent; m_TaskArg.iTaskList[0] =&m_ORequestTask; m_TaskArg.iTaskList[1] =&m_SRequestTask; m_TaskArg.iTaskList[2] =&m_ReadResponseTask; m_TaskArg.iTimeOut =&m_TimeOut; m_TaskArg.iAssignTaskThread =&m_AssignTaskThread; m_TaskArg.iAsyncResult =0; m_TerminateEvent =CreateEvent(false,false,NULL); m_Notify =CreateEvent(false,false,NULL); m_FinishNotify =CreateEvent(false,false,NULL); m_AssignTaskThread =false; if(m_Mutex) m_Mutex =CreateMutex(false,NULL); m_HttpState =HTTP_FINISH; m_Session=::InternetOpen("Async_Http",PRE_CONFIG_INTERNET_ACCESS, NULL,INTERNET_INVALID_PORT_NUMBER,INTERNET_FLAG_ASYNC); #ifdef _DEBUG if(!m_Session) LOG(TAG,"Open Internet failed!"); #endif // CSetCallBackThread callbackThread; // callbackThread.Start((void*)m_Session); // WaitForSingleObject(callbackThread.GetThreadHandle(),-1); if(INTERNET_INVALID_STATUS_CALLBACK== InternetSetStatusCallback(m_Session,(INTERNET_STATUS_CALLBACK)Callback)) // if(INTERNET_INVALID_STATUS_CALLBACK==(INTERNET_STATUS_CALLBACK)callbackThread.GetRunValue()) { #ifdef _DEBUG LOG(TAG,"InternetSetStatusCallback failed"); #endif } }
UINT APIENTRY CXMLHttpRequest::SendThread(void *pParm) { ATLTRACE(_T("CXMLHttpRequest::SendThread\n")); CXMLHttpRequest *pCtx = reinterpret_cast<CXMLHttpRequest *> (pParm); if (NULL == pCtx) return 0; HINTERNET hOpen = NULL; HINTERNET hConnect = NULL; HINTERNET hRequest = NULL; hOpen = InternetOpen(_T("XMLHTTP/1.0"),INTERNET_OPEN_TYPE_PRECONFIG, NULL,NULL,0); if (NULL == hOpen) { DWORD res = GetLastError(); pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); pCtx->m_bSuccess = false; } if (!pCtx->m_bAbort && pCtx->m_bSuccess) { if (INTERNET_INVALID_STATUS_CALLBACK == InternetSetStatusCallback(hOpen, CXMLHttpRequest::InternetStatusCallback)) { pCtx->m_Error = _T("Invalid Internet Status Callback function."); pCtx->m_bSuccess = false; } } bool bPromptForAuthentication = true; if (!pCtx->m_bAbort && pCtx->m_bSuccess) { LPTSTR lpszUserName = NULL; LPTSTR lpszPassword = NULL; if (pCtx->m_User.length() > 0) { bPromptForAuthentication = false; lpszUserName = pCtx->m_User; if (pCtx->m_Password.length() > 0) lpszPassword = pCtx->m_Password; } hConnect = InternetConnect(hOpen,pCtx->m_HostName,pCtx->m_Port,lpszUserName,lpszPassword, INTERNET_SERVICE_HTTP,0,reinterpret_cast<DWORD> (pCtx)); if (NULL == hConnect) { DWORD res = GetLastError(); pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); pCtx->m_bSuccess = false; } } if (!pCtx->m_bAbort && pCtx->m_bSuccess) { DWORD dwFlags = (443 == pCtx->m_Port) ? INTERNET_FLAG_SECURE : 0; dwFlags |= INTERNET_FLAG_NO_CACHE_WRITE; hRequest = HttpOpenRequest(hConnect,pCtx->m_Method, pCtx->m_URLPath,NULL,NULL,NULL, dwFlags,reinterpret_cast<DWORD> (pCtx)); if (NULL == hRequest) { DWORD res = GetLastError(); pCtx->m_bSuccess = false; pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); } } BOOL rc = TRUE; if (!pCtx->m_bAbort && pCtx->m_bSuccess && pCtx->m_RequestHeaderMap.GetSize() > 0) { _bstr_t requestHeaders; for (int i = 0 ; i < pCtx->m_RequestHeaderMap.GetSize(); ++i) { requestHeaders += pCtx->m_RequestHeaderMap.GetKeyAt(i); requestHeaders += _T(": "); requestHeaders += pCtx->m_RequestHeaderMap.GetValueAt(i); requestHeaders += _T("\r\n"); } rc = HttpAddRequestHeaders(hRequest,requestHeaders,-1,HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); if (!rc) { DWORD res = GetLastError(); pCtx->m_bSuccess = false; pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); } } DWORD dwLen = 0; DWORD dwError = ERROR_SUCCESS; do { if (!pCtx->m_bAbort && pCtx->m_bSuccess) { rc = HttpSendRequest(hRequest,NULL,0,pCtx->m_pBody,pCtx->m_lBodyLength); if (!rc) { DWORD res = GetLastError(); pCtx->m_bSuccess = false; pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); break; } } if (!pCtx->m_bAbort && pCtx->m_bSuccess) { dwLen = sizeof(DWORD); rc = HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &pCtx->m_dwStatus,&dwLen,NULL); if (!rc) { DWORD res = GetLastError(); pCtx->m_bSuccess = false; pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); break; } } if (!pCtx->m_bAbort && pCtx->m_bSuccess && bPromptForAuthentication && (HTTP_STATUS_PROXY_AUTH_REQ == pCtx->m_dwStatus || HTTP_STATUS_DENIED == pCtx->m_dwStatus)) dwError = InternetErrorDlg(pCtx->m_HwndParent, hRequest, ERROR_INTERNET_INCORRECT_PASSWORD, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA, NULL); else break; } while (ERROR_INTERNET_FORCE_RETRY == dwError && !pCtx->m_bAbort && pCtx->m_bSuccess); if (!pCtx->m_bAbort && pCtx->m_bSuccess) { dwLen = 1024; TCHAR *pBuff = new TCHAR[dwLen]; rc = HttpQueryInfo(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF,pBuff,&dwLen,NULL); if (!rc) { DWORD res = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == res) { delete [] pBuff; pBuff = new TCHAR[dwLen]; rc = HttpQueryInfo(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF,pBuff,&dwLen,NULL); if (!rc) { res = GetLastError(); pCtx->m_bSuccess = false; pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); } } else { pCtx->m_bSuccess = false; pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); } } if (rc) pCtx->m_ResponseHeaders = pBuff; delete [] pBuff; } if (!pCtx->m_bAbort && pCtx->m_bSuccess) { dwLen = 1024; TCHAR *pBuff = new TCHAR[dwLen]; rc = HttpQueryInfo(hRequest,HTTP_QUERY_STATUS_TEXT,pBuff,&dwLen,NULL); if (!rc) { DWORD res = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == res) { delete [] pBuff; pBuff = new TCHAR[dwLen]; rc = HttpQueryInfo(hRequest,HTTP_QUERY_STATUS_TEXT,pBuff,&dwLen,NULL); if (!rc) _tcscpy(pBuff,_T("Unknown")); } else _tcscpy(pBuff,_T("Unknown")); } pCtx->m_StatusText = pBuff; delete [] pBuff; if (HTTP_STATUS_OK != pCtx->m_dwStatus) { TCHAR errBuff[MAX_PATH] = _T(""); wsprintf(errBuff,_T("HTTP Status Code: %d, Reason: "),pCtx->m_dwStatus); pCtx->m_Error = errBuff; pCtx->m_Error += pCtx->m_StatusText; pCtx->m_bSuccess = false; } } if (!pCtx->m_bAbort && pCtx->m_bSuccess) { PBYTE buffer[255]; DWORD dwRead = 0; delete [] pCtx->m_pResponseBody; pCtx->m_pResponseBody = NULL; pCtx->m_lResponseBodyLength = 0; while (rc = InternetReadFile(hRequest,buffer,255,&dwRead)) { if (!rc || pCtx->m_bAbort || 0 == dwRead) break; PBYTE tmp = new BYTE[pCtx->m_lResponseBodyLength + dwRead]; if (pCtx->m_pResponseBody) { memcpy(tmp,pCtx->m_pResponseBody,pCtx->m_lResponseBodyLength); delete [] pCtx->m_pResponseBody; } memcpy(tmp+pCtx->m_lResponseBodyLength,buffer,dwRead); pCtx->m_pResponseBody = tmp; pCtx->m_lResponseBodyLength += dwRead; } if (!rc) { DWORD res = GetLastError(); pCtx->m_Error = _T("Error reading response: ") + CXMLHttpRequest::GetErrorMsg(res); pCtx->m_bSuccess = false; } } if (hRequest != NULL) InternetCloseHandle(hRequest); if (hConnect != NULL) InternetCloseHandle(hConnect); if (hOpen) InternetCloseHandle(hOpen); if (!pCtx->m_bAbort && pCtx->m_bAsync) ::PostMessage(pCtx->m_hWnd,MSG_READY_STATE_CHANGE,4,0); return 0; }
bool ResourceHandle::start(Frame* frame) { ref(); if (url().isLocalFile()) { String path = url().path(); // windows does not enjoy a leading slash on paths if (path[0] == '/') path = path.substring(1); // FIXME: This is wrong. Need to use wide version of this call. d->m_fileHandle = CreateFileA(path.utf8().data(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // FIXME: perhaps this error should be reported asynchronously for // consistency. if (d->m_fileHandle == INVALID_HANDLE_VALUE) { delete this; return false; } d->m_fileLoadTimer.startOneShot(0.0); return true; } else { static HINTERNET internetHandle = 0; if (!internetHandle) { String userAgentStr = frame->loader()->userAgent() + String("", 1); LPCWSTR userAgent = reinterpret_cast<const WCHAR*>(userAgentStr.characters()); // leak the Internet for now internetHandle = InternetOpen(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, INTERNET_FLAG_ASYNC); } if (!internetHandle) { delete this; return false; } static INTERNET_STATUS_CALLBACK callbackHandle = InternetSetStatusCallback(internetHandle, transferJobStatusCallback); initializeOffScreenResourceHandleWindow(); d->m_jobId = addToOutstandingJobs(this); DWORD flags = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP; // For form posting, we can't use InternetOpenURL. We have to use // InternetConnect followed by HttpSendRequest. HINTERNET urlHandle; String referrer = frame->loader()->referrer(); if (method() == "POST") { d->m_postReferrer = referrer; String host = url().host(); urlHandle = InternetConnectA(internetHandle, host.latin1().data(), url().port(), NULL, // no username NULL, // no password INTERNET_SERVICE_HTTP, flags, (DWORD_PTR)d->m_jobId); } else { String urlStr = url().string(); int fragmentIndex = urlStr.find('#'); if (fragmentIndex != -1) urlStr = urlStr.left(fragmentIndex); String headers; if (!referrer.isEmpty()) headers += String("Referer: ") + referrer + "\r\n"; urlHandle = InternetOpenUrlA(internetHandle, urlStr.latin1().data(), headers.latin1().data(), headers.length(), flags, (DWORD_PTR)d->m_jobId); } if (urlHandle == INVALID_HANDLE_VALUE) { delete this; return false; } d->m_threadId = GetCurrentThreadId(); return true; } }
DWORD CALLBACK TaskThreadProc(LPVOID ThreadParam) { NSIS::stack_t *pURL,*pFile; HINTERNET hInetSes = NULL, hInetFile = NULL; DWORD cbio = sizeof(DWORD); HANDLE hLocalFile; bool completedFile = false; startnexttask: hLocalFile = INVALID_HANDLE_VALUE; pFile = NULL; TaskLock_AcquireExclusive(); // Now that we've acquired the lock, we can set the event to indicate this. // SetEvent will likely never fail, but if it does we should set it to NULL // to avoid anyone waiting on it. if (!SetEvent(g_hGETStartedEvent)) { CloseHandle(g_hGETStartedEvent); g_hGETStartedEvent = NULL; } pURL = g_pLocations; if (pURL) { pFile = pURL->next; g_pLocations = pFile->next; } #ifndef ONELOCKTORULETHEMALL StatsLock_AcquireExclusive(); #endif if (completedFile) { ++g_FilesCompleted; } completedFile = false; g_cbCurrXF = 0; g_cbCurrTot = FILESIZE_UNKNOWN; if (!pURL) { if (g_FilesTotal) { if (g_FilesTotal == g_FilesCompleted) { g_Status = STATUS_COMPLETEDALL; } } g_hThread = NULL; } #ifndef ONELOCKTORULETHEMALL StatsLock_ReleaseExclusive(); #endif TaskLock_ReleaseExclusive(); if (!pURL) { if (0) { diegle: DWORD gle = GetLastError(); //TODO? if (ERROR_INTERNET_EXTENDED_ERROR==gle) InternetGetLastResponseInfo(...) g_Status = STATUS_ERR_GETLASTERROR; } if (hInetSes) { InternetCloseHandle(hInetSes); } if (INVALID_HANDLE_VALUE != hLocalFile) { CloseHandle(hLocalFile); } StackFreeItem(pURL); StackFreeItem(pFile); return 0; } if (!hInetSes) { hInetSes = InternetOpen(USERAGENT, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (!hInetSes) { TRACE(_T("InetBgDl: InternetOpen failed with gle=%u\n"), GetLastError()); goto diegle; } InternetSetStatusCallback(hInetSes, (INTERNET_STATUS_CALLBACK)InetStatusCallback); //msdn.microsoft.com/library/default.asp?url=/workshop/components/offline/offline.asp#Supporting Offline Browsing in Applications and Components ULONG longOpt; DWORD cbio = sizeof(ULONG); if (InternetQueryOption(hInetSes, INTERNET_OPTION_CONNECTED_STATE, &longOpt, &cbio)) { if (INTERNET_STATE_DISCONNECTED_BY_USER&longOpt) { INTERNET_CONNECTED_INFO ci = {INTERNET_STATE_CONNECTED, 0}; InternetSetOption(hInetSes, INTERNET_OPTION_CONNECTED_STATE, &ci, sizeof(ci)); } } // Change the default connect timeout if specified. if(g_ConnectTimeout > 0) { InternetSetOption(hInetSes, INTERNET_OPTION_CONNECT_TIMEOUT, &g_ConnectTimeout, sizeof(g_ConnectTimeout)); } // Change the default receive timeout if specified. if (g_ReceiveTimeout) { InternetSetOption(hInetSes, INTERNET_OPTION_RECEIVE_TIMEOUT, &g_ReceiveTimeout, sizeof(DWORD)); } } DWORD ec = ERROR_SUCCESS; hLocalFile = CreateFile(pFile->text, GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_DELETE,NULL,CREATE_ALWAYS, 0, NULL); if (INVALID_HANDLE_VALUE == hLocalFile) { TRACE(_T("InetBgDl: CreateFile file handle invalid\n")); goto diegle; } const DWORD IOURedirFlags = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS; const DWORD IOUCacheFlags = INTERNET_FLAG_RESYNCHRONIZE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD; const DWORD IOUCookieFlags = INTERNET_FLAG_NO_COOKIES; DWORD IOUFlags = IOURedirFlags | IOUCacheFlags | IOUCookieFlags | INTERNET_FLAG_NO_UI | INTERNET_FLAG_EXISTING_CONNECT; TCHAR *hostname = (TCHAR*) GlobalAlloc(GPTR, MAX_STRLEN * sizeof(TCHAR)), *urlpath = (TCHAR*) GlobalAlloc(GPTR, MAX_STRLEN * sizeof(TCHAR)), *extrainfo = (TCHAR*) GlobalAlloc(GPTR, MAX_STRLEN * sizeof(TCHAR)); URL_COMPONENTS uc = { sizeof(URL_COMPONENTS), NULL, 0, (INTERNET_SCHEME)0, hostname, MAX_STRLEN, (INTERNET_PORT)0, NULL, 0, NULL, 0, urlpath, MAX_STRLEN, extrainfo, MAX_STRLEN}; uc.dwHostNameLength = uc.dwUrlPathLength = uc.dwExtraInfoLength = MAX_STRLEN; if (!InternetCrackUrl(pURL->text, 0, ICU_ESCAPE, &uc)) { // Bad url or param passed in TRACE(_T("InetBgDl: InternetCrackUrl false with url=%s, gle=%u\n"), pURL->text, GetLastError()); goto diegle; } TRACE(_T("InetBgDl: scheme_id=%d, hostname=%s, port=%d, urlpath=%s, extrainfo=%s\n"), uc.nScheme, hostname, uc.nPort, urlpath, extrainfo); // Only http and https are supported if (uc.nScheme != INTERNET_SCHEME_HTTP && uc.nScheme != INTERNET_SCHEME_HTTPS) { TRACE(_T("InetBgDl: only http and https is supported, aborting...\n")); goto diegle; } TRACE(_T("InetBgDl: calling InternetOpenUrl with url=%s\n"), pURL->text); hInetFile = InternetOpenUrl(hInetSes, pURL->text, NULL, 0, IOUFlags | (uc.nScheme == INTERNET_SCHEME_HTTPS ? INTERNET_FLAG_SECURE : 0), 1); if (!hInetFile) { TRACE(_T("InetBgDl: InternetOpenUrl failed with gle=%u\n"), GetLastError()); goto diegle; } // Get the file length via the Content-Length header FILESIZE_T cbThisFile; cbio = sizeof(cbThisFile); if (!HttpQueryInfo(hInetFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &cbThisFile, &cbio, NULL)) { cbThisFile = FILESIZE_UNKNOWN; } TRACE(_T("InetBgDl: file size=%d bytes\n"), cbThisFile); // Setup a buffer of size 256KiB to store the downloaded data. const UINT cbBufXF = 262144; // Use a 4MiB read buffer for the connection. // Bigger buffers will be faster. // cbReadBufXF should be a multiple of cbBufXF. const UINT cbReadBufXF = 4194304; BYTE bufXF[cbBufXF]; // Up the default internal buffer size from 4096 to internalReadBufferSize. DWORD internalReadBufferSize = cbReadBufXF; if (!InternetSetOption(hInetFile, INTERNET_OPTION_READ_BUFFER_SIZE, &internalReadBufferSize, sizeof(DWORD))) { TRACE(_T("InetBgDl: InternetSetOption failed to set read buffer size to %u bytes, gle=%u\n"), internalReadBufferSize, GetLastError()); // Maybe it's too big, try half of the optimal value. If that fails just // use the default. internalReadBufferSize /= 2; if (!InternetSetOption(hInetFile, INTERNET_OPTION_READ_BUFFER_SIZE, &internalReadBufferSize, sizeof(DWORD))) { TRACE(_T("InetBgDl: InternetSetOption failed to set read buffer size ") \ _T("to %u bytes (using default read buffer size), gle=%u\n"), internalReadBufferSize, GetLastError()); } } for(;;) { DWORD cbio = 0, cbXF = 0; BOOL retXF = InternetReadFile(hInetFile, bufXF, cbBufXF, &cbio); if (!retXF) { ec = GetLastError(); TRACE(_T("InetBgDl: InternetReadFile failed, gle=%u\n"), ec); break; } if (0 == cbio) { ASSERT(ERROR_SUCCESS == ec); // EOF or broken connection? // TODO: Can InternetQueryDataAvailable detect this? TRACE(_T("InetBgDl: InternetReadFile true with 0 cbio, cbThisFile=%d, gle=%u\n"), cbThisFile, GetLastError()); // If we haven't transferred all of the file, and we know how big the file // is, and we have no more data to read from the HTTP request, then set a // broken pipe error. Reading without StatsLock is ok in this thread. if (FILESIZE_UNKNOWN != cbThisFile && g_cbCurrXF != cbThisFile) { TRACE(_T("InetBgDl: downloaded file size of %d bytes doesn't equal ") \ _T("expected file size of %d bytes\n"), g_cbCurrXF, cbThisFile); ec = ERROR_BROKEN_PIPE; } break; } // Check if we canceled the download if (0 == g_FilesTotal) { TRACE(_T("InetBgDl: 0 == g_FilesTotal, aborting transfer loop...\n")); ec = ERROR_CANCELLED; break; } cbXF = cbio; if (cbXF) { retXF = WriteFile(hLocalFile, bufXF, cbXF, &cbio, NULL); if (!retXF || cbXF != cbio) { ec = GetLastError(); break; } StatsLock_AcquireExclusive(); if (FILESIZE_UNKNOWN != cbThisFile) { g_cbCurrTot = cbThisFile; } g_cbCurrXF += cbXF; StatsLock_ReleaseExclusive(); } } TRACE(_T("InetBgDl: TaskThreadProc completed %s, ec=%u\n"), pURL->text, ec); InternetCloseHandle(hInetFile); if (ERROR_SUCCESS == ec) { if (INVALID_HANDLE_VALUE != hLocalFile) { CloseHandle(hLocalFile); hLocalFile = INVALID_HANDLE_VALUE; } StackFreeItem(pURL); StackFreeItem(pFile); ++completedFile; } else { TRACE(_T("InetBgDl: failed with ec=%u\n"), ec); SetLastError(ec); goto diegle; } goto startnexttask; }
HippoHTTP::HippoHTTP(void) { inetHandle_ = InternetOpen(L"Mugshot Client/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC); InternetSetStatusCallback(inetHandle_, asyncStatusUpdate); }
HRESULT CHttpDownloader::ConnectToServer(_bstr_t &strBuffer) { BOOL bResult; DWORD dwStatus; DWORD nTimeoutCounter; _bstr_t strMethod; _bstr_t strUrl = m_request.url; LPCTSTR szProxyName = NULL; if(m_ProxyType == INTERNET_OPEN_TYPE_PROXY) szProxyName = m_ProxyName; //// InternetOpen \\\\ if(!m_hInternet) m_hInternet = InternetOpen(_T("McHttpDownloader"), m_ProxyType, szProxyName, NULL, INTERNET_FLAG_ASYNC); if(!m_hInternet) { strBuffer = _T("InternetOpen failed"); return E_FAIL; } InternetSetStatusCallback(m_hInternet, (INTERNET_STATUS_CALLBACK)CallbackFunc); //// InternetOpen //// if(m_longAbort > 0) return E_ABORT; //// InternetConnect \\\\ if(!m_hConnect) { m_hConnect = InternetConnect(m_hInternet, m_request.server, (short)m_request.port, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, (DWORD)&m_context); } if(m_hConnect == NULL) { strBuffer = _T("InternetConnect failed"); return INET_E_CANNOT_CONNECT; } //// InternetConnect //// nTimeoutCounter = 0; NewConnect: strMethod = _T("GET"); strBuffer = _T(""); //// OpenRequest \\\\ if(m_hRequest) { ::InternetCloseHandle(m_hRequest); m_hRequest = NULL; } if(m_longAbort > 0) return E_ABORT; DWORD dwFlags = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_NO_AUTO_REDIRECT | INTERNET_FLAG_HYPERLINK | (m_request.bUseSSL ? (INTERNET_FLAG_SECURE/*| INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS| INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP*/) : 0); m_context.op = HTTP_DOWNLOADER_OP_OPEN_REQUEST; m_hRequest = HttpOpenRequest(m_hConnect, strMethod, strUrl, _T("HTTP/1.1"), NULL, NULL, dwFlags, (DWORD)&m_context); if(m_hRequest == NULL) { strBuffer = _T("HttpOpenRequest failed"); return E_FAIL; } if(m_ProxyType == INTERNET_OPEN_TYPE_PROXY) { if(GetOptionInt(IDS_NETOPTIONS,IDS_USEFIREWALL,0)) { CString fireWallUser = GetOptionString(IDS_NETOPTIONS, IDS_FIREWALLUSER, _T("")); CString fireWallPass = GetOptionString(IDS_NETOPTIONS, IDS_FIREWALLPASS, _T("")); ////////////////////////////////////////////////////////////////////////// int HeaderLen = ATL::ProxyAuthorizationStringGetRequiredLength(fireWallUser, fireWallPass); LPTSTR strHeader = new TCHAR[HeaderLen+1]; ZeroMemory(strHeader,HeaderLen+1); HRESULT hr = ATL::ProxyAuthorizationString(fireWallUser, fireWallPass, strHeader, &HeaderLen); ASSERT(hr==S_OK); HttpAddRequestHeaders(m_hRequest, strHeader, HeaderLen, HTTP_ADDREQ_FLAG_ADD ); delete []strHeader; ////////////////////////////////////////////////////////////////////////// } } //// OpenRequest //// NewRequest: if(m_longAbort > 0) return E_ABORT; m_context.op = HTTP_DOWNLOADER_OP_SEND_REQUEST; bResult = HttpSendRequest(m_hRequest, NULL , 0, (LPVOID)(BYTE*)(LPCTSTR)strBuffer, lstrlen(strBuffer)); if(!bResult && 997 == GetLastError()) // Overlapped I/O operation is in progress. bResult = WaitForComplete(m_dwTimeout); // Resolve host name, connect, send request, receive response. if(!bResult) { DWORD dwErrCode = GetLastError(); // ATLTRACE("Send Request error = %d \r\n",dwErrCode); if(dwErrCode == 6) // The handle is invalid. goto NewConnect; if(dwErrCode == ERROR_INTERNET_TIMEOUT) // timeout { if(++nTimeoutCounter < m_dwConnectRetryCount) goto NewConnect; else { strBuffer = _T("Timeout"); return E_FAIL;//INET_E_CONNECTION_TIMEOUT; } } strBuffer = _T("SendRequest failed"); return E_FAIL; } dwStatus = GetHttpStatus(); if(dwStatus == 401 || dwStatus == 407) // Denied or Proxy asks password { if(ERROR_INTERNET_FORCE_RETRY == InternetErrorDlg(GetDesktopWindow(), m_hRequest, ERROR_INTERNET_INCORRECT_PASSWORD, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA, NULL)) { goto NewRequest; } } if(dwStatus != 200) // Not OK { strBuffer = _T("SendRequest returned with error"); return INET_E_CANNOT_CONNECT; } return S_OK; }