BOOL HttpRequest(HTTPREQ* req, const wchar_t* url, const wchar_t* header, DWORD header_length, const char* body, DWORD body_length) { BOOL ret = FALSE; req->internet = WinHttpOpen(NULL, NULL, NULL, NULL, NULL); if (req->internet != NULL) { URL_COMPONENTS urlinfo = {0}; urlinfo.dwStructSize = sizeof(URL_COMPONENTS); urlinfo.dwSchemeLength = (DWORD)-1; urlinfo.dwUserNameLength = (DWORD)-1; urlinfo.dwHostNameLength = (DWORD)-1; urlinfo.dwUrlPathLength = (DWORD)-1; urlinfo.dwExtraInfoLength = (DWORD)-1; urlinfo.dwPasswordLength = (DWORD)-1; if (WinHttpCrackUrl(url, wcslen(url), 0, &urlinfo)) { if (WinHttpSetTimeouts(req->internet, req->resolveTimeout, req->connectTimeout, req->sendTimeout, req->receiveTimeout)) { TCHAR* host = new TCHAR[urlinfo.dwHostNameLength + 1]; wmemset(host, 0, urlinfo.dwHostNameLength + 1); StrCpyN(host, urlinfo.lpszHostName, urlinfo.dwHostNameLength + 1); req->connect = WinHttpConnect(req->internet, host, urlinfo.nPort, 0); if (req->connect != NULL) { if (body == NULL || body_length == 0) req->request = WinHttpOpenRequest(req->connect, L"GET", urlinfo.lpszUrlPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); else req->request = WinHttpOpenRequest(req->connect, L"POST", urlinfo.lpszUrlPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); if (req->request != NULL) { if (WinHttpSendRequest(req->request, header, header_length, (void*)body, body_length, body_length, 0) && WinHttpReceiveResponse(req->request, 0)) { TCHAR status[16] = {0}; DWORD size = sizeof(status); if (WinHttpQueryHeaders(req->request, WINHTTP_QUERY_STATUS_CODE, NULL, status, &size, 0)) { if (StrCmp(status, L"200") == 0) { char buffer[4096] = {0}; DWORD length = 0; while (TRUE) { if (WinHttpReadData(req->request, buffer, sizeof(buffer), &length) && length > 0) { AppendBuffer(&req->buffer, req->dataLength, req->bufferLength, buffer, length); length = 0; } else break; } ret = TRUE; } } } } } SAFE_DELETE_ARRAY(host); } } } return ret; }
//------------------------------------------------------------------------------------------------------------------------ const char *CHttpClient::SendRequest(const wchar_t * verb, const wchar_t * target_url, const wchar_t * headers, const wchar_t * body) { CParsedURL<wchar_t> url; url.Parse(target_url); HINTERNET hConnect = NULL, hRequest = NULL; if (hSession) // Specify an HTTP server. hConnect = WinHttpConnect(hSession, url.Base(), url.is_https ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT, 0); if (hConnect) // Create an HTTP request handle. hRequest = WinHttpOpenRequest(hConnect, verb, url.Route(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); BOOL bResults = FALSE; if (hRequest) // Send a request. { if (body==nullptr) // indicates a GET request bResults = WinHttpSendRequest(hRequest, headers, wcslen(headers), WINHTTP_NO_REQUEST_DATA, 0, 0, NULL); else bResults = WinHttpSendRequest(hRequest, headers, wcslen(headers), (LPVOID)body, (DWORD)wcslen(body) * 2, (DWORD)wcslen(body) * 2, NULL); } if (bResults)// End the request. bResults = WinHttpReceiveResponse(hRequest, NULL); response.clear(); // Keep checking for data until there is nothing left. if (bResults) for (DWORD dwSize = 1; dwSize > 0;) { if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) // Check for available data. StoreErrorCode(); LPSTR pszOutBuffer = new char[dwSize + 1]; // Allocate space for the buffer. if (!pszOutBuffer) { //ReportError("Out of memory\n", -1); dwSize = 0; } else { ZeroMemory(pszOutBuffer, dwSize + 1); DWORD dwDownloaded = 0; if (WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) // Read the data. response.append(pszOutBuffer); else StoreErrorCode(); delete[] pszOutBuffer;// Free the memory allocated to the buffer. } } else // !bResults StoreErrorCode(); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); return last_err_code? nullptr : response.c_str(); }
bool uploadToImgur(Image* image, String& response) { MemWriteFile memRaw; image->writePNG(&memRaw); bool success = false; response = "Failed to connect"; HINTERNET hSession = WinHttpOpen(L"MuleView", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, NULL, NULL, 0); if (hSession) { HINTERNET hConnect = WinHttpConnect(hSession, L"api.imgur.com", INTERNET_DEFAULT_HTTPS_PORT, 0); if (hConnect) { HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/3/image", L"HTTP/1.1", WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); if (hRequest) { wchar_t* headers = L"Authorization: Client-ID b7668fe01959177\r\n" L"Content-Type: image/png\r\n"; BOOL result = WinHttpSendRequest(hRequest, headers, -1, memRaw.buffer(), memRaw.size(), memRaw.size(), NULL); if (result) result = WinHttpReceiveResponse(hRequest, NULL); DWORD avail; if (result) result = WinHttpQueryDataAvailable(hRequest, &avail); if (result) { char* ptr = new char[avail + 1]; WinHttpReadData(hRequest, ptr, avail, &avail); ptr[avail] = 0; LocalPtr<json::Value> value = json::Value::parse(File::memfile(ptr, avail, false)); json::Value* sub = (value && value->type() == json::Value::tObject ? value->get("data") : NULL); json::Value* sub2 = (sub && sub->type() == json::Value::tObject ? sub->get("id") : NULL); if (sub2 && sub2->type() == json::Value::tString) { success = true; response = sub2->getString(); } else { sub2 = (sub && sub->type() == json::Value::tObject ? sub->get("error") : NULL); if (sub2 && sub2->type() == json::Value::tString) response = sub2->getString(); } delete[] ptr; } WinHttpCloseHandle(hRequest); } WinHttpCloseHandle(hConnect); } WinHttpCloseHandle(hSession); } return success; }
// POST request to URL void WinHttpIO::post(HttpReq* req, const char* data, unsigned len) { LOG_debug << "POST target URL: " << req->posturl << " chunked: " << req->chunked; if (req->binary) { LOG_debug << "[sending " << (data ? len : req->out->size()) << " bytes of raw data]"; } else { LOG_debug << "Sending: " << *req->out; } WinHttpContext* httpctx; WCHAR szURL[8192]; WCHAR szHost[256]; URL_COMPONENTS urlComp = { sizeof urlComp }; urlComp.lpszHostName = szHost; urlComp.dwHostNameLength = sizeof szHost / sizeof *szHost; urlComp.dwUrlPathLength = (DWORD)-1; urlComp.dwSchemeLength = (DWORD)-1; httpctx = new WinHttpContext; httpctx->httpio = this; httpctx->req = req; httpctx->gzip = false; req->httpiohandle = (void*)httpctx; if (MultiByteToWideChar(CP_UTF8, 0, req->posturl.c_str(), -1, szURL, sizeof szURL / sizeof *szURL) && WinHttpCrackUrl(szURL, 0, 0, &urlComp)) { if ((httpctx->hConnect = WinHttpConnect(hSession, szHost, urlComp.nPort, 0))) { httpctx->hRequest = WinHttpOpenRequest(httpctx->hConnect, L"POST", urlComp.lpszUrlPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, (urlComp.nScheme == INTERNET_SCHEME_HTTPS) ? WINHTTP_FLAG_SECURE : 0); if (httpctx->hRequest) { if (proxyUsername.size()) { LOG_verbose << "Setting proxy credentials"; WinHttpSetCredentials(httpctx->hRequest, WINHTTP_AUTH_TARGET_PROXY, WINHTTP_AUTH_SCHEME_BASIC, (LPWSTR)proxyUsername.data(), (LPWSTR)proxyPassword.data(), NULL); } WinHttpSetTimeouts(httpctx->hRequest, 58000, 58000, 0, 0); WinHttpSetStatusCallback(httpctx->hRequest, asynccallback, WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE | WINHTTP_CALLBACK_FLAG_READ_COMPLETE | WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE | WINHTTP_CALLBACK_FLAG_REQUEST_ERROR | WINHTTP_CALLBACK_FLAG_SECURE_FAILURE | WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE | WINHTTP_CALLBACK_FLAG_SEND_REQUEST | WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE | WINHTTP_CALLBACK_FLAG_HANDLES, 0); LPCWSTR pwszHeaders = req->type == REQ_JSON || !req->buf ? L"Content-Type: application/json\r\nAccept-Encoding: gzip" : L"Content-Type: application/octet-stream"; // data is sent in HTTP_POST_CHUNK_SIZE instalments to ensure // semi-smooth UI progress info if (req->chunkedout.size()) { req->outbuf.append(req->chunkedout); req->chunkedout.clear(); } req->chunked = 0; httpctx->postlen = data ? len : req->out->size(); httpctx->postdata = data ? data : req->out->data(); if (urlComp.nPort == 80) { LOG_verbose << "HTTP connection"; // HTTP connection: send a chunk of data immediately httpctx->postpos = (httpctx->postlen < HTTP_POST_CHUNK_SIZE) ? httpctx->postlen : HTTP_POST_CHUNK_SIZE; } else { LOG_verbose << "HTTPS connection"; // HTTPS connection: ignore certificate errors, send no data yet DWORD flags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_UNKNOWN_CA; WinHttpSetOption(httpctx->hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof flags); httpctx->postpos = 0; } if (WinHttpSendRequest(httpctx->hRequest, pwszHeaders, wcslen(pwszHeaders), (LPVOID)httpctx->postdata, httpctx->postpos, httpctx->postlen, (DWORD_PTR)httpctx)) { LOG_verbose << "Request sent"; req->status = REQ_INFLIGHT; return; } LOG_err << "Error sending request: " << req->posturl << " Code: " << GetLastError(); } else { LOG_err << "Error opening request: " << req->posturl << " Code: " << GetLastError(); } } else { LOG_err << "Error connecting to " << req->posturl << " Code: " << GetLastError(); httpctx->hRequest = NULL; } } else { LOG_err << "Error parsing POST URL: " << req->posturl << " Code: " << GetLastError(); httpctx->hRequest = NULL; httpctx->hConnect = NULL; } LOG_err << "Request failed"; req->status = REQ_FAILURE; }
bool KickStats::Connect() { // User-Agent: Firefox 44.0 m_hSession = WinHttpOpen(L"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (!m_hSession) return false; m_hConnect = WinHttpConnect(m_hSession, m_wsHost.c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0); if (!m_hConnect) return false; m_hRequest = WinHttpOpenRequest(m_hConnect, L"GET", m_wsPath.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE | WINHTTP_FLAG_REFRESH); if (m_hRequest) return true; return false; }
xlw::XlfOper HttpProtocol::Execute(const char* name, bool sendCaller, xlw::XlfOper* args, int argc) { REQUEST_CONTEXT context; context.hEvent = CreateEvent(0, 1, 0, 0); context.hConnect = WinHttpConnect(hSession, host, urlc.nPort, 0); int flags = WINHTTP_FLAG_BYPASS_PROXY_CACHE; if(urlc.nScheme == INTERNET_SCHEME_HTTPS) flags |= WINHTTP_FLAG_SECURE; context.hRequest = WinHttpOpenRequest(context.hConnect, L"POST", path, 0, 0, 0, flags); context.conf.beautify = 0; context.conf.indentString = ""; context.g = yajl_gen_alloc(&context.conf, 0); context.px = xlw::XlfOper(); //context.px->xltype = xltypeNil | xlbitDLLFree; GenerateRequest(context.g, name, sendCaller, args, argc); const unsigned char * buf; unsigned int len = 0; yajl_gen_get_buf(context.g, &buf, &len); BOOL res = FALSE; res = WinHttpSendRequest(context.hRequest, 0, 0, (LPVOID) buf, len, len, (DWORD_PTR) &context); if(!res) { const char* err = "#Could not connect to server"; Log::Error(err); WinHttpCloseHandle(context.hRequest); WinHttpCloseHandle(context.hConnect); context.px = xlw::XlfOper(err); return context.px; } // TODO timeout/background res = WinHttpReceiveResponse(context.hRequest, 0); if(!res) { const char* err = "#Error retrieving server response"; Log::Error(err); WinHttpCloseHandle(context.hRequest); WinHttpCloseHandle(context.hConnect); context.px = xlw::XlfOper(err); return context.px; } // Check http response code DWORD status; DWORD statusLength = 4; res = WinHttpQueryHeaders(context.hRequest, WINHTTP_QUERY_STATUS_CODE| WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &statusLength, 0); if(!res || status != 200) { Log::Error("Status code: %d", status); const char* err = "#Server returned an error"; WinHttpCloseHandle(context.hRequest); WinHttpCloseHandle(context.hConnect); context.px = xlw::XlfOper(err); return context.px; } ReadData(&context); WinHttpCloseHandle(context.hRequest); WinHttpCloseHandle(context.hConnect); yajl_gen_clear(context.g); yajl_gen_free(context.g); //context.px->xltype |= xlbitDLLFree; return context.px; }
// POST request to URL void WinHttpIO::post(HttpReq* req, const char* data /*= nullptr*/, unsigned len /*= 0*/) { if (debug) { cout << "POST target URL: " << req->posturl << endl; if (req->binary) { cout << "[sending " << req->out->size() << " bytes of raw data]" << endl; } else { cout << "Sending: " << *req->out << endl; } } WinHttpContext* cpContext = new WinHttpContext; req->httpiohandle = (void*)cpContext; WCHAR szHost[256] = L""; URL_COMPONENTS urlComp = { sizeof(URL_COMPONENTS) }; urlComp.lpszHostName = szHost; urlComp.dwHostNameLength = _countof(szHost); urlComp.dwUrlPathLength = (DWORD)-1; urlComp.dwSchemeLength = (DWORD)-1; try { // Crack the URL. std::wstring strURL = ConvertUTF16fromUTF8(req->posturl); BOOL bRet = WinHttpCrackUrl(strURL.c_str(), strURL.length(), 0, &urlComp); if (bRet == FALSE) throw std::exception("WinHttpCrackUrl failed"); cpContext->hConnect = WinHttpConnect(hSession, szHost, urlComp.nPort, 0); if (cpContext->hConnect == NULL) throw std::exception("WinHttpConnect failed"); cpContext->hRequest = WinHttpOpenRequest(cpContext->hConnect, L"POST", urlComp.lpszUrlPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, (urlComp.nScheme == INTERNET_SCHEME_HTTPS) ? WINHTTP_FLAG_SECURE : 0); if (cpContext->hRequest == NULL) throw std::exception("WinHttpOpenRequest failed"); if (data) { cpContext->data.assign(data, len); } req->status = REQ_INFLIGHT; cpContext->processThread = std::thread(_ProcessIO, req, cpContext); return; } catch (std::exception& e) { cout << e.what() << endl; ATLASSERT(FALSE); } req->status = REQ_FAILURE; }
//#else void CSinaSvr::PostWeibo(LPCTSTR lpContent) { BOOL bResults= FALSE; HINTERNET hSession = NULL,hConnect = NULL, hRequest = NULL; TCHAR szServer[1024] = _T("weibo.com"); TCHAR szParam[1024] = _T("aj/mblog/add"); TCHAR szHeader[1024] = {0}; TCHAR szCookie[1024] = {0}; _stprintf(szHeader,_T("Accept: */*\r\nContent-Type: application/x-www-form-urlencoded\r\nReferer: http://weibo.com/%s\r\nx-requested-with: XMLHttpRequest\r\n"),m_szCurUID); _stprintf(szCookie,_T("Cookie: %s\r\n"),m_strCookie.GetBuffer()); WCHAR szwPost[1024]={0}; _stprintf(szwPost,_T("_t=0&pic_id=&text=%s"),lpContent); char szPost[1024]= {0}; WideCharToMultiByte(CP_UTF8, 0, szwPost, -1, szPost, MAX_PATH, NULL, NULL); PBYTE pBuf = new BYTE[1024*1024]; hSession = WinHttpOpen(0, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 ); if(hSession) WinHttpSetTimeouts( hSession, 600000, 600000, 600000, 600000); if( hSession ) hConnect = WinHttpConnect( hSession,szServer,80, 0 ); if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"POST", szParam, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); int nLen = strlen(szPost); WinHttpAddRequestHeaders( hRequest, szCookie, -1, WINHTTP_ADDREQ_FLAG_ADD); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, szHeader,-1, szPost, nLen,nLen,0); DWORD dwLen; GetHttpResponse(pBuf,dwLen,hRequest); if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); delete []pBuf; PostWeibo1(lpContent); }
bool Http::Send(WCHAR szUrl[]) { if (this->hSession == NULL) return false; HINTERNET hConnect, hRequest; URL_COMPONENTS urlComponents; WCHAR szHostName[256], szUrlPath[2048]; LPBYTE lpHeader, lpData; DWORD dwSize; ZeroMemory(&urlComponents, sizeof(URL_COMPONENTS)); urlComponents.dwStructSize = sizeof(URL_COMPONENTS); urlComponents.lpszHostName = szHostName; urlComponents.dwHostNameLength = sizeof(szHostName) / sizeof(WCHAR); urlComponents.lpszUrlPath = szUrlPath; urlComponents.dwUrlPathLength = sizeof(szUrlPath) / sizeof(WCHAR); if (!WinHttpCrackUrl(szUrl, lstrlenW(szUrl), 0, &urlComponents)) { WinHttpCloseHandle(hSession); return false; } hConnect = WinHttpConnect(hSession, szHostName, INTERNET_DEFAULT_PORT, 0); if (hConnect == NULL) { WinHttpCloseHandle(hSession); return false; } hRequest = WinHttpOpenRequest(hConnect, L"GET", szUrlPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); if (hRequest == NULL) { WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); return false; } if (!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0)) { WinHttpCloseHandle(hRequest); WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); return false; } WinHttpReceiveResponse(hRequest, NULL); dwSize = 0; lpData = ReadData(hRequest, &dwSize); HeapFree(GetProcessHeap(), 0, lpData); WinHttpCloseHandle(hRequest); WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); return true; }
HINTERNET WinHTTPSession::setup(const Request & request, LPCWSTR method) { platform::WideString wurl(request.url()); URL_COMPONENTS url; ZeroMemory(&url, sizeof(url)); url.dwStructSize = sizeof(url); url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = DWORD(-1); if(WinHttpCrackUrl(wurl, 0, 0, &url) != TRUE) { throw new Response("Invalid URL: \"" + request.url() + "\""); } DWORD flags = 0; if(url.nScheme == INTERNET_SCHEME_HTTPS) { flags |= WINHTTP_FLAG_SECURE; } else if(url.nScheme != INTERNET_SCHEME_HTTP) { throw new Response("Unsupported protocol"); } if(m_scheme != url.nScheme || m_port != url.nPort || m_host.compare(0, m_host.length(), url.lpszHostName, url.dwHostNameLength) != 0) { if(m_connection) { WinHttpCloseHandle(m_connection); } m_scheme = url.nScheme; m_host.assign(url.lpszHostName, url.dwHostNameLength); m_port = url.nPort; m_connection = WinHttpConnect(m_session, m_host.c_str(), m_port, 0); } if(!m_connection) { throw new Response("Could not create connection object: " + errorString()); } LPCWSTR resource = url.dwUrlPathLength ? url.lpszUrlPath : L"/"; LPCWSTR accept[] = { L"*/*", NULL }; HINTERNET wrequest = WinHttpOpenRequest(m_connection, method, resource, NULL, WINHTTP_NO_REFERER, accept, flags); if(!wrequest) { throw new Response("Could not create request object: " + errorString()); } if(request.followRedirects()) { WinHttpSetStatusCallback(wrequest, statusCallback, WINHTTP_CALLBACK_FLAG_REDIRECT, 0); } else { ULONG disable = WINHTTP_DISABLE_REDIRECTS; WinHttpSetOption(wrequest, WINHTTP_OPTION_DISABLE_FEATURE, &disable, sizeof(disable)); } return wrequest; }
static void test_redirect( void ) { static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0}; HANDLE ses, con, req; DWORD size, status; BOOL ret; struct info info, *context = &info; info.test = redirect_test; info.count = sizeof(redirect_test) / sizeof(redirect_test[0]); info.index = 0; info.wait = NULL; ses = WinHttpOpen( user_agent, 0, NULL, NULL, 0 ); ok(ses != NULL, "failed to open session %u\n", GetLastError()); WinHttpSetStatusCallback( ses, check_notification, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0 ); ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); ok(ret, "failed to set context value %u\n", GetLastError()); setup_test( &info, winhttp_connect, __LINE__ ); con = WinHttpConnect( ses, codeweavers, 0, 0 ); ok(con != NULL, "failed to open a connection %u\n", GetLastError()); setup_test( &info, winhttp_open_request, __LINE__ ); req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); ok(req != NULL, "failed to open a request %u\n", GetLastError()); setup_test( &info, winhttp_send_request, __LINE__ ); ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); ok(ret, "failed to send request %u\n", GetLastError()); setup_test( &info, winhttp_receive_response, __LINE__ ); ret = WinHttpReceiveResponse( req, NULL ); ok(ret, "failed to receive response %u\n", GetLastError()); size = sizeof(status); ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); ok(ret, "failed unexpectedly %u\n", GetLastError()); ok(status == 200, "request failed unexpectedly %u\n", status); setup_test( &info, winhttp_close_handle, __LINE__ ); WinHttpCloseHandle( req ); WinHttpCloseHandle( con ); WinHttpCloseHandle( ses ); }
int main(int argc, char* argv[]) { printf("Hello World!\n"); BOOL bResults=FALSE; HINTERNET hSession = NULL,hConnect = NULL, hRequest = NULL; //http://login.sina.com.cn/sso/login.php TCHAR szServer[1024] = _T("login.sina.com.cn"); TCHAR szParam[1024] = _T("sso/login.php"); TCHAR szHeader[1024] = _T("Accept: */*\r\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n"); char szPost[1024] = "[email protected]&password=93732717&entry=miniblog&act=1&from=referer%3Awww_index"; PBYTE pBuf = new BYTE[1024*1024]; hSession = WinHttpOpen(0, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 ); if(hSession) WinHttpSetTimeouts( hSession, 600000, 600000, 600000, 600000); if( hSession ) hConnect = WinHttpConnect( hSession,szServer,80, 0 ); if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"POST", szParam, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); int nLen = strlen(szPost); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, szHeader,-1, szPost, nLen,nLen,0); DWORD dwLen; GetHttpResponse(pBuf,dwLen,hRequest); WriteResponseInfo(pBuf,_T("out.txt")); if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); delete []pBuf; return 0; }
bool CWinHttp::Open(LPCWSTR url) { bool bRet=false; bool bResults=false; if(!CrackURL(url)) goto exit0; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"BbLiFe", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 ); if (!hSession) goto exit0; // Specify an HTTP server. hConnect = WinHttpConnect( hSession, m_strHostName, m_Port, 0 ); if(!hConnect) goto exit0; // Create an HTTP request handle. hRequest = WinHttpOpenRequest( hConnect, m_strVerb, m_stUrlPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_ESCAPE_DISABLE ); bRet=true; exit0: assert(bRet!=false); return bRet; }
void HTTPClient::sendMsg(HTTPMsg* pMsg){ lwassert(pMsg); if ( !_isConnected ){ connect(); } if ( !_isConnected ){ return; } HINTERNET hRequest = WinHttpOpenRequest( _hConnect, L"POST", pMsg->getObjName(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0 ); pMsg->setHRequest(hRequest); //WinHttpSetOption(hRequest, // WINHTTP_OPTION_CONTEXT_VALUE, // pMsg, // sizeof(pMsg)); WinHttpSetStatusCallback(hRequest, requestCallback, WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS | WINHTTP_CALLBACK_FLAG_HANDLES, // to listen to the HANDLE_CLOSING event 0); DWORD size = pMsg->getBuff()->getSize(); bool bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, pMsg->getBuff()->getBuff(), size, size, (DWORD_PTR)pMsg ) != 0; if ( bResults ){ _msgs.push_back(pMsg); }else{ delete pMsg; } }
int _tmain(int argc, _TCHAR* argv[]) { // WinHTTP Sessions Overview | https://msdn.microsoft.com/en-us/library/windows/desktop/aa384270(v=vs.85).aspx DWORD dwSize = 0; DWORD dwDownloaded = 0; LPSTR pszOutBuffer; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen(L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect(hSession, L"www.microsoft.com", INTERNET_DEFAULT_HTTPS_PORT, 0); // Create an HTTP request handle. if (hConnect) hRequest = WinHttpOpenRequest(hConnect, L"GET", NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); // Send a request. if (hRequest) bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // End the request. if (bResults) bResults = WinHttpReceiveResponse(hRequest, NULL); // Keep checking for data until there is nothing left. if (bResults) { do { // Check for available data. dwSize = 0; if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) printf("Error %u in WinHttpQueryDataAvailable.\n", GetLastError()); // Allocate space for the buffer. pszOutBuffer = new char[dwSize + 1]; if (!pszOutBuffer) { printf("Out of memory\n"); dwSize = 0; } else { // Read the data. ZeroMemory(pszOutBuffer, dwSize + 1); if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) printf("Error %u in WinHttpReadData.\n", GetLastError()); else printf("%s", pszOutBuffer); // Free the memory allocated to the buffer. delete[] pszOutBuffer; } } while (dwSize > 0); } // Report any errors. if (!bResults) printf("Error %d has occurred.\n", GetLastError()); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); return 0; }
static int winhttp_stream_connect(winhttp_stream *s) { winhttp_subtransport *t = OWNING_SUBTRANSPORT(s); git_buf buf = GIT_BUF_INIT; char *proxy_url = NULL; wchar_t ct[MAX_CONTENT_TYPE_LEN]; LPCWSTR types[] = { L"*/*", NULL }; BOOL peerdist = FALSE; int error = -1; unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS; int default_timeout = TIMEOUT_INFINITE; int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT; /* Prepare URL */ git_buf_printf(&buf, "%s%s", t->connection_data.path, s->service_url); if (git_buf_oom(&buf)) return -1; /* Convert URL to wide characters */ if (git__utf8_to_16_alloc(&s->request_uri, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "Failed to convert string to wide form"); goto on_error; } /* Establish request */ s->request = WinHttpOpenRequest( t->connection, s->verb, s->request_uri, NULL, WINHTTP_NO_REFERER, types, t->connection_data.use_ssl ? WINHTTP_FLAG_SECURE : 0); if (!s->request) { giterr_set(GITERR_OS, "Failed to open request"); goto on_error; } if (!WinHttpSetTimeouts(s->request, default_timeout, default_connect_timeout, default_timeout, default_timeout)) { giterr_set(GITERR_OS, "Failed to set timeouts for WinHTTP"); goto on_error; } /* Set proxy if necessary */ if (git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url) < 0) goto on_error; if (proxy_url) { WINHTTP_PROXY_INFO proxy_info; wchar_t *proxy_wide; /* Convert URL to wide characters */ int proxy_wide_len = git__utf8_to_16_alloc(&proxy_wide, proxy_url); if (proxy_wide_len < 0) { giterr_set(GITERR_OS, "Failed to convert string to wide form"); goto on_error; } /* Strip any trailing forward slash on the proxy URL; * WinHTTP doesn't like it if one is present */ if (proxy_wide_len > 1 && L'/' == proxy_wide[proxy_wide_len - 2]) proxy_wide[proxy_wide_len - 2] = L'\0'; proxy_info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; proxy_info.lpszProxy = proxy_wide; proxy_info.lpszProxyBypass = NULL; if (!WinHttpSetOption(s->request, WINHTTP_OPTION_PROXY, &proxy_info, sizeof(WINHTTP_PROXY_INFO))) { giterr_set(GITERR_OS, "Failed to set proxy"); git__free(proxy_wide); goto on_error; } git__free(proxy_wide); } /* Disable WinHTTP redirects so we can handle them manually. Why, you ask? * http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/b2ff8879-ab9f-4218-8f09-16d25dff87ae */ if (!WinHttpSetOption(s->request, WINHTTP_OPTION_DISABLE_FEATURE, &disable_redirects, sizeof(disable_redirects))) { giterr_set(GITERR_OS, "Failed to disable redirects"); goto on_error; } /* Strip unwanted headers (X-P2P-PeerDist, X-P2P-PeerDistEx) that WinHTTP * adds itself. This option may not be supported by the underlying * platform, so we do not error-check it */ WinHttpSetOption(s->request, WINHTTP_OPTION_PEERDIST_EXTENSION_STATE, &peerdist, sizeof(peerdist)); /* Send Pragma: no-cache header */ if (!WinHttpAddRequestHeaders(s->request, pragma_nocache, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) { giterr_set(GITERR_OS, "Failed to add a header to the request"); goto on_error; } if (post_verb == s->verb) { /* Send Content-Type and Accept headers -- only necessary on a POST */ git_buf_clear(&buf); if (git_buf_printf(&buf, "Content-Type: application/x-git-%s-request", s->service) < 0) goto on_error; if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "Failed to convert content-type to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "Failed to add a header to the request"); goto on_error; } git_buf_clear(&buf); if (git_buf_printf(&buf, "Accept: application/x-git-%s-result", s->service) < 0) goto on_error; if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "Failed to convert accept header to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "Failed to add a header to the request"); goto on_error; } } /* If requested, disable certificate validation */ if (t->connection_data.use_ssl) { int flags; if (t->owner->parent.read_flags(&t->owner->parent, &flags) < 0) goto on_error; } /* If we have a credential on the subtransport, apply it to the request */ if (t->cred && t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT && t->auth_mechanism == GIT_WINHTTP_AUTH_BASIC && apply_basic_credential(s->request, t->cred) < 0) goto on_error; else if (t->cred && t->cred->credtype == GIT_CREDTYPE_DEFAULT && t->auth_mechanism == GIT_WINHTTP_AUTH_NEGOTIATE && apply_default_credentials(s->request) < 0) goto on_error; /* If no other credentials have been applied and the URL has username and * password, use those */ if (!t->cred && t->connection_data.user && t->connection_data.pass) { if (!t->url_cred && git_cred_userpass_plaintext_new(&t->url_cred, t->connection_data.user, t->connection_data.pass) < 0) goto on_error; if (apply_basic_credential(s->request, t->url_cred) < 0) goto on_error; } /* We've done everything up to calling WinHttpSendRequest. */ error = 0; on_error: if (error < 0) winhttp_stream_close(s); git__free(proxy_url); git_buf_free(&buf); return error; }
string fetchUrl(string server, string path) { BOOL bResults = FALSE; HINTERNET hSession = NULL; HINTERNET hConnect = NULL; HINTERNET hRequest = NULL; string result; wstring wserver(server.begin(), server.end()); wstring wpath(path.begin(), path.end()); // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen(L"Penis Browser/1.1", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect(hSession, wserver.c_str(), INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP request handle. if (hConnect) hRequest = WinHttpOpenRequest(hConnect, L"GET", wpath.c_str(), NULL, WINHTTP_NO_REFERER, NULL, NULL); // Send a request. if (hRequest) bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // End the request. if (bResults) bResults = WinHttpReceiveResponse(hRequest, NULL); // Keep checking for data until there is nothing left. if (bResults) { DWORD dwSize = 0; do { DWORD dwDownloaded = 0; LPSTR pszOutBuffer; // Check for available data. WinHttpQueryDataAvailable(hRequest, &dwSize); // Allocate space for the buffer. pszOutBuffer = new char[dwSize + 1]; // Read the Data. ZeroMemory(pszOutBuffer, dwSize + 1); if (WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) result.append(string(pszOutBuffer, dwDownloaded)); // Free the memory allocated to the buffer. delete[] pszOutBuffer; } while (dwSize > 0); } // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); return result; }
//リクエストを送る //内部メモリバッファにDLする場合はファイル容量に要注意 //戻り値:エラーコード DWORD CWinHTTPUtil::SendRequest( LPCWSTR url, //[IN] アクセスするURL NW_VERB_MODE verbMode, //[IN] VERBの種類 LPCWSTR addHttpHeader, //[IN] Httpヘッダに追加するものあるなら指定 LPCWSTR saveFilePath, //[IN] DLファイル名、NULL時は内部メモリバッファにDL UPLOAD_DATA_LIST* upList //[IN] サーバーに送信するデータ(PUT or POST) ) { if( url == NULL ){ return ERR_INVALID_ARG; } if( this->session == NULL ){ return ERR_NW_NO_SESSION; } //リクエストクローズ if( this->request != NULL ){ WinHttpSetStatusCallback( this->request, NULL, NULL, NULL ); WinHttpCloseHandle(this->request); this->request = NULL; } ClearUpList(); for( size_t i=0; i<this->dlBuffList.size(); i++ ){ SAFE_DELETE(this->dlBuffList[i]); } this->dlBuffList.clear(); //URLの分解 URL_COMPONENTS stURL; ZeroMemory(&stURL, sizeof(URL_COMPONENTS)); stURL.dwStructSize = sizeof(URL_COMPONENTS); stURL.dwSchemeLength = -1; stURL.dwHostNameLength = -1; stURL.dwUrlPathLength = -1; stURL.dwExtraInfoLength = -1; if( WinHttpCrackUrl( url, (DWORD)wcslen(url), 0, &stURL) == NULL ){ return ERR_FALSE; } if( stURL.dwHostNameLength <= 0 ){ return ERR_FALSE; } wstring host = L""; host.insert(0,stURL.lpszHostName, stURL.dwHostNameLength ); host += L"\0"; if( CompareNoCase(host, stURL.lpszHostName) != 0 || this->lastPort != stURL.nPort){ //前回と違うコネクションなのでやりなおし if( this->connect != NULL ){ WinHttpCloseHandle(this->connect); this->connect = NULL; } } //コネクションオープン if( this->connect == NULL ){ this->connect = WinHttpConnect( this->session, host.c_str(), stURL.nPort, 0 ); if( this->connect == NULL ){ return ERR_NW_OPEN_CONNECT; } } //Verbの設定 wstring verb = L"GET"; if( verbMode == NW_VERB_GET ){ verb = L"GET"; }else if( verbMode == NW_VERB_POST ){ verb = L"POST"; }else if( verbMode == NW_VERB_PUT ){ verb = L"PUT"; } wstring sendUrl = L""; sendUrl.insert(0, stURL.lpszUrlPath, stURL.dwUrlPathLength+stURL.dwExtraInfoLength); sendUrl += L"\0"; //リクエストオープン if( stURL.nPort == INTERNET_DEFAULT_HTTPS_PORT ){ this->request = WinHttpOpenRequest( this->connect, verb.c_str(), sendUrl.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); }else{ this->request = WinHttpOpenRequest( this->connect, verb.c_str(), sendUrl.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0 ); } if( this->request == NULL ){ return ERR_NW_OPEN_REQUEST; } if( this->useProxy == TRUE ){ //ProxyのIDとパスワードがあったらセット if( this->proxyID.size() > 0 || this->proxyPWD.size() > 0 ){ if( WinHttpSetCredentials( this->request, WINHTTP_AUTH_TARGET_PROXY, WINHTTP_AUTH_SCHEME_BASIC, this->proxyID.c_str(), this->proxyPWD.c_str(), NULL ) == FALSE ){ return ERR_NW_PROXY_LOGIN; } } } //HTTPヘッダを設定 if( addHttpHeader != NULL ){ WinHttpAddRequestHeaders( this->request, addHttpHeader, -1, WINHTTP_ADDREQ_FLAG_ADD ); } //コールバック設定 WinHttpSetStatusCallback(this->request, StatusCallback, WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS, NULL ); //アップロードデータのコピー this->totalUpSize = 0; if( upList != NULL ){ for( DWORD i=0; i<upList->listCount; i++ ){ UPLOAD_DATA* item = new UPLOAD_DATA; item->filePathFlag = upList->list[i].filePathFlag; item->buffSize = upList->list[i].buffSize; if( item->buffSize > 0 ){ item->buff = new BYTE[item->buffSize]; memcpy(item->buff, upList->list[i].buff, item->buffSize); } upDataList.push_back(item); if( item->filePathFlag == TRUE ){ HANDLE file = CreateFileW( (WCHAR*)item->buff, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( file == INVALID_HANDLE_VALUE ){ //ファイルにアクセスできないのでエラー return ERR_NW_OPEN_FILE; } DWORD HSize=0; DWORD LSize=0; LSize = GetFileSize(file, &HSize); CloseHandle(file); if( HSize > 0 ){ //DWORD以上は未サポート return ERR_SIZE; } this->totalUpSize += LSize; }else{ this->totalUpSize += item->buffSize; } } } this->lastHost = host; this->lastPort = stURL.nPort; if( saveFilePath != NULL ){ this->saveFilePath = saveFilePath; }else{ this->saveFilePath = L""; } ResetEvent(this->upStopEvent); ResetEvent(this->responseCompEvent); this->errEndCode = NO_ERR; if( WinHttpSendRequest( this->request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, totalUpSize, (DWORD_PTR)this) == FALSE ){ return ERR_NW_SEND_REQUEST; } if( this->asyncMode == FALSE ){ //同期なので完了するまで待つ WaitForSingleObject(this->responseCompEvent, INFINITE); return this->errEndCode; } return NO_ERR; }
bool GameJoltAPI::SendRequest( CStdString &output, CStdString url ) { // The private key must be set to send a request. if ( m_GamePrivateKey == _T("") ) { m_ErrorMessage += _T("(You must put in your game's private key before you can use any of the API functions.)"); return false; } //////////////////////////////////// // Let's form the URL first. url = GJAPI_ROOT + GJAPI_VERSION + url; CStdString signature( md5( CStdStringA( _T("http://") + GJAPI_SERVER + url + m_GamePrivateKey ) ) ); url += _T("&signature=") + signature; // Now let's build the request. BOOL ret = FALSE; HINTERNET hSession = NULL; HINTERNET hConnect = NULL; HINTERNET hRequest = NULL; hSession = WinHttpOpen ( L"Game Jolt API Construct/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 ); if ( hSession ) hConnect = WinHttpConnect ( hSession, CStdStringW( GJAPI_SERVER ), INTERNET_DEFAULT_PORT, 0 ); else m_ErrorMessage += _T("(Could not open HTTP session.)"); if ( hConnect ) hRequest = WinHttpOpenRequest ( hConnect, L"GET", CStdStringW( url ), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_REFRESH ); else m_ErrorMessage += _T("(Could not connect to the HTTP session.)"); if ( hRequest ) ret = WinHttpSendRequest ( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0 ); else m_ErrorMessage += _T("(Could not set up the HTTP request.)"); if ( ret ) ret = WinHttpReceiveResponse( hRequest, NULL ); else m_ErrorMessage += _T("(Could not send the HTTP request.)"); DWORD bufferSize = 0; DWORD outputDownloaded = 0; LPSTR outputBuffer = 0; // Keep checking for data until there is nothing left. if ( ret ) { do { // Check for available data. bufferSize = 0; WinHttpQueryDataAvailable( hRequest, &bufferSize ); // Allocate space for the buffer. outputBuffer = new char[bufferSize + 1]; if ( outputBuffer ) { // Read the data. ZeroMemory( outputBuffer, bufferSize + 1 ); if ( WinHttpReadData( hRequest, (LPVOID)outputBuffer, bufferSize, &outputDownloaded ) ) output += outputBuffer; // Free the memory allocated to the buffer. delete [] outputBuffer; } } while( bufferSize > 0 ); } else m_ErrorMessage += _T("(Did not get a response from the server.)"); if ( hRequest ) WinHttpCloseHandle( hRequest ); if ( hConnect ) WinHttpCloseHandle( hConnect ); if ( hSession ) WinHttpCloseHandle( hSession ); return true; }
String HTTPGetString (CTSTR url, CTSTR extraHeaders, int *responseCode, String verb) { HINTERNET hSession = NULL; HINTERNET hConnect = NULL; HINTERNET hRequest = NULL; URL_COMPONENTS urlComponents; BOOL secure = FALSE; String result = ""; String body = TEXT(""); String nurl = url; String hostName, path; const TCHAR *acceptTypes[] = { TEXT("*/*"), NULL }; if (verb == TEXT("POST")){ CTSTR s = srchr(url, TEXT('?')); body = String(s + 1); nurl = nurl.Left(s - url); } hostName.SetLength(256); path.SetLength(1024); zero(&urlComponents, sizeof(urlComponents)); urlComponents.dwStructSize = sizeof(urlComponents); urlComponents.lpszHostName = hostName; urlComponents.dwHostNameLength = hostName.Length(); urlComponents.lpszUrlPath = path; urlComponents.dwUrlPathLength = path.Length(); WinHttpCrackUrl(nurl, 0, 0, &urlComponents); if (urlComponents.nPort == 443) secure = TRUE; hSession = WinHttpOpen(TEXT("gecko test"), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (!hSession) goto failure; hConnect = WinHttpConnect(hSession, hostName, secure ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT, 0); if (!hConnect) goto failure; hRequest = WinHttpOpenRequest(hConnect, verb, path, NULL, WINHTTP_NO_REFERER, acceptTypes, secure ? WINHTTP_FLAG_SECURE|WINHTTP_FLAG_REFRESH : WINHTTP_FLAG_REFRESH); if (!hRequest) goto failure; BOOL bResults = WinHttpSendRequest(hRequest, extraHeaders, extraHeaders ? -1 : 0, body.Array(), body.Length(), body.Length(), 0); // End the request. if (bResults) bResults = WinHttpReceiveResponse(hRequest, NULL); else goto failure; TCHAR statusCode[8]; DWORD statusCodeLen; statusCodeLen = sizeof(statusCode); if (!WinHttpQueryHeaders (hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeLen, WINHTTP_NO_HEADER_INDEX)) goto failure; *responseCode = wcstoul(statusCode, NULL, 10); if (bResults && *responseCode == 200) { CHAR buffer[16384]; DWORD dwSize, dwOutSize; do { // Check for available data. dwSize = 0; if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) goto failure; if (!WinHttpReadData(hRequest, (LPVOID)buffer, dwSize, &dwOutSize)) { goto failure; } else { if (!dwOutSize) break; // Ensure the string is terminated. buffer[dwOutSize] = 0; String b = String((LPCSTR)buffer); result.AppendString(b); } } while (dwSize > 0); } failure: if (hSession) WinHttpCloseHandle(hSession); if (hConnect) WinHttpCloseHandle(hConnect); if (hRequest) WinHttpCloseHandle(hRequest); return result; }
BOOL HTTPGetFile (CTSTR url, CTSTR outputPath, CTSTR extraHeaders, int *responseCode) { HINTERNET hSession = NULL; HINTERNET hConnect = NULL; HINTERNET hRequest = NULL; URL_COMPONENTS urlComponents; BOOL secure = FALSE; BOOL ret = FALSE; String hostName, path; const TCHAR *acceptTypes[] = { TEXT("*/*"), NULL }; hostName.SetLength(256); path.SetLength(1024); zero(&urlComponents, sizeof(urlComponents)); urlComponents.dwStructSize = sizeof(urlComponents); urlComponents.lpszHostName = hostName; urlComponents.dwHostNameLength = hostName.Length(); urlComponents.lpszUrlPath = path; urlComponents.dwUrlPathLength = path.Length(); WinHttpCrackUrl(url, 0, 0, &urlComponents); if (urlComponents.nPort == 443) secure = TRUE; hSession = WinHttpOpen(OBS_VERSION_STRING, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (!hSession) goto failure; hConnect = WinHttpConnect(hSession, hostName, secure ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT, 0); if (!hConnect) goto failure; hRequest = WinHttpOpenRequest(hConnect, TEXT("GET"), path, NULL, WINHTTP_NO_REFERER, acceptTypes, secure ? WINHTTP_FLAG_SECURE|WINHTTP_FLAG_REFRESH : WINHTTP_FLAG_REFRESH); if (!hRequest) goto failure; BOOL bResults = WinHttpSendRequest(hRequest, extraHeaders, extraHeaders ? -1 : 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // End the request. if (bResults) bResults = WinHttpReceiveResponse(hRequest, NULL); else goto failure; TCHAR statusCode[8]; DWORD statusCodeLen; statusCodeLen = sizeof(statusCode); if (!WinHttpQueryHeaders (hRequest, WINHTTP_QUERY_STATUS_CODE, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeLen, WINHTTP_NO_HEADER_INDEX)) goto failure; *responseCode = wcstoul(statusCode, NULL, 10); if (bResults && *responseCode == 200) { BYTE buffer[16384]; DWORD dwSize, dwOutSize; XFile updateFile; if (!updateFile.Open(outputPath, XFILE_WRITE, CREATE_ALWAYS)) goto failure; do { // Check for available data. dwSize = 0; if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) goto failure; if (!WinHttpReadData(hRequest, (LPVOID)buffer, dwSize, &dwOutSize)) { goto failure; } else { if (!dwOutSize) break; if (!updateFile.Write(buffer, dwOutSize)) goto failure; } } while (dwSize > 0); updateFile.Close(); } ret = TRUE; failure: if (hSession) WinHttpCloseHandle(hSession); if (hConnect) WinHttpCloseHandle(hConnect); if (hRequest) WinHttpCloseHandle(hRequest); return ret; }
void main() { DWORD dwSize = 0; DWORD dwDownloaded = 0; LPSTR pszOutBuffer = NULL; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; BOOL bResults = FALSE; hSession=WinHttpOpen(L"User-Agent",WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0); if(hSession) { hConnect=WinHttpConnect(hSession,L"kinggigi.sinaapp.com",INTERNET_DEFAULT_HTTP_PORT,0); } if(hConnect) { hRequest=WinHttpOpenRequest(hConnect, L"POST",L"hello.php",L"HTTP/1.1", WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES,0); } LPCWSTR header=L"Content-type: application/x-www-form-urlencoded"; SIZE_T len = lstrlenW(header); WinHttpAddRequestHeaders(hRequest,header,DWORD(len), WINHTTP_ADDREQ_FLAG_ADD); if(hRequest) { std::string data="val1=10&val2=9"; const void *ss=(const char *)data.c_str(); bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, const_cast<void *>(ss), data.length(), data.length(), 0); ////bResults=WinHttpSendRequest(hRequest,WINHTTP_NO_ADDITIONAL_HEADERS, 0,WINHTTP_NO_REQUEST_DATA, 0, 0, 0 ); } if(bResults) { bResults=WinHttpReceiveResponse(hRequest,NULL); } if(bResults) { do { // Check for available data. dwSize = 0; if (!WinHttpQueryDataAvailable( hRequest, &dwSize)) { printf( "Error %u in WinHttpQueryDataAvailable.\n",GetLastError()); break; } if (!dwSize) break; pszOutBuffer = new char[dwSize+1]; if (!pszOutBuffer) { printf("Out of memory\n"); break; } ZeroMemory(pszOutBuffer, dwSize+1); if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) { printf( "Error %u in WinHttpReadData.\n", GetLastError()); } else { printf("%s", pszOutBuffer); } delete [] pszOutBuffer; if (!dwDownloaded) break; } while (dwSize > 0); } if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); system("pause"); }
/*! * @brief Prepare a winHTTP request with the given context. * @param ctx Pointer to the HTTP transport context to prepare the request from. * @param isGet Indication of whether this request is a GET request, otherwise POST is used. * @param direction String representing the direction of the communications (for debug). * @return An Internet request handle. */ static HINTERNET get_request_winhttp(HttpTransportContext *ctx, BOOL isGet, const char *direction) { HINTERNET hReq = NULL; DWORD flags = WINHTTP_FLAG_BYPASS_PROXY_CACHE; if (ctx->ssl) { flags |= WINHTTP_FLAG_SECURE; dprintf("[%s] Setting secure flag..", direction); } vdprintf("[%s] opening request on connection %x to %S", direction, ctx->connection, ctx->uri); hReq = WinHttpOpenRequest(ctx->connection, isGet ? L"GET" : L"POST", ctx->uri, NULL, NULL, NULL, flags); if (hReq == NULL) { dprintf("[%s] Failed WinHttpOpenRequest: %u", direction, GetLastError()); SetLastError(ERROR_NOT_FOUND); return NULL; } // if no proxy is set, we should look to see if we can (and should) use the system // proxy settings for the given user. if (!ctx->proxy) { if (!ctx->proxy_configured) { WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieConfig = { 0 }; if (WinHttpGetIEProxyConfigForCurrentUser(&ieConfig)) { dprintf("[PROXY] Got IE configuration"); dprintf("[PROXY] AutoDetect: %s", ieConfig.fAutoDetect ? "yes" : "no"); dprintf("[PROXY] Auto URL: %S", ieConfig.lpszAutoConfigUrl); dprintf("[PROXY] Proxy: %S", ieConfig.lpszProxy); dprintf("[PROXY] Proxy Bypass: %S", ieConfig.lpszProxyBypass); if (ieConfig.lpszAutoConfigUrl || ieConfig.fAutoDetect) { WINHTTP_AUTOPROXY_OPTIONS autoProxyOpts = { 0 }; WINHTTP_PROXY_INFO proxyInfo = { 0 }; if (ieConfig.fAutoDetect) { dprintf("[PROXY] IE config set to autodetect with DNS or DHCP"); autoProxyOpts.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; autoProxyOpts.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A; autoProxyOpts.lpszAutoConfigUrl = 0; } else if (ieConfig.lpszAutoConfigUrl) { dprintf("[PROXY] IE config set to autodetect with URL %S", ieConfig.lpszAutoConfigUrl); autoProxyOpts.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL; autoProxyOpts.dwAutoDetectFlags = 0; autoProxyOpts.lpszAutoConfigUrl = ieConfig.lpszAutoConfigUrl; } autoProxyOpts.fAutoLogonIfChallenged = TRUE; if (WinHttpGetProxyForUrl(ctx->internet, ctx->url, &autoProxyOpts, &proxyInfo)) { ctx->proxy_for_url = malloc(sizeof(WINHTTP_PROXY_INFO)); memcpy(ctx->proxy_for_url, &proxyInfo, sizeof(WINHTTP_PROXY_INFO)); } } else if (ieConfig.lpszProxy) { WINHTTP_PROXY_INFO* proxyInfo = (WINHTTP_PROXY_INFO*)calloc(1, sizeof(WINHTTP_PROXY_INFO)); ctx->proxy_for_url = proxyInfo; dprintf("[PROXY] IE config set to proxy %S with bypass %S", ieConfig.lpszProxy, ieConfig.lpszProxyBypass); proxyInfo->dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; proxyInfo->lpszProxy = ieConfig.lpszProxy; proxyInfo->lpszProxyBypass = ieConfig.lpszProxyBypass; // stop the cleanup code from removing these as we're using them behind the scenes and they will // be freed later instead. ieConfig.lpszProxy = NULL; ieConfig.lpszProxyBypass = NULL;; } if (ieConfig.lpszAutoConfigUrl) { GlobalFree(ieConfig.lpszAutoConfigUrl); } if (ieConfig.lpszProxy) { GlobalFree(ieConfig.lpszProxy); } if (ieConfig.lpszProxyBypass) { GlobalFree(ieConfig.lpszProxyBypass); } } // mark as "configured" so we don't attempt to do this horrible PoS mess again. ctx->proxy_configured = TRUE; } if (ctx->proxy_for_url && !WinHttpSetOption(hReq, WINHTTP_OPTION_PROXY, ctx->proxy_for_url, sizeof(WINHTTP_PROXY_INFO))) { dprintf("[%s] Unable to set proxy options: %u", GetLastError()); } } else { if (ctx->proxy_user) { dprintf("[%s] Setting proxy username to %S", direction, ctx->proxy_user); if (!WinHttpSetOption(hReq, WINHTTP_OPTION_PROXY_USERNAME, ctx->proxy_user, (DWORD)(wcslen(ctx->proxy_user)))); { dprintf("[%s] Failed to set username %u", direction, GetLastError()); } } if (ctx->proxy_pass) { dprintf("[%s] Setting proxy password to %S", direction, ctx->proxy_pass); if (!WinHttpSetOption(hReq, WINHTTP_OPTION_PROXY_PASSWORD, ctx->proxy_pass, (DWORD)(wcslen(ctx->proxy_pass)))); { dprintf("[%s] Failed to set password %u", direction, GetLastError()); } } } if (ctx->ssl) { flags = SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE; if (!WinHttpSetOption(hReq, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags))) { dprintf("[%s] failed to set the security flags on the request", direction); } } return hReq; }
BOOL CSyoboiCalUtil::SendReserve(const vector<RESERVE_DATA>* reserveList, const vector<TUNER_RESERVE_INFO>* tunerList) { if( reserveList == NULL || tunerList == NULL ){ return FALSE; } if( reserveList->size() == 0 ){ return FALSE; } wstring iniAppPath = L""; GetModuleIniPath(iniAppPath); if( GetPrivateProfileInt(L"SYOBOI", L"use", 0, iniAppPath.c_str()) == 0 ){ return FALSE; } _OutputDebugString(L"★SyoboiCalUtil:SendReserve"); wstring textPath; GetModuleFolderPath(textPath); textPath += L"\\SyoboiCh.txt"; CParseServiceChgText srvChg; srvChg.ParseText(textPath.c_str()); wstring proxyServerName; wstring proxyUserName; wstring proxyPassword; if( GetPrivateProfileInt(L"SYOBOI", L"useProxy", 0, iniAppPath.c_str()) != 0 ){ proxyServerName = GetPrivateProfileToString(L"SYOBOI", L"ProxyServer", L"", iniAppPath.c_str()); proxyUserName = GetPrivateProfileToString(L"SYOBOI", L"ProxyID", L"", iniAppPath.c_str()); proxyPassword = GetPrivateProfileToString(L"SYOBOI", L"ProxyPWD", L"", iniAppPath.c_str()); } wstring id=GetPrivateProfileToString(L"SYOBOI", L"userID", L"", iniAppPath.c_str()); wstring pass=GetPrivateProfileToString(L"SYOBOI", L"PWD", L"", iniAppPath.c_str()); int slot = GetPrivateProfileInt(L"SYOBOI", L"slot", 0, iniAppPath.c_str()); wstring devcolors=GetPrivateProfileToString(L"SYOBOI", L"devcolors", L"", iniAppPath.c_str()); wstring epgurl=GetPrivateProfileToString(L"SYOBOI", L"epgurl", L"", iniAppPath.c_str()); if( id.size() == 0 ){ _OutputDebugString(L"★SyoboiCalUtil:NoUserID"); return FALSE; } //Authorization wstring auth = L""; auth = id; auth += L":"; auth += pass; string authA; WtoA(auth, authA); DWORD destSize = 0; Base64Enc(authA.c_str(), (DWORD)authA.size(), NULL, &destSize); vector<WCHAR> base64(destSize + 1, L'\0'); Base64Enc(authA.c_str(), (DWORD)authA.size(), &base64.front(), &destSize); //無駄なCRLFが混じることがあるため std::replace(base64.begin(), base64.end(), L'\r', L'\0'); std::replace(base64.begin(), base64.end(), L'\n', L'\0'); wstring authHead = L""; Format(authHead, L"Authorization: Basic %s\r\nContent-type: application/x-www-form-urlencoded\r\n", &base64.front()); //data wstring dataParam; wstring param; map<DWORD, wstring> tunerMap; for( size_t i=0; i<tunerList->size(); i++ ){ for( size_t j=0; j<(*tunerList)[i].reserveList.size(); j++ ){ tunerMap.insert(pair<DWORD, wstring>((*tunerList)[i].reserveList[j], (*tunerList)[i].tunerName)); } } map<DWORD, wstring>::iterator itrTuner; DWORD dataCount = 0; for(size_t i=0; i<reserveList->size(); i++ ){ if( dataCount>=200 ){ break; } const RESERVE_DATA* info = &(*reserveList)[i]; if( info->recSetting.recMode == RECMODE_NO || info->recSetting.recMode == RECMODE_VIEW ){ continue; } wstring device=L""; itrTuner = tunerMap.find(info->reserveID); if( itrTuner != tunerMap.end() ){ device = itrTuner->second; } wstring stationName = info->stationName; srvChg.ChgText(stationName); __int64 startTime = GetTimeStamp(info->startTime); Format(param, L"%I64d\t%I64d\t%s\t%s\t%s\t\t0\t%d\n", startTime, startTime+info->durationSecond, device.c_str(), info->title.c_str(), stationName.c_str(), info->reserveID ); dataParam+=param; } if(dataParam.size() == 0 ){ _OutputDebugString(L"★SyoboiCalUtil:NoReserve"); return FALSE; } string utf8; UrlEncodeUTF8(dataParam.c_str(), (DWORD)dataParam.size(), utf8); string data; Format(data, "slot=%d&data=%s",slot, utf8.c_str()); if( devcolors.size() > 0){ utf8 = ""; UrlEncodeUTF8(devcolors.c_str(), (DWORD)devcolors.size(), utf8); data += "&devcolors="; data += utf8; } if( epgurl.size() > 0){ utf8 = ""; UrlEncodeUTF8(epgurl.c_str(), (DWORD)epgurl.size(), utf8); data += "&epgurl="; data += utf8; } vector<char> dataBuff(data.begin(), data.end()); //URLの分解 URL_COMPONENTS stURL = {}; stURL.dwStructSize = sizeof(stURL); stURL.dwSchemeLength = (DWORD)-1; stURL.dwHostNameLength = (DWORD)-1; stURL.dwUrlPathLength = (DWORD)-1; stURL.dwExtraInfoLength = (DWORD)-1; if( WinHttpCrackUrl(SYOBOI_UP_URL, 0, 0, &stURL) == FALSE || stURL.dwHostNameLength == 0 ){ return FALSE; } wstring host(stURL.lpszHostName, stURL.dwHostNameLength); wstring sendUrl(stURL.lpszUrlPath, stURL.dwUrlPathLength + stURL.dwExtraInfoLength); HINTERNET session; if( proxyServerName.empty() ){ session = WinHttpOpen(L"EpgTimerSrv", WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); }else{ session = WinHttpOpen(L"EpgTimerSrv", WINHTTP_ACCESS_TYPE_NAMED_PROXY, proxyServerName.c_str(), WINHTTP_NO_PROXY_BYPASS, 0); } if( session == NULL ){ return FALSE; } LPCWSTR result = L"1"; HINTERNET connect = NULL; HINTERNET request = NULL; if( WinHttpSetTimeouts(session, 15000, 15000, 15000, 15000) == FALSE ){ result = L"0 SetTimeouts"; goto EXIT; } //コネクションオープン connect = WinHttpConnect(session, host.c_str(), stURL.nPort, 0); if( connect == NULL ){ result = L"0 Connect"; goto EXIT; } //リクエストオープン request = WinHttpOpenRequest(connect, L"POST", sendUrl.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, stURL.nPort == INTERNET_DEFAULT_HTTPS_PORT ? WINHTTP_FLAG_SECURE : 0); if( request == NULL ){ result = L"0 OpenRequest"; goto EXIT; } if( proxyServerName.empty() == false ){ //ProxyのIDかパスワードがあったらセット if( proxyUserName.empty() == false || proxyPassword.empty() == false ){ if( WinHttpSetCredentials(request, WINHTTP_AUTH_TARGET_PROXY, WINHTTP_AUTH_SCHEME_BASIC, proxyUserName.c_str(), proxyPassword.c_str(), NULL) == FALSE ){ result = L"0 SetCredentials"; goto EXIT; } } } if( WinHttpSendRequest(request, authHead.c_str(), (DWORD)-1, &dataBuff.front(), (DWORD)dataBuff.size(), (DWORD)dataBuff.size(), 0) == FALSE ){ result = L"0 SendRequest"; goto EXIT; } if( WinHttpReceiveResponse(request, NULL) == FALSE ){ result = L"0 ReceiveResponse"; goto EXIT; } //HTTPのステータスコード確認 DWORD statusCode; DWORD statusCodeSize = sizeof(statusCode); if( WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeSize, WINHTTP_NO_HEADER_INDEX) == FALSE ){ statusCode = 0; } if( statusCode != 200 && statusCode != 201 ){ result = L"0 StatusNotOK"; goto EXIT; } EXIT: if( request != NULL ){ WinHttpCloseHandle(request); } if( connect != NULL ){ WinHttpCloseHandle(connect); } if( session != NULL ){ WinHttpCloseHandle(session); } _OutputDebugString(L"★SyoboiCalUtil:SendRequest res:%s", result); if( result[0] != L'1' ){ return FALSE; } return TRUE; }
static void test_connection_cache( void ) { HANDLE ses, con, req; DWORD size, status; BOOL ret; struct info info, *context = &info; info.test = cache_test; info.count = sizeof(cache_test) / sizeof(cache_test[0]); info.index = 0; info.wait = NULL; ses = WinHttpOpen( user_agent, 0, NULL, NULL, 0 ); ok(ses != NULL, "failed to open session %u\n", GetLastError()); WinHttpSetStatusCallback( ses, check_notification, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0 ); ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); ok(ret, "failed to set context value %u\n", GetLastError()); setup_test( &info, winhttp_connect, __LINE__ ); con = WinHttpConnect( ses, test_winehq, 0, 0 ); ok(con != NULL, "failed to open a connection %u\n", GetLastError()); setup_test( &info, winhttp_open_request, __LINE__ ); req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); ok(req != NULL, "failed to open a request %u\n", GetLastError()); setup_test( &info, winhttp_send_request, __LINE__ ); ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); ok(ret, "failed to send request %u\n", GetLastError()); setup_test( &info, winhttp_receive_response, __LINE__ ); ret = WinHttpReceiveResponse( req, NULL ); ok(ret, "failed to receive response %u\n", GetLastError()); size = sizeof(status); ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); ok(ret, "failed unexpectedly %u\n", GetLastError()); ok(status == 200, "request failed unexpectedly %u\n", status); setup_test( &info, winhttp_close_handle, __LINE__ ); WinHttpCloseHandle( req ); setup_test( &info, winhttp_open_request, __LINE__ ); req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); ok(req != NULL, "failed to open a request %u\n", GetLastError()); ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); ok(ret, "failed to set context value %u\n", GetLastError()); setup_test( &info, winhttp_send_request, __LINE__ ); ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); ok(ret, "failed to send request %u\n", GetLastError()); setup_test( &info, winhttp_receive_response, __LINE__ ); ret = WinHttpReceiveResponse( req, NULL ); ok(ret, "failed to receive response %u\n", GetLastError()); size = sizeof(status); ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); ok(ret, "failed unexpectedly %u\n", GetLastError()); ok(status == 200, "request failed unexpectedly %u\n", status); setup_test( &info, winhttp_close_handle, __LINE__ ); WinHttpCloseHandle( req ); setup_test( &info, winhttp_close_handle, __LINE__ ); WinHttpCloseHandle( req ); WinHttpCloseHandle( con ); WinHttpCloseHandle( ses ); Sleep(2000); /* make sure connection is evicted from cache */ info.index = 0; ses = WinHttpOpen( user_agent, 0, NULL, NULL, 0 ); ok(ses != NULL, "failed to open session %u\n", GetLastError()); WinHttpSetStatusCallback( ses, check_notification, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0 ); ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); ok(ret, "failed to set context value %u\n", GetLastError()); setup_test( &info, winhttp_connect, __LINE__ ); con = WinHttpConnect( ses, test_winehq, 0, 0 ); ok(con != NULL, "failed to open a connection %u\n", GetLastError()); setup_test( &info, winhttp_open_request, __LINE__ ); req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); ok(req != NULL, "failed to open a request %u\n", GetLastError()); ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); ok(ret, "failed to set context value %u\n", GetLastError()); setup_test( &info, winhttp_send_request, __LINE__ ); ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); ok(ret, "failed to send request %u\n", GetLastError()); setup_test( &info, winhttp_receive_response, __LINE__ ); ret = WinHttpReceiveResponse( req, NULL ); ok(ret, "failed to receive response %u\n", GetLastError()); size = sizeof(status); ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); ok(ret, "failed unexpectedly %u\n", GetLastError()); ok(status == 200, "request failed unexpectedly %u\n", status); setup_test( &info, winhttp_close_handle, __LINE__ ); WinHttpCloseHandle( req ); setup_test( &info, winhttp_open_request, __LINE__ ); req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); ok(req != NULL, "failed to open a request %u\n", GetLastError()); ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); ok(ret, "failed to set context value %u\n", GetLastError()); setup_test( &info, winhttp_send_request, __LINE__ ); ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); ok(ret, "failed to send request %u\n", GetLastError()); setup_test( &info, winhttp_receive_response, __LINE__ ); ret = WinHttpReceiveResponse( req, NULL ); ok(ret, "failed to receive response %u\n", GetLastError()); size = sizeof(status); ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); ok(ret, "failed unexpectedly %u\n", GetLastError()); ok(status == 200, "request failed unexpectedly %u\n", status); setup_test( &info, winhttp_close_handle, __LINE__ ); WinHttpCloseHandle( req ); WinHttpCloseHandle( con ); WinHttpCloseHandle( ses ); Sleep(2000); /* make sure connection is evicted from cache */ }
BOOL DoBlockingHttpGet( const char* sRequestedPage, char* pBufferOut, const unsigned int /*nBufferOutSize*/, DWORD* pBytesRead ) { BOOL bResults = FALSE, bSuccess = FALSE; HINTERNET hSession = nullptr, hConnect = nullptr, hRequest = nullptr; WCHAR wBuffer[1024]; size_t nTemp; char* sDataDestOffset = &pBufferOut[0]; DWORD nBytesToRead = 0; DWORD nBytesFetched = 0; char sClientName[1024]; sprintf_s( sClientName, 1024, "Retro Achievements Client" ); WCHAR wClientNameBuffer[1024]; mbstowcs_s( &nTemp, wClientNameBuffer, 1024, sClientName, strlen(sClientName)+1 ); // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( wClientNameBuffer, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if( hSession != nullptr ) { hConnect = WinHttpConnect( hSession, L"www.retroachievements.org", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if( hConnect != nullptr ) { mbstowcs_s( &nTemp, wBuffer, 1024, sRequestedPage, strlen(sRequestedPage)+1 ); hRequest = WinHttpOpenRequest( hConnect, L"GET", wBuffer, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if( hRequest != nullptr ) { bResults = WinHttpSendRequest( hRequest, L"Content-Type: application/x-www-form-urlencoded", 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); if( WinHttpReceiveResponse( hRequest, NULL ) ) { nBytesToRead = 0; (*pBytesRead) = 0; WinHttpQueryDataAvailable( hRequest, &nBytesToRead ); while( nBytesToRead > 0 ) { char sHttpReadData[8192]; ZeroMemory( sHttpReadData, 8192*sizeof(char) ); assert( nBytesToRead <= 8192 ); if( nBytesToRead <= 8192 ) { nBytesFetched = 0; if( WinHttpReadData( hRequest, &sHttpReadData, nBytesToRead, &nBytesFetched ) ) { assert( nBytesToRead == nBytesFetched ); //Read: parse buffer memcpy( sDataDestOffset, sHttpReadData, nBytesFetched ); sDataDestOffset += nBytesFetched; (*pBytesRead) += nBytesFetched; } } bSuccess = TRUE; WinHttpQueryDataAvailable( hRequest, &nBytesToRead ); } } } } } // Close open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); return bSuccess; }
static void test_async( void ) { HANDLE ses, con, req; DWORD size, status; BOOL ret; struct info info, *context = &info; char buffer[1024]; info.test = async_test; info.count = sizeof(async_test) / sizeof(async_test[0]); info.index = 0; info.wait = CreateEventW( NULL, FALSE, FALSE, NULL ); ses = WinHttpOpen( user_agent, 0, NULL, NULL, WINHTTP_FLAG_ASYNC ); ok(ses != NULL, "failed to open session %u\n", GetLastError()); WinHttpSetStatusCallback( ses, check_notification, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0 ); ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); ok(ret, "failed to set context value %u\n", GetLastError()); setup_test( &info, winhttp_connect, __LINE__ ); con = WinHttpConnect( ses, test_winehq, 0, 0 ); ok(con != NULL, "failed to open a connection %u\n", GetLastError()); setup_test( &info, winhttp_open_request, __LINE__ ); req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); ok(req != NULL, "failed to open a request %u\n", GetLastError()); setup_test( &info, winhttp_send_request, __LINE__ ); ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); ok(ret, "failed to send request %u\n", GetLastError()); WaitForSingleObject( info.wait, INFINITE ); setup_test( &info, winhttp_receive_response, __LINE__ ); ret = WinHttpReceiveResponse( req, NULL ); ok(ret, "failed to receive response %u\n", GetLastError()); WaitForSingleObject( info.wait, INFINITE ); size = sizeof(status); ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); ok(ret, "failed unexpectedly %u\n", GetLastError()); ok(status == 200, "request failed unexpectedly %u\n", status); setup_test( &info, winhttp_query_data, __LINE__ ); ret = WinHttpQueryDataAvailable( req, NULL ); ok(ret, "failed to query data available %u\n", GetLastError()); WaitForSingleObject( info.wait, INFINITE ); setup_test( &info, winhttp_read_data, __LINE__ ); ret = WinHttpReadData( req, buffer, sizeof(buffer), NULL ); ok(ret, "failed to query data available %u\n", GetLastError()); WaitForSingleObject( info.wait, INFINITE ); setup_test( &info, winhttp_close_handle, __LINE__ ); WinHttpCloseHandle( req ); WinHttpCloseHandle( con ); WinHttpCloseHandle( ses ); WaitForSingleObject( info.wait, INFINITE ); CloseHandle( info.wait ); }
void shoes_winhttp(LPCWSTR host, INTERNET_PORT port, LPCWSTR path, TCHAR **mem, ULONG memlen, HANDLE file, LPDWORD size, shoes_download_handler handler, void *data) { DWORD len = 0, rlen = 0, status = 0, complete = 0, flen = 0, total = 0, written = 0; LPTSTR buf = SHOE_ALLOC_N(TCHAR, SHOES_BUFSIZE); LPTSTR fbuf = SHOE_ALLOC_N(TCHAR, SHOES_CHUNKSIZE); LPWSTR uagent = SHOE_ALLOC_N(WCHAR, SHOES_BUFSIZE); HINTERNET sess = NULL, conn = NULL, req = NULL; SHOES_TIME last = 0; if (buf == NULL || fbuf == NULL || uagent == NULL) goto done; _snwprintf(uagent, SHOES_BUFSIZE, L"Shoes/0.r%d (%S) %S/%d", SHOES_REVISION, SHOES_PLATFORM, SHOES_RELEASE_NAME, SHOES_BUILD_DATE); sess = WinHttpOpen(uagent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (sess == NULL) goto done; conn = WinHttpConnect(sess, host, port, 0); if (conn == NULL) goto done; req = WinHttpOpenRequest(conn, L"GET", path, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); if (req == NULL) goto done; if (!WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0)) goto done; if (!WinHttpReceiveResponse(req, NULL)) goto done; len = sizeof(DWORD); if (!WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &len, NULL)) goto done; else { shoes_download_event event; event.stage = SHOES_HTTP_STATUS; event.status = status; if (handler != NULL) handler(&event, data); } shoes_winhttp_headers(req, handler, data); *size = 0; len = sizeof(buf); if (WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, buf, &len, NULL)) { *size = _wtoi((wchar_t *)buf); if (*mem != NULL && *size > memlen) { SHOE_REALLOC_N(*mem, char, (memlen = *size)); if (*mem == NULL) goto done; }
static int winhttp_stream_connect(winhttp_stream *s) { winhttp_subtransport *t = OWNING_SUBTRANSPORT(s); git_buf buf = GIT_BUF_INIT; char *proxy_url = NULL; wchar_t ct[MAX_CONTENT_TYPE_LEN]; LPCWSTR types[] = { L"*/*", NULL }; BOOL peerdist = FALSE; int error = -1; unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS; int default_timeout = TIMEOUT_INFINITE; int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT; size_t i; const git_proxy_options *proxy_opts; /* Prepare URL */ git_buf_printf(&buf, "%s%s", t->connection_data.path, s->service_url); if (git_buf_oom(&buf)) return -1; /* Convert URL to wide characters */ if (git__utf8_to_16_alloc(&s->request_uri, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert string to wide form"); goto on_error; } /* Establish request */ s->request = WinHttpOpenRequest( t->connection, s->verb, s->request_uri, NULL, WINHTTP_NO_REFERER, types, t->connection_data.use_ssl ? WINHTTP_FLAG_SECURE : 0); if (!s->request) { giterr_set(GITERR_OS, "failed to open request"); goto on_error; } if (!WinHttpSetTimeouts(s->request, default_timeout, default_connect_timeout, default_timeout, default_timeout)) { giterr_set(GITERR_OS, "failed to set timeouts for WinHTTP"); goto on_error; } proxy_opts = &t->owner->proxy; if (proxy_opts->type == GIT_PROXY_AUTO) { /* Set proxy if necessary */ if (git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url) < 0) goto on_error; } else if (proxy_opts->type == GIT_PROXY_SPECIFIED) { proxy_url = git__strdup(proxy_opts->url); GITERR_CHECK_ALLOC(proxy_url); } if (proxy_url) { git_buf processed_url = GIT_BUF_INIT; WINHTTP_PROXY_INFO proxy_info; wchar_t *proxy_wide; if (!git__prefixcmp(proxy_url, SCHEME_HTTP)) { t->proxy_connection_data.use_ssl = false; } else if (!git__prefixcmp(proxy_url, SCHEME_HTTPS)) { t->proxy_connection_data.use_ssl = true; } else { giterr_set(GITERR_NET, "invalid URL: '%s'", proxy_url); return -1; } gitno_connection_data_free_ptrs(&t->proxy_connection_data); if ((error = gitno_extract_url_parts(&t->proxy_connection_data.host, &t->proxy_connection_data.port, NULL, &t->proxy_connection_data.user, &t->proxy_connection_data.pass, proxy_url, NULL)) < 0) goto on_error; if (t->proxy_connection_data.user && t->proxy_connection_data.pass) { if (t->proxy_cred) { t->proxy_cred->free(t->proxy_cred); } if ((error = git_cred_userpass_plaintext_new(&t->proxy_cred, t->proxy_connection_data.user, t->proxy_connection_data.pass)) < 0) goto on_error; } if (t->proxy_connection_data.use_ssl) git_buf_PUTS(&processed_url, SCHEME_HTTPS); else git_buf_PUTS(&processed_url, SCHEME_HTTP); git_buf_puts(&processed_url, t->proxy_connection_data.host); if (t->proxy_connection_data.port) git_buf_printf(&processed_url, ":%s", t->proxy_connection_data.port); if (git_buf_oom(&processed_url)) { giterr_set_oom(); error = -1; goto on_error; } /* Convert URL to wide characters */ error = git__utf8_to_16_alloc(&proxy_wide, processed_url.ptr); git_buf_free(&processed_url); if (error < 0) goto on_error; proxy_info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; proxy_info.lpszProxy = proxy_wide; proxy_info.lpszProxyBypass = NULL; if (!WinHttpSetOption(s->request, WINHTTP_OPTION_PROXY, &proxy_info, sizeof(WINHTTP_PROXY_INFO))) { giterr_set(GITERR_OS, "failed to set proxy"); git__free(proxy_wide); goto on_error; } git__free(proxy_wide); if (t->proxy_cred) { if (t->proxy_cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT) { if ((error = apply_userpass_credential_proxy(s->request, t->proxy_cred)) < 0) goto on_error; } } } /* Disable WinHTTP redirects so we can handle them manually. Why, you ask? * http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/b2ff8879-ab9f-4218-8f09-16d25dff87ae */ if (!WinHttpSetOption(s->request, WINHTTP_OPTION_DISABLE_FEATURE, &disable_redirects, sizeof(disable_redirects))) { giterr_set(GITERR_OS, "failed to disable redirects"); goto on_error; } /* Strip unwanted headers (X-P2P-PeerDist, X-P2P-PeerDistEx) that WinHTTP * adds itself. This option may not be supported by the underlying * platform, so we do not error-check it */ WinHttpSetOption(s->request, WINHTTP_OPTION_PEERDIST_EXTENSION_STATE, &peerdist, sizeof(peerdist)); /* Send Pragma: no-cache header */ if (!WinHttpAddRequestHeaders(s->request, pragma_nocache, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } if (post_verb == s->verb) { /* Send Content-Type and Accept headers -- only necessary on a POST */ git_buf_clear(&buf); if (git_buf_printf(&buf, "Content-Type: application/x-git-%s-request", s->service) < 0) goto on_error; if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert content-type to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } git_buf_clear(&buf); if (git_buf_printf(&buf, "Accept: application/x-git-%s-result", s->service) < 0) goto on_error; if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert accept header to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } } for (i = 0; i < t->owner->custom_headers.count; i++) { if (t->owner->custom_headers.strings[i]) { git_buf_clear(&buf); git_buf_puts(&buf, t->owner->custom_headers.strings[i]); if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) { giterr_set(GITERR_OS, "failed to convert custom header to wide characters"); goto on_error; } if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) { giterr_set(GITERR_OS, "failed to add a header to the request"); goto on_error; } } } /* If requested, disable certificate validation */ if (t->connection_data.use_ssl) { int flags; if (t->owner->parent.read_flags(&t->owner->parent, &flags) < 0) goto on_error; } /* If we have a credential on the subtransport, apply it to the request */ if (t->cred && t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT && apply_userpass_credential(s->request, t->auth_mechanisms, t->cred) < 0) goto on_error; else if (t->cred && t->cred->credtype == GIT_CREDTYPE_DEFAULT && apply_default_credentials(s->request, t->auth_mechanisms) < 0) goto on_error; /* If no other credentials have been applied and the URL has username and * password, use those */ if (!t->cred && t->connection_data.user && t->connection_data.pass) { if (!t->url_cred && git_cred_userpass_plaintext_new(&t->url_cred, t->connection_data.user, t->connection_data.pass) < 0) goto on_error; if (apply_userpass_credential(s->request, GIT_WINHTTP_AUTH_BASIC, t->url_cred) < 0) goto on_error; } /* We've done everything up to calling WinHttpSendRequest. */ error = 0; on_error: if (error < 0) winhttp_stream_close(s); git__free(proxy_url); git_buf_free(&buf); return error; }
khm_int32 HttpRequest::FetchResource(const wchar_t * domain, const wchar_t * resource, const wchar_t ** mimetypes) { HANDLE hFile = INVALID_HANDLE_VALUE; HINTERNET hSession = NULL; HINTERNET hConnect = NULL; HINTERNET hRequest = NULL; DWORD nTotalBytes = 0; BOOL bContinue = TRUE; khm_int32 rv = KHM_ERROR_GENERAL; hSession = WinHttpOpen(USER_AGENT, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession == NULL) { ReportStatus(KHERR_ERROR, L"Can't create HTTP session", L"%s", GetLastErrorString().c_str()); goto done; } hConnect = WinHttpConnect(hSession, domain, INTERNET_DEFAULT_HTTP_PORT, 0); if (hConnect == NULL) { ReportStatus(KHERR_ERROR, L"Can't open HTTP connection", L"%s", GetLastErrorString().c_str()); goto done; } hRequest = WinHttpOpenRequest(hConnect, L"GET", resource, NULL, WINHTTP_NO_REFERER, mimetypes, WINHTTP_FLAG_ESCAPE_PERCENT); if (hRequest == NULL) { ReportStatus(KHERR_ERROR, L"Can't open request", L"%s", GetLastErrorString().c_str()); goto done; } { DWORD opt; opt = WINHTTP_DISABLE_AUTHENTICATION; if (!WinHttpSetOption(hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &opt, sizeof(opt))) goto done; opt = WINHTTP_DISABLE_COOKIES; if (!WinHttpSetOption(hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &opt, sizeof(opt))) goto done; opt = WINHTTP_DISABLE_KEEP_ALIVE; if (!WinHttpSetOption(hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &opt, sizeof(opt))) goto done; } rv = KHM_ERROR_NOT_FOUND; if (!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) { ReportStatus(KHERR_ERROR, L"Can't send request to server", L"Unable to send HTTP request to server at %s.\n" L"%s", domain, GetLastErrorString().c_str()); goto done; } if (!WinHttpReceiveResponse(hRequest, NULL)) { ReportStatus(KHERR_ERROR, L"Error while receiving response", L"%s", GetLastErrorString().c_str()); goto done; } rv = KHM_ERROR_GENERAL; { DWORD status = 0; DWORD nb = sizeof(status); if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &status, &nb, WINHTTP_NO_HEADER_INDEX)) { ReportStatus(KHERR_ERROR, L"Error while querying response status", L"%s", GetLastErrorString().c_str()); goto done; } if (status == HTTP_STATUS_NOT_FOUND) { switch (m_method) { case ByFavIcon: // Status reports are ignored for Favicon searches // anyway. break; case ByGravatar: ReportStatus(KHERR_ERROR, L"Could not find Gravatar", L"An icon could not be found for %s on %s.\n", m_target.c_str(), domain); break; default: ReportStatus(KHERR_ERROR, L"The requested resource was not found", L"The requested resource was not found on %s.", domain); break; } rv = KHM_ERROR_NOT_FOUND; goto done; } if (status != HTTP_STATUS_OK) { ReportStatus(KHERR_ERROR, L"The request failed", L"The server at %s returned an unexpected status (%d)", domain, status); rv = KHM_ERROR_GENERAL; goto done; } } { wchar_t contenttype[128]; DWORD nb = sizeof(contenttype); int i; if (WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_TYPE, WINHTTP_HEADER_NAME_BY_INDEX, contenttype, &nb, WINHTTP_NO_HEADER_INDEX)) { std::wstring::size_type epos; epos = m_path.rfind(L'.'); if (epos != std::wstring::npos) m_path.erase(epos); for (i=0; i < ARRAYLENGTH(content_type_map); i++) { if (!_wcsicmp(contenttype, content_type_map[i].content_type)) break; } if (i < ARRAYLENGTH(content_type_map)) { m_path.append(content_type_map[i].extension); } else { ReportStatus(KHERR_WARNING, L"Unknown content type", L"The content type %s was not expected for this request.", contenttype); } } else { ReportStatus(KHERR_WARNING, L"Could not query response content type", L"%s", GetLastErrorString().c_str()); } } /* The request went through. Create the file now */ hFile = CreateFile(m_path.c_str(), GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_TEMPORARY, NULL); if (hFile == INVALID_HANDLE_VALUE) { ReportStatus(KHERR_ERROR, L"Can't create file", L"%s", GetLastErrorString().c_str()); goto done; } while (nTotalBytes < MAX_ICON_SIZE && bContinue) { DWORD nBytes = 0; BYTE * buffer = NULL; DWORD nRead = 0; DWORD nWritten = 0; bContinue = FALSE; if (!WinHttpQueryDataAvailable(hRequest, &nBytes)) break; if (nBytes == 0) { bContinue = TRUE; break; } if (nBytes + nTotalBytes > MAX_ICON_SIZE) break; buffer = PNEW BYTE[nBytes]; if (buffer == NULL) break; if (!WinHttpReadData(hRequest, buffer, nBytes, &nRead) || nRead == 0) { /* Fail */ } else { /* Data found */ if (WriteFile(hFile, buffer, nRead, &nWritten, NULL)) bContinue = TRUE; } delete [] buffer; nTotalBytes += nBytes; } if (bContinue) { /* Done with file */ rv = KHM_ERROR_SUCCESS; } else { /* File is incomplete */ ReportStatus(KHERR_ERROR, L"Download incomplete", L"The download was terminated unexpectedly."); DeleteFile(m_path.c_str()); } done: if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); ReportComplete(KHM_SUCCEEDED(rv)); return rv; }