Высокоуровневая клиентская библиотека HTTP для встроенного C/С++ в Win32

Нет ли "высокоуровневых" HTTP-библиотек для родного C/С++ в Win32, или я просто ищу в неправильных местах?

Под "high-level" я подразумеваю API, который позволяет мне делать HTTP-запросы/ответы HTTP на С++ с "примерно тем же" уровнем абстракции, что и .NET framework (но обратите внимание, что использование С++/CLI не является вариантом для меня).

Как сделать что-то вроде этого (примерно с таким же количеством кода) в C/С++ в Win32 без использования .NET? В качестве ссылки я включаю образец кода, чтобы показать, как я сделаю это на С#.

byte[] fileBytes = null;
bool successfulDownload = false;
using (WebClient client = new WebClient())
{
    WebProxy proxy = WebProxy.GetDefaultProxy();
    client.Proxy = proxy;
tryAgain:
    try
    {
        fileBytes = client.DownloadData(fileUrl);
        successfulDownload = true;
    }
    catch (WebException wEx)
    {
        if (wEx.Response != null && wEx.Response is HttpWebResponse)
        {
            string username = null, password = null;
            bool userCanceled = false;
            HttpStatusCode statusCode = ((HttpWebResponse)wEx.Response).StatusCode;
            switch (statusCode)
            {
                case HttpStatusCode.ProxyAuthenticationRequired:
                    // This is just a convenience function defined elsewhere
                    GetAuthenticationCredentials(fileUrl, true,
                        out username, out password, out userCanceled);
                    if (!userCanceled)
                    {
                        client.Proxy.Credentials = new NetworkCredential(username, password);
                        goto tryAgain;
                    }
                    break;
                case HttpStatusCode.Unauthorized:
                    // This is just a convenience function defined elsewhere
                    GetAuthenticationCredentials(fileUrl, false,
                        out username, out password, out userCanceled);
                    if (!userCanceled)
                    {
                        client.Credentials = new NetworkCredential(username, password);
                        goto tryAgain;
                    }
                    break;
            }
        }
    }
}

Ответ 2

Я думаю, libcurl соответствует этим требованиям. И затем некоторые.

В этом примере показано, как получить страницу HTTP, сохраняя ее только в памяти. Это немного больше кода, чем ваш пример, но он в C.

Ответ 3

Помимо libcurl/curlpp (который является гибким и мощным, но я нахожу очень... clunky) есть две библиотеки С++, на которые я слежу. Оба являются совершенно новыми и основаны на Boost:: ASIO. Тем не менее, ни поддержка прокси (насколько я могу сказать).

cpp-netlib (blog) является возможно, более зрелый (я знаю, что у него было какое-то реальное тестирование), но в настоящее время не хватает тайм-аутов (я над этим работаю!). Пример:

network::http::request  request("http://google.com");
network::http::client   client;
network::http::response response;

response = client.get(request);
if (response.status() == 200)
{
    std::cout << body(response));
}

Urdl (документация) написана создатель ASIO и имеет таймауты (но был объявлен только в прошлом месяце). Он использует другую модель, предпочитая работать с потоками:

urdl::istream is("http://google.com");
std::string line;
while (std::getline(is, line))
{
    std::cout << line << std::endl;
}

Я согласен с тем, что С++ не имеет большой поддержки HTTP, но обе эти библиотеки показывают многообещающие перспективы.

Ответ 4

POCO также имеет межплатформенные сетевые компоненты.

Примеры предоставляют FTP-программу как-то вроде этого (это без ошибок проверки ошибок)

Poco::Net::FTPStreamFactory::registerFactory();
std::ofstream localFile(inputFile, std::ios_base::out | std::ios_base::binary);
Poco::URI uri(inputURL);
std::auto_ptr<std::istream> ptrFtpStream(Poco::Net::URIStreamOpener::defaultOpener().open(uri));
Poco::StreamCopier::copyStream(*ptrFtpStream.get(), localFile);

Ответ 5

Вы не, глядя в неправильные места. Это просто печальная реальность. Вот почему С++-оболочка для libcurl называется curlpp.

Ниже приведена example о том, как извлечь веб-страницу и распечатать ее в потоке stdout.

#include <curlpp/curlpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>


using namespace curlpp::options;

int main(int, char **)
{
  try
  {
    // That all that is needed to do cleanup of used resources (RAII style).
    curlpp::Cleanup myCleanup;

    // Our request to be sent.
    curlpp::Easy myRequest;

    // Set the URL.
    myRequest.setOpt<Url>("http://example.com");

    // Send request and get a result.
    // By default the result goes to standard output.
    myRequest.perform();
  }

  catch(curlpp::RuntimeError & e)
  {
    std::cout << e.what() << std::endl;
  }

  catch(curlpp::LogicError & e)
  {
    std::cout << e.what() << std::endl;
  }

  return 0;
}

Ответ 6

Часть Qt-библиотеки, QtNetwork, также является возможностью.