//--------------------------------------------------------------------------- #include #include #include #include #include //#include #pragma hdrstop #include "HttpThread.h" #include "GlobalUnit.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma comment(lib, "wininet") //--------------------------------------------------------------------------- DWORD WINAPI HttpProc(LPVOID args) { THttpParam* param = (THttpParam*)args; TCHAR hdrsStream[] = _T("Content-Type: application/octet-stream\r\n"), hdrsXForm[] = _T("Content-Type: application/x-www-form-urlencoded\r\n"), *hdrs = param->iMode==0 ? hdrsStream : hdrsXForm; LPCTSTR lpszAccept[] = { _T("text/html"), NULL };//{ _T("application/json"), NULL };// char szBuffer[1024]; DWORD dwFlags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, dwByteRead = 0, dwAllBytes = 0, dwSize = 4; int pos = 0; bool bSent = false; // char srvAddr[256]; //Open internet connection param->hSession = InternetOpen( L"HttpPost/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 ); if( !param->hSession ){ param->errCode = ERROR_INTERNET_OPEN; return 0; } char addr[80]; int port = 80; char* p = strstr( param->server, ":" ); if( p ){ memcpy( addr, param->server, p - param->server ); addr[p - param->server] = 0; sscanf( p+1, "%d", &port ); } else strcpy( addr, param->server ); param->hConnect = InternetConnect(param->hSession, (String(addr)).w_str(), port,//INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1); if( param->hConnect ){ if( port==INTERNET_DEFAULT_HTTPS_PORT ) dwFlags |= INTERNET_FLAG_SECURE; param->hRequest = HttpOpenRequest(param->hConnect, _T("POST"), ((String)param->api).c_str(), NULL, NULL, NULL,//lpszAccept,// dwFlags, 1); if( param->hRequest ){ if( port==INTERNET_DEFAULT_HTTPS_PORT ){ DWORD flags = 0; DWORD bufflen = sizeof(flags); InternetQueryOption(param->hRequest, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&flags, &bufflen); flags |= SECURITY_FLAG_IGNORE_REVOCATION; InternetSetOption(param->hRequest, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&flags, sizeof(flags)); } if( HttpSendRequest( param->hRequest, hdrs, wcslen(hdrs), param->dataIn, param->sizeIn) ){ bSent = true; } else{ param->errCode = GetLastError(); } } else{ param->errCode = GetLastError(); } } else{ param->errCode = GetLastError(); } if( !param->hConnect ){ param->errCode = ERROR_INTERNET_CONN; return 0; } if( !param->hRequest ){ param->errCode = ERROR_INTERNET_REQ; return 0; } if( !bSent ){ param->errCode = ERROR_INTERNET_SEND; return 0; } // if( param->bGetDT ){ // SYSTEMTIME sysTime; // SecureZeroMemory(&sysTime, sizeof(SYSTEMTIME)); // DWORD dwSize = sizeof(SYSTEMTIME); // if( HttpQueryInfo( param->hRequest, HTTP_QUERY_DATE|HTTP_QUERY_FLAG_SYSTEMTIME, // &sysTime, &dwSize, NULL ) ){ // TDateTime dt = SystemTimeToDateTime(sysTime); // param->dwDateTime = DateTimeToUnix(dt); // } // else // param->dwDateTime = 0; // } if( !HttpQueryInfo( param->hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, &dwAllBytes, &dwSize, NULL ) ){ dwAllBytes = 0; } // 防止乱码的方法就是建立完变量立即清空 ZeroMemory(szBuffer, sizeof(szBuffer)); ZeroMemory(param->dataOut, param->sizeOut); // 循环读取缓冲区内容直到结束 while( param->hRequest && InternetReadFile(param->hRequest, szBuffer, sizeof(szBuffer), &dwByteRead) && dwByteRead > 0 ){ if( pos + dwByteRead > param->sizeOut ){ param->errCode = ERROR_SIZE; return 0; } // 复制输出数据 memcpy( param->dataOut+pos, szBuffer, dwByteRead ); pos += dwByteRead; // 清空缓冲区以备下一次读取 ZeroMemory(szBuffer, sizeof(szBuffer)); } if( !param->hRequest ){ param->errCode = ERROR_INTERNET_REQ; } else if( dwAllBytes>0 && pos!=dwAllBytes ){ param->errCode = ERROR_SIZE; } else{ param->dataOut[pos] = 0; param->sizeOut = pos; } return 0; } //--------------------------------------------------------------------------- DWORD WINAPI VeloProc(LPVOID args) { TVeloParam* param = (TVeloParam*)args; TCHAR hdrs[] = _T("Content-Type: application/x-www-form-urlencoded\r\n"); // TCHAR hdrs[] = _T("Content-Type: text/html\r\n"); LPCTSTR lpszAccept[] = { _T("*/*"), NULL }; // char srvAddr[256]; //Open internet connection param->hSession = InternetOpen(L"Velocity",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if( !param->hSession ){ param->errCode = ERROR_INTERNET_OPEN; return 0; } param->hConnect = InternetConnect(param->hSession, (String(param->addr)).w_str(), param->port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); if( !param->hConnect ){ param->errCode = ERROR_INTERNET_CONN; return 0; } param->hRequest = HttpOpenRequest(param->hConnect, _T("GET"), ((String)param->api).c_str(), _T("HTTP/1.1"), NULL, NULL,//lpszAccept, param->flag, 0); if( !param->hRequest ){ //param->errCode = ERROR_INTERNET_REQ; return 0; } if( param->port==INTERNET_DEFAULT_HTTPS_PORT ){ DWORD flags = 0; DWORD bufflen = sizeof(flags); InternetQueryOption(param->hRequest, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&flags, &bufflen); flags |= SECURITY_FLAG_IGNORE_REVOCATION | SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_CN_INVALID; InternetSetOption(param->hRequest, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&flags, sizeof(flags)); } if( !HttpSendRequest( param->hRequest, hdrs, wcslen(hdrs), NULL, 0) ){ //param->errCode = ERROR_INTERNET_SEND; int err = GetLastError(); return 0; } DWORD dwCode = 0, dwSize = sizeof(DWORD); if( HttpQueryInfo( param->hRequest, HTTP_QUERY_STATUS_CODE |HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwSize, NULL ) ){ if( dwCodeerrCode = 1; ReleaseSemaphore( param->hSema, 1, NULL ); } } return 0; } //--------------------------------------------------------------------------- DWORD WINAPI ProbProc(LPVOID args) { TProbParam* param = (TProbParam*)args; param->hSession = InternetOpen( L"RookIE/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 ); if( param->hSession ){ String api = L"http://" + (String)param->server + L"/Api/chkServer"; param->hRequest = InternetOpenUrl( param->hSession, api.c_str(), NULL, 0, INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD|INTERNET_FLAG_PRAGMA_NOCACHE, 0 ); if( param->hRequest ){ DWORD dwByteRead = 0; char szBuffer[1024]; ZeroMemory(szBuffer, sizeof(szBuffer)); InternetReadFile(param->hRequest, szBuffer, sizeof(szBuffer), &dwByteRead); if( dwByteRead==2 && szBuffer[0]=='o' && szBuffer[1]=='k' ){ param->errCode = 1; ReleaseSemaphore( param->hSema, 1, NULL ); } } else param->errCode = ERROR_INTERNET_REQ; } else param->errCode = ERROR_INTERNET_OPEN; return 0; } //--------------------------------------------------------------------------- DWORD WINAPI UrlProc(LPVOID args) { TUrlParam* param = (TUrlParam*)args; param->hSession = InternetOpen( L"RookIE/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 ); if( param->hSession ){ param->hRequest = InternetOpenUrl( param->hSession, param->url.c_str(), param->header.c_str(), 0, INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD|INTERNET_FLAG_PRAGMA_NOCACHE, 0 ); if( param->hRequest ){ int pos = 0; DWORD dwByteRead = 0; char szBuffer[10240]; ZeroMemory(szBuffer, sizeof(szBuffer)); ZeroMemory(param->dataOut, param->sizeOut); // 循环读取缓冲区内容直到结束 while( param->hRequest && InternetReadFile(param->hRequest, szBuffer, 10240, &dwByteRead) && dwByteRead > 0){ if( pos + dwByteRead > param->sizeOut ){ param->errCode = ERROR_SIZE; break; } // 复制输出数据 memcpy( param->dataOut+pos, szBuffer, dwByteRead ); pos += dwByteRead; // 清空缓冲区以备下一次读取 ZeroMemory(szBuffer, 10240); } param->dataOut[pos] = 0; param->sizeOut = pos; if( param->hRequest ) return 0; } param->errCode = ERROR_INTERNET_REQ; } else param->errCode = ERROR_INTERNET_OPEN; return 0; } //--------------------------------------------------------------------------- bool IsPureUrl(String url) { bool bPure = false; int num = 0; int len = url.Length(); for( int i=1; i<=len && num<5; i++ ){ if( url[i]=='/' ){ num++; } } if( num<3 ) bPure = true; else if( num==3 && url[len]=='/' ) bPure = true; return bPure; } ///////////////////////////////////////////////////////////////////////////// // TBaseWebThread __fastcall TBaseWebThread::TBaseWebThread( HWND handle ) : TThread(true) { m_hWnd = handle; m_hSema = CreateSemaphore( NULL, 0, 1, NULL ); } //--------------------------------------------------------------------------- __fastcall TBaseWebThread::~TBaseWebThread() { if( m_hSema ) CloseHandle( m_hSema ); } //--------------------------------------------------------------------------- void __fastcall TBaseWebThread::Cancel() { Terminate(); ReleaseSemaphore( m_hSema, 1, NULL ); } //--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// // TAsynHttpThread __fastcall TAsynHttpThread::TAsynHttpThread( HWND handle, char* server, String api, char* dataIn, int sizeIn, int op, int mode ) : TBaseWebThread( handle ) { memcpy( m_dataIn, dataIn, sizeIn ); m_dataIn[sizeIn] = 0; m_sizeIn = sizeIn; memset( m_dataOut, 0, sizeof(m_dataOut) ); m_sizeOut = 0; strcpy( m_server, server ); m_api = api; m_iOp = op; m_iMode = mode; } //--------------------------------------------------------------------------- void __fastcall TAsynHttpThread::Execute() { char szReturn[10240]; int errCode = 0; THttpParam param; param.iMode = m_iMode; param.sizeIn = m_sizeIn; param.dataIn = m_dataIn; param.sizeOut = 10240; param.dataOut = szReturn; strcpy( param.server, m_server ); strcpy( param.api, ((AnsiString)m_api).c_str() ); DWORD id; HANDLE hThread = CreateThread( NULL, 0, HttpProc, ¶m, 0, &id ); if( hThread ){ HANDLE aHandle[2] = { m_hSema, hThread }; DWORD dwRet = WaitForMultipleObjects( 2, aHandle, FALSE, 15000 ); if( param.hRequest ) InternetCloseHandle( param.hRequest ); if( param.hConnect ) InternetCloseHandle( param.hConnect ); if( param.hSession ) InternetCloseHandle( param.hSession ); param.hSession = param.hConnect = param.hRequest = NULL; WaitForSingleObject( hThread, 200 ); CloseHandle( hThread ); if( dwRet==WAIT_OBJECT_0 ){ //用户退出 return;//errCode = ERROR_INTERNET_CANCEL; } else if( dwRet==WAIT_OBJECT_0+1 && param.errCode==0 ){ //线程正常退出 m_sizeOut = param.sizeOut; memcpy( m_dataOut, szReturn, m_sizeOut ); m_dataOut[m_sizeOut] = 0; } else if( dwRet==WAIT_TIMEOUT ) //超时 errCode = ERROR_INTERNET_TMOUT; else if( param.errCode==0 )//出错了 errCode = ERROR_INTERNET_UNKNOWN; } else errCode = ERROR_INTERNET_UNKNOWN; if( m_hWnd ) PostMessage( m_hWnd, UM_HTTPRETURN, errCode, m_iOp ); } //--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// // TAsynUrlThread __fastcall TAsynUrlThread::TAsynUrlThread( HWND handle, String api, char* pzOut, int& szOut, int op, String header ) : TBaseWebThread( handle ), m_szOut(szOut) { m_url = api; m_pzOut = pzOut; m_iOp = op; m_header = header; } //--------------------------------------------------------------------------- void __fastcall TAsynUrlThread::Execute() { int errCode = 0; TUrlParam param; param.url = m_url; param.header = m_header; param.dataOut = m_pzOut; param.sizeOut = m_szOut; DWORD id; HANDLE hThread = CreateThread( NULL, 0, UrlProc, ¶m, 0, &id ); if( hThread ){ HANDLE aHandle[2] = { m_hSema, hThread }; DWORD dwRet = WaitForMultipleObjects( 2, aHandle, FALSE, 15000 ); if( param.hRequest ) InternetCloseHandle( param.hRequest ); if( param.hSession ) InternetCloseHandle( param.hSession ); param.hSession = param.hRequest = NULL; WaitForSingleObject( hThread, 200 ); CloseHandle( hThread ); if( dwRet==WAIT_OBJECT_0 ){ //用户退出 return; } else if( dwRet==WAIT_OBJECT_0+1 ){ //线程正常退出 m_szOut = param.sizeOut; errCode = param.errCode; } else if( dwRet==WAIT_TIMEOUT ) //超时 errCode = ERROR_INTERNET_TMOUT; else if( param.errCode==0 )//出错了 errCode = ERROR_INTERNET_UNKNOWN; } else errCode = ERROR_INTERNET_UNKNOWN; if( m_hWnd ) PostMessage( m_hWnd, UM_URLRETURN, errCode, m_iOp ); } //--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// // TVeloThread __fastcall TVeloThread::TVeloThread( HWND handle, int nWS, char* websites[], int ports[], char* api, int msWait ) : TBaseWebThread( handle ) { m_nWS = nWS; m_websites = websites; m_ports = ports; m_msWait = msWait; strcpy(m_sApi, api); } //--------------------------------------------------------------------------- void __fastcall TVeloThread::Execute() { HANDLE *aHandle = new HANDLE[m_nWS]; TVeloParam* aParam = new TVeloParam[m_nWS]; HANDLE hWaitSema = CreateSemaphore( NULL, 0, m_nWS>1 ? 2 : 1, NULL ); DWORD id; for( int i=0; i0 && m_sWebsite.Pos(m_websites[i])){ aHandle[i] = NULL; } else{ aParam[i].hSema = hWaitSema; aParam[i].port = m_ports ? m_ports[i] : INTERNET_DEFAULT_HTTPS_PORT; aParam[i].flag = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE; if( aParam[i].port==INTERNET_DEFAULT_HTTPS_PORT ) aParam[i].flag |= INTERNET_FLAG_SECURE; strcpy( aParam[i].addr, m_websites[i] ); strcpy( aParam[i].api, m_sApi ); //aParam[i].api[0] = 0; aHandle[i] = CreateThread( NULL, 0, VeloProc, &aParam[i], CREATE_SUSPENDED, &id ); ResumeThread(aHandle[i]); } } DWORD dwRet = WaitForSingleObject( hWaitSema, m_msWait ); int sel = -1; for( int i=0; i