C++ Wininet 自定义 http 标头

Posted

技术标签:

【中文标题】C++ Wininet 自定义 http 标头【英文标题】:C++ Wininet Custom http headers 【发布时间】:2014-08-14 12:50:40 【问题描述】:

我正在使用 dev c++、Wininet lib 从 Web 下载文件。我正在尝试更改引用者或用户代理。我使用此代码,它成功下载,但我不知道如何更改 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" )

【问题讨论】:

WinInet 文档中的“HTTP Sessions”下提到过。 【参考方案1】:

您将用户代理字符串作为第一个参数传递给InternetOpen

使用HttpOpenRequestHttpSendRequest 代替InternetOpenUrl。引用字符串是HttpOpenRequest的第5个参数

【讨论】:

【参考方案2】:

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 都有一个 headers 参数

以上是关于C++ Wininet 自定义 http 标头的主要内容,如果未能解决你的问题,请参考以下文章

WinInet HttpQueryInfo 可以返回原始字节吗? (带有 unicode 字符的 HTTP 标头)

将文件发送到 HTTP 服务器(C++ Wininet)

如果授权标头不存在,则无法在 Webfilter 中发送自定义正文

将进度条添加到wininet http上传C++

自定义 Authorization HTTP 标头

自定义安全 HTTP 标头是不是违反关注点分离