Esempio n. 1
0
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!");
}
Esempio n. 2
0
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);
}