C++ Wininet 自定义 HTTP 标头

3
我正在使用dev c++和Wininet库从web下载文件。我想要更改referer或user agent,我使用了这段代码,成功地下载了文件,但我不知道如何更改http头。谢谢。
#include <Windows.h>
#include <Wininet.h>
#include <iostream>
#include <fstream>

namespace {

    ::HINTERNET netstart ()
    {
        const ::HINTERNET handle =
            ::InternetOpenW(0, INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0);
        if ( handle == 0 )
        {
            const ::DWORD error = ::GetLastError();
            std::cerr
                << "InternetOpen(): " << error << "."
                << std::endl;
        }
        return (handle);
    }

    void netclose ( ::HINTERNET object )
    {
        const ::BOOL result = ::InternetCloseHandle(object);
        if ( result == FALSE )
        {
            const ::DWORD error = ::GetLastError();
            std::cerr
                << "InternetClose(): " << error << "."
                << std::endl;
        }
    }

    ::HINTERNET netopen ( ::HINTERNET session, ::LPCWSTR url )
    {
        const ::HINTERNET handle =
            ::InternetOpenUrlW(session, url, 0, 0, 0, 0);
        if ( handle == 0 )
        {
            const ::DWORD error = ::GetLastError();
            std::cerr
                << "InternetOpenUrl(): " << error << "."
                << std::endl;
        }
        return (handle);
    }

    void netfetch ( ::HINTERNET istream, std::ostream& ostream )
    {
        static const ::DWORD SIZE = 1024;
        ::DWORD error = ERROR_SUCCESS;
        ::BYTE data[SIZE];
        ::DWORD size = 0;
        do {
            ::BOOL result = ::InternetReadFile(istream, data, SIZE, &size);
            if ( result == FALSE )
            {
                error = ::GetLastError();
                std::cerr
                    << "InternetReadFile(): " << error << "."
                    << std::endl;
            }
            ostream.write((const char*)data, size);
        }
        while ((error == ERROR_SUCCESS) && (size > 0));
    }

}

int main ( int, char ** )
{
    const ::WCHAR URL[] = L"http://google.com";
    const ::HINTERNET session = ::netstart();
    if ( session != 0 )
    {
        const ::HINTERNET istream = ::netopen(session, URL);
        if ( istream != 0 )
        {
            std::ofstream ostream("googleindex.html", std::ios::binary);
            if ( ostream.is_open() ) {
                ::netfetch(istream, ostream);
            }
            else {
                std::cerr << "Could not open 'googleindex.html'." << std::endl;
            }
            ::netclose(istream);
        }
        ::netclose(session);
    }
}

#pragma comment ( lib, "Wininet.lib" )

1
在WinInet文档的“HTTP会话”部分中提到了这一点。 - molbdnilo
2个回答

1
你需要将用户代理字符串作为第一个参数传递给InternetOpen
使用HttpOpenRequestHttpSendRequest替换InternetOpenUrl。 Referer字符串是HttpOpenRequest的第5个参数。

1
InternetOpenUrl的第三个参数是lpszHeaders [in](来自MSDN):

一个指向以空字符结尾的字符串的指针,该字符串指定要发送到HTTP服务器的标头。有关详细信息,请参阅HttpSendRequest函数中lpszHeaders参数的描述。

您可以像这样设置Referer和User agent:
LPWSTR headers = L"User-Agent: myagent\r\nReferer: my.referer.com\r\n\r\n\r\n";
//and then call
::InternetOpenUrlW(session, url, headers, -1, 0, 0);

您必须用\r\n分隔每个标题,并用\r\n\r\n关闭该块。


值得注意的是,InternetOpenUrl和HttpSendRequest都有一个头参数。 - hack-tramp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接