Search code examples
visual-c++boostmfcgzip

InternetReadFile with gzip compression - download and unzip


I'm trying to download a gzip file from a server and unzip it using Boost. I have an exception. _data value has right gzip beginning (1f 8b 08), but unzip did not work. Help please.

CInternetSession isession;
CString url = m_url;
std::string _data;
CString hdrs = _T("Accept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\r\n");
CHttpFile* httpfile = (CHttpFile*)isession.OpenURL(url, 1, INTERNET_FLAG_SECURE |
    INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD, hdrs, hdrs.GetLength());
CString buffer = _T("");

if (httpfile)
{
    DWORD dwStatusCode;
    httpfile->QueryInfoStatusCode(dwStatusCode);
    if (dwStatusCode == 200)
    {
        DWORD rSize;
        char tmp[2048 + 1];
        while (InternetReadFile(*httpfile, tmp, 2048, &rSize) && rSize > 0)
        {
            _data.append(tmp);
            tmp[rSize] = '\0';
            buffer += (CString)tmp;
        }
    }
    httpfile->Close();
    delete httpfile;
}

using namespace boost::iostreams;
filtering_streambuf<input> in;
in.push(gzip_decompressor());
in.push(boost::iostreams::array_source(_data.data(), _data.size()));
std::stringstream _sstream; 

boost::iostreams::copy(in, _sstream);///exception here

std::cout << _sstream.rdbuf(); 

Solution

  • Working code, if it is interesting (raw, no try/catch, but working)

    CString CGenf::parse(CString m_url)
    {
        DWORD bytesRead;
        DWORD totalBytesRead = 0;
        std::vector<char> dataBuffer2;
    
        CInternetSession isession;
        CString url = m_url;
        std::string _data;
        
        int y = 0;
        CString hdrs = _T("Accept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\r\n");
        CHttpFile* httpfile = (CHttpFile*)isession.OpenURL(url, 1, INTERNET_FLAG_SECURE |
            INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD,hdrs,hdrs.GetLength());
        CString buffer = _T("");
    
        if (httpfile)
        {
            DWORD dwStatusCode;
            httpfile->QueryInfoStatusCode(dwStatusCode);
            if (dwStatusCode == 200)
            {
    
                do {
                    char buffer[4096]; // Temporary buffer for reading
                    if (!InternetReadFile(*httpfile, buffer, sizeof(buffer), &bytesRead)) {
                        std::cerr << "InternetReadFile failed" << std::endl;
                        break;
                    }
                    // Append to the vector
                    dataBuffer2.insert(dataBuffer2.end(), buffer, buffer + bytesRead);
                } while (bytesRead > 0);
    
            }
            httpfile->Close();
            delete httpfile;
        }
        //return 0;
    
    
        using namespace std;
        using namespace boost::iostreams;
        std::string s2(dataBuffer2.begin(), dataBuffer2.end());
        boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
        in.push(boost::iostreams::gzip_decompressor());
        in.push(boost::iostreams::array_source(s2.data(), s2.size()));
        std::istream is(&in);
        std::string str((std::istream_iterator<char>(is)), std::istream_iterator<char>());
        CString  temp(str.data());
        return temp;
    }