wininet C ++的问题

时间:2011-02-03 10:46:21

标签: c++ wininet

有人能在这个功能中找到问题吗? 我的应用程序提出了几个请求,如果第一个请求使用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;
}

感谢。

2 个答案:

答案 0 :(得分:0)

首先,您有Buffer的缓冲区溢出。

考虑以下几点:

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

Buffer[dwRead] = 0;

由于您在前一行中将sizeof(Buffer)作为 dwNumberOfBytesToRead 参数传递,因此dwRead的最大值为sizeof(Buffer)。如果发生这种情况,后一行将在Buffer的末尾写一个字节。您的数据布局不太可能导致崩溃(但这很有可能!),除非您启用了运行时安全检查,这可以解释崩溃消息。

此外,据我所知,“此应用程序已请求运行时以不寻常的方式终止它”消息在Microsoft实现中由assert()terminate()显示。 (我目前没有MSVC可用,无法验证)。我没有在这段代码中看到任何一个的原因,所以如果它不是Buffer溢出,那么也在其他地方寻找它。

答案 1 :(得分:0)

尝试删除strlen:

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

在这种情况下,该功能会更安全一些。

无论如何,请考虑使用Crash Dump Analysis。在这种情况下,您将能够检查来自“某些计算机”的崩溃转储中的callstack。