void FetchThread::run() { string headers; DWORD flags = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_COOKIES; if (!m_client->m_bRedirect) flags |= INTERNET_FLAG_NO_AUTO_REDIRECT; const char *verb = "GET"; unsigned postSize = m_client->m_client->post_size(); if (postSize != NO_POSTSIZE) verb = "POST"; URL_COMPONENTSA url; memset(&url, 0, sizeof(url)); url.dwStructSize = sizeof(url); char host[256]; url.lpszHostName = host; url.dwHostNameLength = sizeof(host); char user[256]; url.lpszUserName = user; url.dwUserNameLength = sizeof(user); char pass[256]; url.lpszPassword = pass; url.dwPasswordLength = sizeof(pass); char urlPath[1024]; url.lpszUrlPath = urlPath; url.dwUrlPathLength = sizeof(urlPath); char extra[1024]; url.lpszExtraInfo = extra; url.dwExtraInfoLength = sizeof(extra); if (!_InternetCrackUrl(m_client->m_uri.c_str(), 0, ICU_DECODE, &url)){ error("InternetCrackUrl"); return; } if (url.nScheme == INTERNET_SCHEME_HTTPS){ flags |= INTERNET_FLAG_SECURE; }else if (url.nScheme != INTERNET_SCHEME_HTTP){ error("Unsupported scheme"); return; } hCon = _InternetConnect(hInet, url.lpszHostName, url.nPort, url.lpszUserName, url.lpszPassword, INTERNET_SERVICE_HTTP, 0, 0); if (hCon == NULL){ error("InternetConnect"); return; } string uri = url.lpszUrlPath; if (url.lpszExtraInfo) uri += url.lpszExtraInfo; hReq = _HttpOpenRequest(hCon, verb, uri.c_str(), NULL, NULL, NULL, flags, 0); if (hReq == NULL){ error("HttpOpenRequest error"); return; } for (HEADERS_MAP::iterator it = m_client->m_hOut.begin(); it != m_client->m_hOut.end(); ++it){ string name = (*it).first.c_str(); if (!headers.empty()) headers += "\r\n"; headers += name; headers += ": "; headers += (*it).second.c_str(); } Buffer b; b.packetStart(); b << verb << " " << uri.c_str() << " HTTP/1.0\r\n" << headers.c_str() << "\r\n"; log_packet(b, true, HTTPPacket); for (;;){ if (postSize != NO_POSTSIZE){ INTERNET_BUFFERSA BufferIn; memset(&BufferIn, 0, sizeof(BufferIn)); BufferIn.dwStructSize = sizeof(INTERNET_BUFFERSA); BufferIn.lpcszHeader = headers.c_str(); BufferIn.dwHeadersLength = headers.length(); BufferIn.dwHeadersTotal = headers.length(); BufferIn.dwBufferTotal = (postSize != NO_POSTSIZE) ? postSize : 0; if (!_HttpSendRequestEx(hReq, &BufferIn, NULL, HSR_INITIATE | HSR_SYNC, 0)){ error("HttpSendRequestEx"); return; } unsigned size = postSize; while (size){ char buff[4096]; unsigned tail = size; if (tail > sizeof(buff)) tail = sizeof(buff); const char *data = m_client->m_client->read_data(buff, tail); if (data == NULL){ error("ReadStreamError"); return; } DWORD res; if (m_bClose) return; if (!_InternetWriteFile(hReq, (void*)data, tail, &res)){ error("InternetWriteFile"); return; } if (m_client->m_speed){ m_client->m_sendSize += tail; time_t now; time(&now); if ((unsigned)now != m_client->m_sendTime){ m_client->m_sendTime = now; m_client->m_sendSize = 0; } if (m_client->m_sendSize > (m_client->m_speed << 18)){ Sleep(1000); return; } } size -= tail; } if (m_bClose) return; if(!_HttpEndRequest(hReq, NULL, 0, 0)){ error("HttpEndRequest"); return; } }else{ if (!_HttpSendRequest(hReq, headers.c_str(), headers.length(), NULL, 0)){ error("HttpSendRequest"); return; } } DWORD dwCode; DWORD dwSize = sizeof(dwCode); _HttpQueryInfo (hReq, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwSize, NULL); if (dwCode != HTTP_STATUS_PROXY_AUTH_REQ) break; DWORD res = _InternetErrorDlg (GetDesktopWindow(), hReq, ERROR_INTERNET_INCORRECT_PASSWORD, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, NULL); if (res != ERROR_INTERNET_FORCE_RETRY) break; } DWORD size = 0; DWORD err = 0; _HttpQueryInfo(hReq, HTTP_QUERY_RAW_HEADERS_CRLF, NULL, &size, 0); err = GetLastError(); if (err != ERROR_INSUFFICIENT_BUFFER ){ error("HttpQueryInfo"); return; } Buffer in_headers; in_headers.packetStart(); in_headers.init(size); if (!_HttpQueryInfo(hReq, HTTP_QUERY_RAW_HEADERS_CRLF, in_headers.data(), &size, 0)){ error("HttpQueryInfo"); return; } in_headers.setWritePos(size); log_packet(in_headers, false, HTTPPacket); string line; bool bFirst = true; for (; in_headers.readPos() < in_headers.writePos(); ){ if (!in_headers.scan("\r\n", line)){ line = ""; unsigned size = in_headers.writePos() - in_headers.readPos(); line.append(size, '\x00'); in_headers.unpack((char*)line.c_str(), size); } if (bFirst){ bFirst = false; getToken(line, ' '); m_client->m_code = atol(line.c_str()); continue; } m_client->m_hIn += line; m_client->m_hIn += '\x00'; } if (bFirst){ error("Bas answer"); return; } for (;;){ DWORD readn; char buff[4096]; if (!_InternetReadFile(hReq, buff, sizeof(buff), &readn)){ error("InternetReadFile"); return; } if (m_bClose) return; if (readn == 0) break; if (!m_client->m_client->write_data(buff, readn)){ error("Write error"); return; } } /* Signals / Slots aren't thread-safe - need to use an event */ close(); QCustomEvent* ce = new QCustomEvent(Q_EVENT_SIM_FETCH_DONE); ce->setData(m_client->m_client); postEvent(m_client, ce); log(L_DEBUG,"EventPosted!"); }
void FetchThread::run() { log(L_DEBUG, "fetch"); string headers; DWORD flags = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_COOKIES; if (!m_client->m_bRedirect) flags |= INTERNET_FLAG_NO_AUTO_REDIRECT; const char *verb = "GET"; unsigned postSize = m_client->m_client->post_size(); if (postSize != NO_POSTSIZE) verb = "POST"; log(L_DEBUG, "URL: %s", m_client->m_uri.c_str()); URL_COMPONENTSA url; memset(&url, 0, sizeof(url)); url.dwStructSize = sizeof(url); char host[256]; url.lpszHostName = host; url.dwHostNameLength = sizeof(host); char user[256]; url.lpszUserName = user; url.dwUserNameLength = sizeof(user); char pass[256]; url.lpszPassword = pass; url.dwPasswordLength = sizeof(pass); char urlPath[1024]; url.lpszUrlPath = urlPath; url.dwUrlPathLength = sizeof(urlPath); char extra[1024]; url.lpszExtraInfo = extra; url.dwExtraInfoLength = sizeof(extra); if (!_InternetCrackUrl(m_client->m_uri.c_str(), 0, ICU_DECODE, &url)){ error("InternetCrackUrl"); return; } if (url.nScheme == INTERNET_SCHEME_HTTPS){ flags |= INTERNET_FLAG_SECURE; }else if (url.nScheme != INTERNET_SCHEME_HTTP){ error("Unsupported scheme"); return; } hCon = _InternetConnect(hInet, url.lpszHostName, url.nPort, url.lpszUserName, url.lpszPassword, INTERNET_SERVICE_HTTP, 0, 0); if (hCon == NULL){ error("InternetConnect"); return; } string uri = url.lpszUrlPath; if (url.lpszExtraInfo) uri += url.lpszExtraInfo; hReq = _HttpOpenRequest(hCon, verb, uri.c_str(), NULL, NULL, NULL, flags, 0); if (hReq == NULL){ error("HttpOpenRequest error"); return; } for (HEADERS_MAP::iterator it = m_client->m_hOut.begin(); it != m_client->m_hOut.end(); ++it){ string name = (*it).first.c_str(); if (!headers.empty()) headers += "\r\n"; headers += name; headers += ": "; headers += (*it).second.c_str(); } if (postSize != NO_POSTSIZE){ INTERNET_BUFFERSA BufferIn; memset(&BufferIn, 0, sizeof(BufferIn)); BufferIn.dwStructSize = sizeof(INTERNET_BUFFERSA); BufferIn.lpcszHeader = headers.c_str(); BufferIn.dwHeadersLength = headers.length(); BufferIn.dwHeadersTotal = headers.length(); BufferIn.dwBufferTotal = (postSize != NO_POSTSIZE) ? postSize : 0; if (!_HttpSendRequestEx(hReq, &BufferIn, NULL, HSR_INITIATE | HSR_SYNC, 0)){ error("HttpSendRequestEx"); return; } while (postSize){ char buff[4096]; unsigned tail = postSize; if (tail > sizeof(buff)) tail = sizeof(buff); const char *data = m_client->m_client->read_data(buff, tail); if (data == NULL){ error("ReadStreamError"); return; } DWORD res; if (m_bClose) return; if (!_InternetWriteFile(hReq, (void*)data, tail, &res)){ error("InternetWriteFile"); return; } if (m_client->m_speed){ m_client->m_sendSize += tail; time_t now; time(&now); if ((unsigned)now != m_client->m_sendTime){ m_client->m_sendTime = now; m_client->m_sendSize = 0; } if (m_client->m_sendSize > (m_client->m_speed << 18)){ Sleep(1000); return; } } postSize -= tail; } if (m_bClose) return; if(!_HttpEndRequest(hReq, NULL, 0, 0)){ error("HttpEndRequest"); return; } }else{ if (!_HttpSendRequest(hReq, headers.c_str(), headers.length(), NULL, 0)){ error("HttpSendRequest"); return; } } DWORD size = 0; DWORD err = 0; _HttpQueryInfo(hReq, HTTP_QUERY_RAW_HEADERS_CRLF, NULL, &size, 0); err = GetLastError(); if (err != ERROR_INSUFFICIENT_BUFFER ){ error("HttpQueryInfo"); return; } Buffer in_headers; in_headers.init(size); if (!_HttpQueryInfo(hReq, HTTP_QUERY_RAW_HEADERS_CRLF, in_headers.data(), &size, 0)){ error("HttpQueryInfo"); return; } in_headers.setWritePos(size); string line; bool bFirst = true; for (; in_headers.readPos() < in_headers.writePos(); ){ if (!in_headers.scan("\r\n", line)){ line = ""; unsigned size = in_headers.writePos() - in_headers.readPos(); line.append(size, '\x00'); in_headers.unpack((char*)line.c_str(), size); } if (bFirst){ bFirst = false; getToken(line, ' '); m_client->m_code = atol(line.c_str()); continue; } m_client->m_hIn += line; m_client->m_hIn += '\x00'; } if (bFirst){ error("Bas answer"); return; } for (;;){ DWORD readn; char buff[4096]; if (!_InternetReadFile(hReq, buff, sizeof(buff), &readn)){ error("InternetReadFile"); return; } if (m_bClose) return; if (readn == 0) break; if (!m_client->m_client->write_data(buff, readn)){ error("Write error"); return; } } m_client->m_state = FetchClientPrivate::Done; close(); FetchManager::manager->done(m_client->m_client); }