Проблем с wininet C++

Може ли някой да намери проблем в тази функция? Приложението ми прави няколко заявки и ако първата заявка използва SSL, приложението се срива на някои компютри (на моите 4 компютъра + vmware работи добре без срив).

Ето кода

char Buffer[1024];
DWORD dwRead;
string data;

string Request(string method, string host, string file, string headers,
               string post, bool debug, bool SSL)
{
    HINTERNET hSession, hDownload, hRequest;
    DWORD flag;
    DWORD port;

    data.empty();

    //SSL or not + flag :)
    if (SSL)
    {
        port = INTERNET_DEFAULT_HTTPS_PORT;
        flag = INTERNET_FLAG_SECURE; // FLAG_SECURE
    }
    else
    {
        port = INTERNET_DEFAULT_HTTP_PORT;
        flag = INTERNET_FLAG_RELOAD; //FLAG_RELOAD
    }

    char * postdata;
    postdata = new char[post.size() + 1];
    strcpy(postdata, post.c_str());
    char * headersdata;
    headersdata = new char[headers.size() + 1];
    strcpy(headersdata, headers.c_str());

    //Actual request
    hSession
            = InternetOpen(
                    "Mozilla/5.0 (Windows; U; Windows NT 6.1; sl; rv:1.9.2.11) Gecko/20101012 Firefox/3.6.11",
                    INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    if (hSession)
    {
        hDownload = InternetConnect(hSession, host.c_str(), port, NULL, NULL,
                INTERNET_SERVICE_HTTP, 0, 0);
        if (hDownload)
        {
            hRequest = HttpOpenRequest(hDownload, method.c_str(), file.c_str(),
                    "HTTP/1.1", NULL, NULL, flag, 0);
            if (hRequest)
            {
                if (strlen(headersdata) && strlen(postdata))
                {
                    HttpSendRequest(hRequest, headersdata, strlen(headersdata),
                            postdata, strlen(postdata));
                }
                else
                {
                    HttpSendRequest(hRequest, NULL, 0, NULL, 0);
                }
            }
        }
    }
    //Writing HTML response in data buffer
    while (InternetReadFile(hRequest, Buffer, sizeof(Buffer), &dwRead))
    {
        if (dwRead == 0)
        {
            break;
        }
        Buffer[dwRead] = 0;
        data += Buffer;
    }

    //Debug :)
    if (debug)
    {
        ofstream dbgfile;
        dbgfile.open("debug.html");
        dbgfile << data;
        dbgfile.close();
    }

    //Close handles
    InternetCloseHandle(hSession);
    InternetCloseHandle(hDownload);
    InternetCloseHandle(hRequest);

    return data;
}

Благодаря.


person pwnu91    schedule 03.02.2011    source източник
comment
Каква грешка се дава при възникване на срив? Нарушаване на достъпа? Друг код за грешка?   -  person Matthew Iselin    schedule 03.02.2011
comment
Грешката е Това приложение е поискало от Runtime да го прекрати по необичаен начин. Жалко, че не се случва тук, за да мога да отстранявам грешки :(   -  person pwnu91    schedule 03.02.2011
comment
можете да опитате дистанционно отстраняване на грешки...   -  person smerlin    schedule 03.02.2011


Отговори (2)


Първо, имате препълване на буфер с Buffer.

Помислете за тези редове:

while (InternetReadFile(hRequest, Buffer, sizeof(Buffer), &dwRead))

и

Buffer[dwRead] = 0;

Тъй като предавате sizeof(Buffer) като параметър dwNumberOfBytesToRead в предишния ред, максималната стойност на dwRead е sizeof(Buffer). Ако възникне такъв случай, последният ред ще запише един байт след края на Buffer. Вашето оформление на данните го прави малко вероятно да причини срив (но това е чист шанс!), освен ако не сте активирали проверките за сигурност по време на изпълнение, което може да обясни съобщението за срив.

Освен това, доколкото си спомням, съобщението „Това приложение е поискало от Runtime да го прекрати по необичаен начин“ се показва или от assert(), или от terminate() в изпълнението на Microsoft. (В момента нямам наличен MSVC и не мога да го проверя). Не виждам причината за нито едно от тях в тази част от кода, така че ако не е препълването Buffer, потърсете го и на други места.

person atzz    schedule 03.02.2011
comment
Благодаря, че ми каза, че го поправих :) Но все пак това не решава проблема... :( Не знам защо се срива само на някои машини, а не на всички... - person pwnu91; 05.02.2011

Опитайте да премахнете strlen:

HttpSendRequest(hRequest, &headers.front(), headers.size(),
                 &post.front(), post.size());

В този случай функцията ще бъде малко по-сигурна.

Както и да е, обмислете използването на Анализ на разтоварване при срив . В този случай ще можете да проверите стека за извикване от дъмпа за срив, получен от „някои компютри“.

person Eugene    schedule 07.02.2011