bool HttpGateway::upload(wstring& server, wstring& uri, wstring& local) { HINTERNET conn = ::InternetConnectW( inetCore, server.c_str(), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 ); LPCWSTR acc[] = { L"*/*", NULL }; HINTERNET req = ::HttpOpenRequestW( conn, L"POST", uri.c_str(), NULL, NULL, acc, 0, INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_NO_AUTO_REDIRECT | INTERNET_FLAG_HYPERLINK ); wstring mac = query_mac_addrw(); wstring headers; headers.append(L"X-mac-addr: "); headers.append(mac); HttpAddRequestHeadersW(req, mac.c_str(), 0, HTTP_ADDREQ_FLAG_ADD_IF_NEW); FILE* f = wfopen(local.c_str(), L"rb"); DWORD bufsize = 1024*100; DWORD totalsize = wfsize(local.c_str()); INTERNET_BUFFERS ib; memset(&ib, 0, sizeof(INTERNET_BUFFERS)); ib.dwStructSize = sizeof(INTERNET_BUFFERS); ib.dwBufferTotal = totalsize; ib.dwBufferLength = bufsize; ::HttpSendRequestEx(req, &ib, NULL, 0, 0); char *buffer = new char[bufsize]; DWORD dwWritten = 0; size_t readBytes = 0; while (!feof(f)) { memset(buffer, 0, bufsize * sizeof(char)); readBytes = fread(buffer, sizeof(char), bufsize, f); ::InternetWriteFile(req, buffer, readBytes, &dwWritten); } fclose(f); ::HttpEndRequest(req, NULL, 0, 0); ::InternetCloseHandle(conn); }
void InetInsertCookies(HTTP_REQUEST_HANDLE *lpReq) { if ((lpReq) && (lpReq->dwType == HTTP_REQUEST)) { EnterSafeCriticalSection(&lpReq->lpUrl->lpSession->csSession); { WCHAR *lpUrl=NULL, *lpPath=NULL, *lpHost=NULL; do { DWORD dwLen=INTERNET_MAX_URL_LENGTH*sizeof(WCHAR); lpUrl=(WCHAR*)MemQuickAlloc(dwLen); if (!lpUrl) break; if (!InternetQueryOptionW(lpReq->hReq,INTERNET_OPTION_URL,lpUrl,&dwLen)) break; lpPath=WCHAR_QuickAlloc(INTERNET_MAX_PATH_LENGTH); if (!lpPath) break; lpHost=WCHAR_QuickAlloc(INTERNET_MAX_HOST_NAME_LENGTH); if (!lpHost) break; URL_COMPONENTSW url={0}; url.dwStructSize=sizeof(url); url.lpszHostName=lpHost; url.dwHostNameLength=INTERNET_MAX_HOST_NAME_LENGTH; url.lpszUrlPath=lpPath; url.dwUrlPathLength=INTERNET_MAX_PATH_LENGTH; if (!InternetCrackUrlW(lpUrl,NULL,0,&url)) break; WCHAR *lpCookies=NULL; if (Cookie_Get(lpReq->lpUrl->lpSession,lpHost,lpPath,&lpCookies,(url.nScheme == INTERNET_SCHEME_HTTPS),url.nPort)) { HttpAddRequestHeadersW(lpReq->hReq,lpCookies,-1,HTTP_ADDREQ_FLAG_ADD); MemFree(lpCookies); } } while (false); MemFree(lpUrl); MemFree(lpPath); MemFree(lpHost); } LeaveSafeCriticalSection(&lpReq->lpUrl->lpSession->csSession); } return; }
BOOL WINAPI my_HttpAddRequestHeadersW(HINTERNET hRequest, LPWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwModifiers) { BOOL Ret; LPWSTR NewHeaders; ENTER_HOOK(); if (NewHeaders = IeCreateContextModifyHeadersW(hRequest, lpszHeaders, dwHeadersLength, NULL, NULL)) lpszHeaders = NewHeaders; Ret = HttpAddRequestHeadersW(hRequest, lpszHeaders, dwHeadersLength, dwModifiers); if (NewHeaders) hFree(NewHeaders); LEAVE_HOOK(); return(Ret); }
BOOL WINAPI DetourHttpSendRequestW(HINTERNET hRequest, LPCWSTR lpszHeaders, DWORD dwHeadersLength, LPVOID lpOptional, DWORD dwOptionalLength) { USES_CONVERSION; // 减少多次转换 if(hwid == L"") { wstring thwid(A2W(GenHWID2().c_str())); hwid = thwid; } if(sn == L"") { wstring tsn(A2W(CSNManager::GetInstance()->GetSN().c_str())); sn = tsn; } TCHAR szBuf[1024]; memset(szBuf, 0, sizeof(szBuf)); swprintf_s(szBuf, L"MoneyhubUID: %s\r\nSN:%s\r\n",hwid.c_str(),sn.c_str()); HttpAddRequestHeadersW(hRequest, szBuf, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); return OldHttpSendRequestW(hRequest, lpszHeaders, dwHeadersLength, lpOptional, dwOptionalLength); }
int64_t Downloader::downloadWin(Job* job, const Request& request, Downloader::Response* response) { QUrl url = request.url; QString verb = request.httpMethod; QFile* file = request.file; QString* mime = &response->mimeType; QString* contentDisposition = &response->contentDisposition; HWND parentWindow = defaultPasswordWindow; QString* sha1 = &response->hashSum; bool useCache = request.useCache; QCryptographicHash::Algorithm alg = request.alg; bool keepConnection = request.keepConnection; int timeout = request.timeout; bool interactive = request.interactive; QString initialTitle = job->getTitle(); job->setTitle(initialTitle + " / " + QObject::tr("Connecting")); if (sha1) sha1->clear(); QString server = url.host(); QString resource = url.path(); QString encQuery = url.query(QUrl::FullyEncoded); if (!encQuery.isEmpty()) resource.append('?').append(encQuery); QString agent("Npackd/"); agent.append(NPACKD_VERSION); agent += " (compatible; MSIE 9.0)"; HINTERNET internet = InternetOpenW((WCHAR*) agent.utf16(), INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0); if (internet == 0) { QString errMsg; WPMUtils::formatMessage(GetLastError(), &errMsg); job->setErrorMessage(errMsg); } if (job->shouldProceed()) { // change the timeout to 5 minutes DWORD rec_timeout = timeout * 1000; InternetSetOption(internet, INTERNET_OPTION_RECEIVE_TIMEOUT, &rec_timeout, sizeof(rec_timeout)); // enable automatic gzip decoding const DWORD INTERNET_OPTION_HTTP_DECODING = 65; BOOL b = TRUE; InternetSetOption(internet, INTERNET_OPTION_HTTP_DECODING, &b, sizeof(b)); job->setProgress(0.01); } HINTERNET hConnectHandle = 0; if (job->shouldProceed()) { INTERNET_PORT port = url.port(url.scheme() == "https" ? INTERNET_DEFAULT_HTTPS_PORT: INTERNET_DEFAULT_HTTP_PORT); hConnectHandle = InternetConnectW(internet, (WCHAR*) server.utf16(), port, 0, 0, INTERNET_SERVICE_HTTP, 0, 0); if (hConnectHandle == 0) { QString errMsg; WPMUtils::formatMessage(GetLastError(), &errMsg); job->setErrorMessage(errMsg); } } // flags: http://msdn.microsoft.com/en-us/library/aa383661(v=vs.85).aspx // We support accepting any mime file type since this is a simple download // of a file HINTERNET hResourceHandle = 0; if (job->shouldProceed()) { LPCTSTR ppszAcceptTypes[2]; ppszAcceptTypes[0] = L"*/*"; ppszAcceptTypes[1] = NULL; DWORD flags = (url.scheme() == "https" ? INTERNET_FLAG_SECURE : 0); if (keepConnection) flags |= INTERNET_FLAG_KEEP_CONNECTION; flags |= INTERNET_FLAG_RESYNCHRONIZE; if (!useCache) flags |= INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD; hResourceHandle = HttpOpenRequestW(hConnectHandle, reinterpret_cast<LPCWSTR>(verb.utf16()), (WCHAR*) resource.utf16(), 0, 0, ppszAcceptTypes, flags, 0); if (hResourceHandle == 0) { QString errMsg; WPMUtils::formatMessage(GetLastError(), &errMsg); job->setErrorMessage(errMsg); } } if (job->shouldProceed()) { job->checkOSCall(HttpAddRequestHeadersW(hResourceHandle, L"Accept-Encoding: gzip, deflate", -1, HTTP_ADDREQ_FLAG_ADD)); } DWORD dwStatus, dwStatusSize = sizeof(dwStatus); // qDebug() << "download.5"; int callNumber = 0; while (job->shouldProceed()) { // qDebug() << "download.5.1"; DWORD sendRequestError = 0; if (!HttpSendRequestW(hResourceHandle, reinterpret_cast<LPCWSTR>(request.headers.utf16()), -1, const_cast<char*>(request.postData.data()), request.postData.length())) { sendRequestError = GetLastError(); } // http://msdn.microsoft.com/en-us/library/aa384220(v=vs.85).aspx if (!HttpQueryInfo(hResourceHandle, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, &dwStatus, &dwStatusSize, NULL)) { QString errMsg; WPMUtils::formatMessage(GetLastError(), &errMsg); job->setErrorMessage(errMsg); break; } /* qDebug() << callNumber << sendRequestError << dwStatus << request.httpMethod << request.url.toString(); */ // 2XX if (sendRequestError == 0) { DWORD hundreds = dwStatus / 100; if (hundreds == 2 || hundreds == 5) break; } // the InternetErrorDlg calls below can either handle // sendRequestError <> 0 or HTTP error code <> 2xx void* p = 0; // both calls to InternetErrorDlg should be enclosed by one // mutex, so that only one dialog will be shown loginDialogMutex.lock(); DWORD r; if (callNumber == 0) { r = InternetErrorDlg(0, hResourceHandle, sendRequestError, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_NO_UI, &p); if (r == ERROR_SUCCESS && interactive) r = ERROR_INTERNET_FORCE_RETRY; } else if (interactive) { if (parentWindow) { r = InternetErrorDlg(parentWindow, hResourceHandle, sendRequestError, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA, &p); } else { QString e = inputPassword(hConnectHandle, dwStatus); //qDebug() << "inputPassword: "******"HTTP status code %1")).arg(dwStatus)); } } else if (r == ERROR_INTERNET_FORCE_RETRY) { // nothing } else if (r == ERROR_CANCELLED) { job->setErrorMessage(QObject::tr("Cancelled by the user")); } else if (r == ERROR_INVALID_HANDLE) { job->setErrorMessage(QObject::tr("Invalid handle")); } else { job->setErrorMessage(QString( QObject::tr("Unknown error %1 from InternetErrorDlg")).arg(r)); } loginDialogMutex.unlock(); if (!job->shouldProceed()) break; // read all the data before re-sending the request char smallBuffer[4 * 1024]; while (true) { DWORD read; if (!InternetReadFile(hResourceHandle, &smallBuffer, sizeof(smallBuffer), &read)) { QString errMsg; WPMUtils::formatMessage(GetLastError(), &errMsg); job->setErrorMessage(errMsg); goto out; } // qDebug() << "read some bytes " << read; if (read == 0) break; } callNumber++; }; // while (job->shouldProceed()) out: if (job->shouldProceed()) { // http://msdn.microsoft.com/en-us/library/aa384220(v=vs.85).aspx if (!HttpQueryInfo(hResourceHandle, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, &dwStatus, &dwStatusSize, NULL)) { QString errMsg; WPMUtils::formatMessage(GetLastError(), &errMsg); job->setErrorMessage(errMsg); } else { // 2XX if (dwStatus / 100 != 2) { job->setErrorMessage(QString( QObject::tr("HTTP status code %1")).arg(dwStatus)); } } } if (job->shouldProceed()) { job->setProgress(0.03); job->setTitle(initialTitle + " / " + QObject::tr("Downloading")); } // MIME type if (job->shouldProceed()) { if (mime) { WCHAR mimeBuffer[1024]; DWORD bufferLength = sizeof(mimeBuffer); DWORD index = 0; if (!HttpQueryInfoW(hResourceHandle, HTTP_QUERY_CONTENT_TYPE, &mimeBuffer, &bufferLength, &index)) { QString errMsg; WPMUtils::formatMessage(GetLastError(), &errMsg); job->setErrorMessage(errMsg); } else { mime->setUtf16((ushort*) mimeBuffer, bufferLength / 2); } } } bool gzip = false; // Content-Encoding if (job->shouldProceed()) { WCHAR contentEncodingBuffer[1024]; DWORD bufferLength = sizeof(contentEncodingBuffer); DWORD index = 0; if (HttpQueryInfoW(hResourceHandle, HTTP_QUERY_CONTENT_ENCODING, &contentEncodingBuffer, &bufferLength, &index)) { QString contentEncoding; contentEncoding.setUtf16((ushort*) contentEncodingBuffer, bufferLength / 2); gzip = contentEncoding == "gzip" || contentEncoding == "deflate"; } job->setProgress(0.04); } // Content-Disposition if (job->shouldProceed()) { if (contentDisposition) { WCHAR cdBuffer[1024]; wcscpy(cdBuffer, L"Content-Disposition"); DWORD bufferLength = sizeof(cdBuffer); DWORD index = 0; if (HttpQueryInfoW(hResourceHandle, HTTP_QUERY_CUSTOM, &cdBuffer, &bufferLength, &index)) { contentDisposition->setUtf16((ushort*) cdBuffer, bufferLength / 2); } } } int64_t contentLength = -1; // content length if (job->shouldProceed()) { WCHAR contentLengthBuffer[100]; DWORD bufferLength = sizeof(contentLengthBuffer); DWORD index = 0; if (HttpQueryInfoW(hResourceHandle, HTTP_QUERY_CONTENT_LENGTH, contentLengthBuffer, &bufferLength, &index)) { QString s; s.setUtf16((ushort*) contentLengthBuffer, bufferLength / 2); bool ok; contentLength = s.toLongLong(&ok, 10); if (!ok) contentLength = 0; } job->setProgress(0.05); } if (job->shouldProceed()) { Job* sub = job->newSubJob(0.95, QObject::tr("Reading the data")); readData(sub, hResourceHandle, file, sha1, gzip, contentLength, alg); if (!sub->getErrorMessage().isEmpty()) job->setErrorMessage(sub->getErrorMessage()); } if (hResourceHandle) InternetCloseHandle(hResourceHandle); if (hConnectHandle) InternetCloseHandle(hConnectHandle); if (internet) InternetCloseHandle(internet); if (job->shouldProceed()) job->setProgress(1); job->setTitle(initialTitle); job->complete(); return contentLength; }
void WinHttpStream::initRequest() { TextParser<wchar_t> parser; if (!parser(L"%1://%[*-_.a-zA-Z0-9:@]2%%[/](*)*3",url)) throw FileOpenError(THISLOCATION,ERROR_FILE_NOT_FOUND,url); String protocol = parser[1].str(); String hostident = parser[2].str(); String::SplitIterator hostidentsplit = hostident.split('@'); String ident; String domain; domain = hostidentsplit.getNext(); while (hostidentsplit.hasItems()) { ident = ident + domain + ConstStrW('@'); domain = hostidentsplit.getNext(); } String path = parser[3].str(); natural port; String username; String password; bool secure; if (parser( L"%1:%u2",domain)) { domain = parser[1].str(); port = parser[2]; secure = false; } else if (protocol == ConstStrW(L"http")) { port = INTERNET_DEFAULT_HTTP_PORT; secure = false; } else if (protocol == ConstStrW(L"https")) { port = INTERNET_DEFAULT_HTTPS_PORT; secure = true; } else throw FileOpenError(THISLOCATION,ERROR_NOT_FOUND,url); if (!ident.empty()) { if (parser(L"%1:%2@",ident)) { username = parser[1].str(); password = parser[2].str(); } else { throw FileMsgException(THISLOCATION,0,url,"Invalid identification field in the url"); } } DWORD accessType; switch (settings.proxyMode) { case pmManual: accessType = INTERNET_OPEN_TYPE_PROXY; case pmDirect: accessType = INTERNET_OPEN_TYPE_DIRECT; case pmAuto: accessType = INTERNET_OPEN_TYPE_PRECONFIG; } TextFormatBuff<wchar_t> fmt; String proxyName; if (accessType == INTERNET_OPEN_TYPE_PROXY) { fmt(L"%1:%2") << settings.proxyAddr << settings.proxyPort; proxyName = fmt.write(); } if (hInternet) InternetCloseHandle(hInternet); hInternet = InternetOpenW(settings.userAgent.cStr(),accessType,proxyName.cStr(),0,0); if (hInternet == 0) throw FileMsgException(THISLOCATION,GetLastError(),url,"Cannot initialize WinInet"); if (hConnect) InternetCloseHandle(hConnect); hConnect = InternetConnectW(hInternet,domain.cStr(),(INTERNET_PORT)port, username.empty()?0:username.cStr(), password.empty()?0:password.cStr(), INTERNET_SERVICE_HTTP ,0,0); if (hConnect == 0) throw FileMsgException(THISLOCATION,GetLastError(),url,"Cannot connect remote site"); DWORD reqFlags = INTERNET_FLAG_NO_UI |INTERNET_FLAG_HYPERLINK ; if (redirDisabled) reqFlags|=INTERNET_FLAG_NO_AUTO_REDIRECT ; if (!settings.cookiesEnabled) reqFlags|=INTERNET_FLAG_NO_COOKIES; if (secure) reqFlags|=INTERNET_FLAG_SECURE; hHTTPConn = HttpOpenRequestW(hConnect,String(method).cStr(),path.cStr(), 0,0,0,reqFlags,0); if (hHTTPConn == 0) throw FileMsgException(THISLOCATION,GetLastError(),url,"Cannot connect remote site"); AutoArray<wchar_t> hdrall; for (HeaderMap::Iterator iter = hdrmap.getFwIter(); iter.hasItems();) { const HeaderMap::Entity &e = iter.getNext(); fmt(L"%1: %2\n") << e.key << e.value; hdrall.append(fmt.write()); } if (!hdrall.empty() && !HttpAddRequestHeadersW(hHTTPConn,hdrall.data(),(DWORD)hdrall.length(),HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDREQ_FLAG_ADD)) throw FileMsgException(THISLOCATION,GetLastError(),url,"AddRequest failed"); if (!HttpSendRequestW(hHTTPConn,0,0,postBuffer.data(),(DWORD)postBuffer.length())) { bool stillError = true; DWORD dwError = GetLastError(); if (dwError == ERROR_INTERNET_INVALID_CA && settings.allowUntrustedCert) { DWORD dwFlags; DWORD dwBuffLen = sizeof(dwFlags); InternetQueryOption (hHTTPConn, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&dwFlags, &dwBuffLen); dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA; InternetSetOption (hHTTPConn, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags) ); if (HttpSendRequestW(hHTTPConn,0,0,postBuffer.data(),(DWORD)postBuffer.length())) stillError = false; } if (stillError) throw FileMsgException(THISLOCATION,GetLastError(),url,"Failed to SendRequest"); } postBuffer.clear(); }