添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams No, there's currently no built-in support either via the language or the standard library for networking. However, there's a Networking TS N4370 . I also VTC'd this question since it's attracting library recommendations. user3920237 Mar 11, 2015 at 9:22 @user3920237 Fortunately, most of the people dont think destructively, to VTC the useful question. These are made for people's usage, let it be library. T.Todua Sep 17, 2020 at 18:19

I had the same problem. libcurl is really complete. There is a C++ wrapper curlpp that might interest you as you ask for a C++ library. neon is another interesting C library that also support WebDAV .

curlpp seems natural if you use C++. There are many examples provided in the source distribution. To get the content of an URL you do something like that (extracted from examples) :

// Edit : rewritten for cURLpp 0.7.3
// Note : namespace changed, was cURLpp in 0.7.2 ...
#include <curlpp/cURLpp.hpp>
#include <curlpp/Options.hpp>
// RAII cleanup
curlpp::Cleanup myCleanup;
// Send request and get a result.
// Here I use a shortcut to get it in a string stream ...
std::ostringstream os;
os << curlpp::options::Url(std::string("http://example.com"));
string asAskedInQuestion = os.str();

See the examples directory in curlpp source distribution, there is a lot of more complex cases, as well as a simple complete minimal one using curlpp.

my 2 cents ...

latest version seems to be broken under mac.. something is messed up with config.h when linked as library. – eugene Apr 8, 2011 at 0:59 Well, I could not compile the above. However, replacing os << myRequest.perform(); with myRequest.setOpt( new curlpp::options::WriteStream( &os ) ); myRequest.perform(); gave results. Make sure to not use http://example.com, this will return an empty page. Better use e.g. http://www.wikipedia.org. – Zane Nov 4, 2012 at 14:22 I don't agree with the latest edit by @ryan-sam. It clearly was the intention of the author to write "webdav" and not web development as the given library is made explicitly for "HTTP and WebDAV operations". – Bostrot Dec 5, 2018 at 11:20 @bostrot: Yep that what I meant. I reverted and added a link, I think people thought I wrote webdev. What a pity :) – neuro Dec 5, 2018 at 13:43 //HTTP GET string get_http = "GET / HTTP/1.1\r\nHost: " + url + "\r\nConnection: close\r\n\r\n"; if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0){ cout << "WSAStartup failed.\n"; system("pause"); //return 1; Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); host = gethostbyname(url.c_str()); SockAddr.sin_port=htons(80); SockAddr.sin_family=AF_INET; SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr); if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0){ cout << "Could not connect"; system("pause"); //return 1; // send GET / HTTP send(Socket,get_http.c_str(), strlen(get_http.c_str()),0 ); // recieve html while ((nDataLength = recv(Socket,buffer,10000,0)) > 0){ int i = 0; while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r'){ website_HTML+=buffer[i]; i += 1; closesocket(Socket); WSACleanup(); // Display HTML source cout<<website_HTML; // pause cout<<"\n\nPress ANY key to close.\n\n"; cin.ignore(); cin.get(); return 0;

Here is a much better implementation:

#include <windows.h>
#include <string>
#include <stdio.h>
using std::string;
#pragma comment(lib,"ws2_32.lib")
HINSTANCE hInst;
WSADATA wsaData;
void mParseUrl(char *mUrl, string &serverName, string &filepath, string &filename);
SOCKET connectToServer(char *szServerName, WORD portNum);
int getHeaderLength(char *content);
char *readUrl2(char *szUrl, long &bytesReturnedOut, char **headerOut);
int main()
    const int bufLen = 1024;
    char *szUrl = "http://stackoverflow.com";
    long fileSize;
    char *memBuffer, *headerBuffer;
    FILE *fp;
    memBuffer = headerBuffer = NULL;
    if ( WSAStartup(0x101, &wsaData) != 0)
        return -1;
    memBuffer = readUrl2(szUrl, fileSize, &headerBuffer);
    printf("returned from readUrl\n");
    printf("data returned:\n%s", memBuffer);
    if (fileSize != 0)
        printf("Got some data\n");
        fp = fopen("downloaded.file", "wb");
        fwrite(memBuffer, 1, fileSize, fp);
        fclose(fp);
         delete(memBuffer);
        delete(headerBuffer);
    WSACleanup();
    return 0;
void mParseUrl(char *mUrl, string &serverName, string &filepath, string &filename)
    string::size_type n;
    string url = mUrl;
    if (url.substr(0,7) == "http://")
        url.erase(0,7);
    if (url.substr(0,8) == "https://")
        url.erase(0,8);
    n = url.find('/');
    if (n != string::npos)
        serverName = url.substr(0,n);
        filepath = url.substr(n);
        n = filepath.rfind('/');
        filename = filepath.substr(n+1);
        serverName = url;
        filepath = "/";
        filename = "";
SOCKET connectToServer(char *szServerName, WORD portNum)
    struct hostent *hp;
    unsigned int addr;
    struct sockaddr_in server;
    SOCKET conn;
    conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (conn == INVALID_SOCKET)
        return NULL;
    if(inet_addr(szServerName)==INADDR_NONE)
        hp=gethostbyname(szServerName);
        addr=inet_addr(szServerName);
        hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
    if(hp==NULL)
        closesocket(conn);
        return NULL;
    server.sin_addr.s_addr=*((unsigned long*)hp->h_addr);
    server.sin_family=AF_INET;
    server.sin_port=htons(portNum);
    if(connect(conn,(struct sockaddr*)&server,sizeof(server)))
        closesocket(conn);
        return NULL;
    return conn;
int getHeaderLength(char *content)
    const char *srchStr1 = "\r\n\r\n", *srchStr2 = "\n\r\n\r";
    char *findPos;
    int ofset = -1;
    findPos = strstr(content, srchStr1);
    if (findPos != NULL)
        ofset = findPos - content;
        ofset += strlen(srchStr1);
        findPos = strstr(content, srchStr2);
        if (findPos != NULL)
            ofset = findPos - content;
            ofset += strlen(srchStr2);
    return ofset;
char *readUrl2(char *szUrl, long &bytesReturnedOut, char **headerOut)
    const int bufSize = 512;
    char readBuffer[bufSize], sendBuffer[bufSize], tmpBuffer[bufSize];
    char *tmpResult=NULL, *result;
    SOCKET conn;
    string server, filepath, filename;
    long totalBytesRead, thisReadSize, headerLen;
    mParseUrl(szUrl, server, filepath, filename);
    ///////////// step 1, connect //////////////////////
    conn = connectToServer((char*)server.c_str(), 80);
    ///////////// step 2, send GET request /////////////
    sprintf(tmpBuffer, "GET %s HTTP/1.0", filepath.c_str());
    strcpy(sendBuffer, tmpBuffer);
    strcat(sendBuffer, "\r\n");
    sprintf(tmpBuffer, "Host: %s", server.c_str());
    strcat(sendBuffer, tmpBuffer);
    strcat(sendBuffer, "\r\n");
    strcat(sendBuffer, "\r\n");
    send(conn, sendBuffer, strlen(sendBuffer), 0);
//    SetWindowText(edit3Hwnd, sendBuffer);
    printf("Buffer being sent:\n%s", sendBuffer);
    ///////////// step 3 - get received bytes ////////////////
    // Receive until the peer closes the connection
    totalBytesRead = 0;
    while(1)
        memset(readBuffer, 0, bufSize);
        thisReadSize = recv (conn, readBuffer, bufSize, 0);
        if ( thisReadSize <= 0 )
            break;
        tmpResult = (char*)realloc(tmpResult, thisReadSize+totalBytesRead);
        memcpy(tmpResult+totalBytesRead, readBuffer, thisReadSize);
        totalBytesRead += thisReadSize;
    headerLen = getHeaderLength(tmpResult);
    long contenLen = totalBytesRead-headerLen;
    result = new char[contenLen+1];
    memcpy(result, tmpResult+headerLen, contenLen);
    result[contenLen] = 0x0;
    char *myTmp;
    myTmp = new char[headerLen+1];
    strncpy(myTmp, tmpResult, headerLen);
    myTmp[headerLen] = NULL;
    delete(tmpResult);
    *headerOut = myTmp;
    bytesReturnedOut = contenLen;
    closesocket(conn);
    return(result);
                Tried this code on a Windows Vista compiling with Dev-C++ Version 4.9.9.2. I gave me a bunch of errors when linking:   [Linker error] undefined reference to `WSAStartup@8'
– tzengia
                Apr 2, 2014 at 20:15
                @Expanding-Dev Only MSVC (visual studio) understands "pragma comment". If you use anything else you must link "ws2_32.lib" manually (like any other library).
– Navin
                May 15, 2014 at 18:37
                What is supposed to be received (using recv) here? I am getting a lot of gibberish as output. Also, why did you put what you did in the send buffer (e.g. GET / HTTP/1.1.1/... etc)? How do I find out how to format what I send?
– LazerSharks
                Sep 8, 2014 at 0:27

Update 2020: I have a new answer that replaces this, now 8-years-old, one: https://stackoverflow.com/a/61177330/278976

On Linux, I tried cpp-netlib, libcurl, curlpp, urdl, boost::asio and considered Qt (but turned it down based on the license). All of these were either incomplete for this use, had sloppy interfaces, had poor documentation, were unmaintained or didn't support https.

Then, at the suggestion of https://stackoverflow.com/a/1012577/278976, I tried POCO. Wow, I wish I had seen this years ago. Here's an example of making an HTTP GET request with POCO:

https://stackoverflow.com/a/26026828/2817595

POCO is free, open source (boost license). And no, I don't have any affiliation with the company; I just really like their interfaces. Great job guys (and gals).

https://pocoproject.org/download.html

Hope this helps someone... it took me three days to try all of these libraries out.

Here's an additional example: github.com/pocoproject/poco/blob/develop/Net/samples/httpget/… – Homer6 Jan 10, 2014 at 21:32 I just downloaded Poco on your suggestion. I would prefer something light that builds on STL and boost rather than rewrite much of it. Plus I'm not a fan of CppUnit and in particular hate tests running with the build, and don't expect to have to test their library as I build it. – CashCow Feb 25, 2014 at 21:30 It is a little big. However, you can disable building the tests and samples (or shared libraries) with configure (ie. --no-tests or --no-samples or --no-sharedlibs). See github.com/pocoproject/poco/blob/develop/configure – Homer6 Feb 25, 2014 at 22:34 thank you for that. I want it anyway as I care about getting done the tasks I need to do. And I note they have JSON parsing there too which is good as I will need to do that after sending the HTTP request which is what I got the library for. – CashCow Feb 26, 2014 at 13:37 @Hack06 Thanks for the comment. I've provided a new answer that now replaces this one: stackoverflow.com/a/61177330/278976 – Homer6 Apr 12, 2020 at 19:58

There is a newer, less mature curl wrapper being developed called C++ Requests. Here's a simple GET request:

#include <iostream>
#include <cpr.h>
int main(int argc, char** argv) {
    auto response = cpr::Get(cpr::Url{"http://httpbin.org/get"});
    std::cout << response.text << std::endl;

It supports a wide variety of HTTP verbs and curl options. There's more usage documentation here.

Disclaimer: I'm the maintainer of this library.

I was at your CppCon 2015 lightning talk yesterday. Well done--both the talk and the library. I particularly like the "Curl for people" design philosophy. – U007D Sep 23, 2015 at 13:59 Hello, I just came across this post here, looking for easier C++ HTTP requests than the plain way. However, I am not really experienced with libraries, and I don't really know how to include this in my visual studio C++ project. Is there any explanation somewhere? I feel like it's not specific to the library, but rather that I don't really know what to do with what I have in front of me now in general. – Sossenbinder Jan 17, 2016 at 21:18 @Sossenbinder, if you can familiarize yourself with CMake, you can generate Visual Studio build files for this project using that. The appveyor configuration file contains a rough example of how to accomplish this. – huu Feb 4, 2016 at 3:41 Looks nice, but building is hell, so your lib is useless, I can't rely on package manager (need reliable way how to add deps externally) and need functional lib as soon as possible ... – dev1223 Sep 15, 2016 at 12:43 that's how you do it. when you compare this to the 200 lines of the second most upvoted answer....... – v.oddou Apr 11, 2018 at 15:57

Updated answer for April, 2020:

I've had a lot of success, recently, with cpp-httplib (both as a client and a server). It's mature and its approximate, single-threaded RPS is around 6k.

On more of the bleeding edge, there's a really promising framework, cpv-framework, that can get around 180k RPS on two cores (and will scale well with the number of cores because it's based on the seastar framework, which powers the fastest DBs on the planet, scylladb).

However, cpv-framework is still relatively immature; so, for most uses, I highly recommend cpp-httplib.

This recommendation replaces my previous answer (8 years ago).

I really like the 1-file (5K-lines is ok) approach of cpp-httplib. Do you have an idea about its performance? – Hack06 May 3, 2020 at 15:44 This library(cpp-httplib) doesn't work below windows 8 ... The error messages are also not very helpful. Also I don't like the idea that I must need a ca-bundle.crt for ssl connection. For client side it's not necessary – Imtiaz Shakil Siddique Mar 28, 2021 at 18:03 i feel crazy coming from c# where a simple http request is sooo easy, cpp-httplib like others, you have to jump through so many hoops just to get it to where you can make a simple https call – ZackOfAllTrades Nov 4, 2021 at 18:25 @ImtiazShakilSiddique Well now, you don't need to care about "below Windows 8" :), the library seems to work fine for me on Windows 10 and 11. – user13944038 Jul 28, 2022 at 15:40

Here is my minimal wrapper around cURL to be able just to fetch a webpage as a string. This is useful, for example, for unit testing. It is basically a RAII wrapper around the C code.

Install "libcurl" on your machine yum install libcurl libcurl-devel or equivalent.

Usage example:

CURLplusplus client;
string x = client.Get("http://google.com");
string y = client.Get("http://yahoo.com");

Class implementation:

#include <curl/curl.h>
class CURLplusplus
private:
    CURL* curl;
    stringstream ss;
    long http_code;
public:
    CURLplusplus()
            : curl(curl_easy_init())
    , http_code(0)
    ~CURLplusplus()
        if (curl) curl_easy_cleanup(curl);
    std::string Get(const std::string& url)
        CURLcode res;
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
        ss.str("");
        http_code = 0;
        res = curl_easy_perform(curl);
        if (res != CURLE_OK)
            throw std::runtime_error(curl_easy_strerror(res));
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
        return ss.str();
    long GetHttpCode()
        return http_code;
private:
    static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)
        return static_cast<CURLplusplus*>(userp)->Write(buffer,size,nmemb);
    size_t Write(void *buffer, size_t size, size_t nmemb)
        ss.write((const char*)buffer,size*nmemb);
        return size*nmemb;

As you want a C++ solution, you could use Qt. It has a QHttp class you can use.

You can check the docs:

http->setHost("qt.nokia.com");
http->get(QUrl::toPercentEncoding("/index.html"));

Qt also has a lot more to it that you could use in a common C++ app.

I think QHttp has been replaced with QNetworkAccessManager and related classes in Qt 4.6 and later versions. – juzzlin Mar 5, 2015 at 21:31 QNetworkAccessManager has been documented since Qt 4.4; and in Qt 4.8 says: QHttp - This class is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code. So I guess it is still available, if you ignore the deprecated warnings. – Jesse Chisholm Aug 5, 2015 at 23:55

You may want to check C++ REST SDK (codename "Casablanca"). http://msdn.microsoft.com/en-us/library/jj950081.aspx

With the C++ REST SDK, you can more easily connect to HTTP servers from your C++ app.

Usage example:

#include <iostream>
#include <cpprest/http_client.h>
using namespace web::http;                  // Common HTTP functionality
using namespace web::http::client;          // HTTP client features
int main(int argc, char** argv) {
    http_client client("http://httpbin.org/");
    http_response response;
    // ordinary `get` request
    response = client.request(methods::GET, "/get").get();
    std::cout << response.extract_string().get() << "\n";
    // working with json
    response = client.request(methods::GET, "/get").get();
    std::cout << "url: " << response.extract_json().get()[U("url")] << "\n";

The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design.

The project seems to be unmaintained now, be aware to use it in production. Its quality isn't that high to meet the standards used in production environments. – prehistoricpenguin Apr 22, 2021 at 3:54

libCURL is a pretty good option for you. Depending on what you need to do, the tutorial should tell you what you want, specifically for the easy handle. But, basically, you could do this just to see the source of a page:

CURL* c;
c = curl_easy_init();
curl_easy_setopt( c, CURL_URL, "www.google.com" );
curl_easy_perform( c );
curl_easy_cleanup( c );

I believe this will cause the result to be printed to stdout. If you want to handle it instead -- which, I assume, you do -- you need to set the CURL_WRITEFUNCTION. All of that is covered in the curl tutorial linked above.

With this answer I refer to the answer from Software_Developer. By rebuilding the code I found that some parts are deprecated (gethostbyname()) or do not provide error handling (creation of sockets, sending something) for an operation.

The following windows code is tested with Visual Studio 2013 and Windows 8.1 64-bit as well as Windows 7 64-bit. It will target an IPv4 TCP Connection with the Web Server of www.google.com.

#include <winsock2.h>
#include <WS2tcpip.h>
#include <windows.h>
#include <iostream>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
    int main (){
    // Initialize Dependencies to the Windows Socket.
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
        cout << "WSAStartup failed.\n";
        system("pause");
        return -1;
    // We first prepare some "hints" for the "getaddrinfo" function
    // to tell it, that we are looking for a IPv4 TCP Connection.
    struct addrinfo hints;
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;          // We are targeting IPv4
    hints.ai_protocol = IPPROTO_TCP;    // We are targeting TCP
    hints.ai_socktype = SOCK_STREAM;    // We are targeting TCP so its SOCK_STREAM
    // Aquiring of the IPv4 address of a host using the newer
    // "getaddrinfo" function which outdated "gethostbyname".
    // It will search for IPv4 addresses using the TCP-Protocol.
    struct addrinfo* targetAdressInfo = NULL;
    DWORD getAddrRes = getaddrinfo("www.google.com", NULL, &hints, &targetAdressInfo);
    if (getAddrRes != 0 || targetAdressInfo == NULL)
        cout << "Could not resolve the Host Name" << endl;
        system("pause");
        WSACleanup();
        return -1;
    // Create the Socket Address Informations, using IPv4
    // We dont have to take care of sin_zero, it is only used to extend the length of SOCKADDR_IN to the size of SOCKADDR
    SOCKADDR_IN sockAddr;
    sockAddr.sin_addr = ((struct sockaddr_in*) targetAdressInfo->ai_addr)->sin_addr;    // The IPv4 Address from the Address Resolution Result
    sockAddr.sin_family = AF_INET;  // IPv4
    sockAddr.sin_port = htons(80);  // HTTP Port: 80
    // We have to free the Address-Information from getaddrinfo again
    freeaddrinfo(targetAdressInfo);
    // Creation of a socket for the communication with the Web Server,
    // using IPv4 and the TCP-Protocol
    SOCKET webSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (webSocket == INVALID_SOCKET)
        cout << "Creation of the Socket Failed" << endl;
        system("pause");
        WSACleanup();
        return -1;
    // Establishing a connection to the web Socket
    cout << "Connecting...\n";
    if(connect(webSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr)) != 0)
        cout << "Could not connect";
        system("pause");
        closesocket(webSocket);
        WSACleanup();
        return -1;
    cout << "Connected.\n";
    // Sending a HTTP-GET-Request to the Web Server
    const char* httpRequest = "GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n";
    int sentBytes = send(webSocket, httpRequest, strlen(httpRequest),0);
    if (sentBytes < strlen(httpRequest) || sentBytes == SOCKET_ERROR)
        cout << "Could not send the request to the Server" << endl;
        system("pause");
        closesocket(webSocket);
        WSACleanup();
        return -1;
    // Receiving and Displaying an answer from the Web Server
    char buffer[10000];
    ZeroMemory(buffer, sizeof(buffer));
    int dataLen;
    while ((dataLen = recv(webSocket, buffer, sizeof(buffer), 0) > 0))
        int i = 0;
        while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
            cout << buffer[i];
            i += 1;
    // Cleaning up Windows Socket Dependencies
    closesocket(webSocket);
    WSACleanup();
    system("pause");
    return 0;

References:

Deprecation of gethostbyname

Return Value of socket()

Return Value of send()

Note that this does not require libcurl, Windows.h, or WinSock! No compilation of libraries, no project configuration, etc. I have this code working in Visual Studio 2017 c++ on Windows 10:

#pragma comment(lib, "urlmon.lib")
#include <urlmon.h>
#include <sstream>
using namespace std;
IStream* stream;
//Also works with https URL's - unsure about the extent of SSL support though.
HRESULT result = URLOpenBlockingStream(0, "http://google.com", &stream, 0, 0);
if (result != 0)
    return 1;
char buffer[100];
unsigned long bytesRead;
stringstream ss;
stream->Read(buffer, 100, &bytesRead);
while (bytesRead > 0U)
    ss.write(buffer, (long long)bytesRead);
    stream->Read(buffer, 100, &bytesRead);
stream->Release();
string resultString = ss.str();

I just figured out how to do this, as I wanted a simple API access script, libraries like libcurl were causing me all kinds of problems (even when I followed the directions...), and WinSock is just too low-level and complicated.

I'm not quite sure about all of the IStream reading code (particularly the while condition - feel free to correct/improve), but hey, it works, hassle free! (It makes sense to me that, since I used a blocking (synchronous) call, this is fine, that bytesRead would always be > 0U until the stream (ISequentialStream?) is finished being read, but who knows.)

See also: URL Monikers and Asynchronous Pluggable Protocol Reference

It was edited out, but after a fair amount of experience in c++, I'm going to stand by my original claim that this is probably the easiest way you will ever be able to do this kind of thing in c++... (At least for now...) – Andrew Aug 23, 2018 at 22:37 I just tested URLOpenBlockingStream with a few URL's from badssl.com (pretty handy), and this operation will fail if the SSL certificate is bad. In every case I tested (just a few), the output of the above code will be an empty string (no stream data). So that's pretty nice. – Andrew Aug 24, 2018 at 1:04 @Robin Ha! You wanted the message and the response code?! You know as well as I do, except that maybe if you look at the documentation and look in the more manual URL Monikers stuff you might find an answer. I seem to recall someone posting code online implementing URLOpenBlockingStream manually, which would allow for more configuration. Do let me know if you figure anything out! – Andrew Aug 28, 2018 at 17:33 There's also this I just found: learn.microsoft.com/en-us/windows/desktop/WinInet/… Have no idea if it's any good. – Andrew Aug 28, 2018 at 17:34

C++ does not provide any way to do it directly. It would entirely depend on what platforms and libraries that you have.

At worst case, you can use the boost::asio library to establish a TCP connection, send the HTTP headers (RFC 2616), and parse the responses directly. Looking at your application needs, this is simple enough to do.

@Andrew: If your "It does" addresses sybreon's "C++ does not provide any way to do it directly.", then the linked answer is not valid as it shows a way to do it using system specifics. – Sebastian Mach Sep 9, 2019 at 13:23 @SebastianMach I mean, it does though. Just import a system-provided library and call a function, and it does the job for you. Compare that with all the other c++ options and it's either really difficult or using 3rd party code. I consider that pretty direct. – Andrew Sep 9, 2019 at 14:26 @Andrew: It's "system-provided" only on Windows. On other systems, it's different. And it doesn't have anything to do with "C++ does not provide any way to do it directly", which really means "The C++ standard does not". – Sebastian Mach Sep 10, 2019 at 7:49 @Andrew: Uhm, no, he specifically stated "C++ does not provide", which is the same as "it's not standardized". If it is provided for C++ by Windows or Linux or OS/2, then it is provided for C++ by Windows or Linux or OS/2, and not by C++. What you mean is "Available for C++", which simply is not the same as "Available by C++". – Sebastian Mach Sep 11, 2019 at 13:21

Here is some code that will work with no need to use any 3rd party library: First define your gateway, user, password and any other parameters you need to send to this specific server.

#define USERNAME "user"
#define PASSWORD "your password"
#define GATEWAY "your gateway"

Here is the code itself:

HINTERNET hOpenHandle, hResourceHandle, hConnectHandle;
const TCHAR* szHeaders = _T("Content-Type:application/json; charset=utf-8\r\n");
hOpenHandle = InternetOpen(_T("HTTPS"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (hOpenHandle == NULL)
    return false;
hConnectHandle = InternetConnect(hOpenHandle,
    GATEWAY,
    INTERNET_DEFAULT_HTTPS_PORT,
    NULL, NULL, INTERNET_SERVICE_HTTP,
    0, 1);
if (hConnectHandle == NULL)
    InternetCloseHandle(hOpenHandle);
    return false;
hResourceHandle = HttpOpenRequest(hConnectHandle,
    _T("POST"),
    GATEWAY,
    NULL, NULL, NULL, INTERNET_FLAG_SECURE | INTERNET_FLAG_KEEP_CONNECTION,
if (hResourceHandle == NULL)
    InternetCloseHandle(hOpenHandle);
    InternetCloseHandle(hConnectHandle);
    return false;
InternetSetOption(hResourceHandle, INTERNET_OPTION_USERNAME, (LPVOID)USERNAME, _tcslen(USERNAME));
InternetSetOption(hResourceHandle, INTERNET_OPTION_PASSWORD, (LPVOID)PASSWORD, _tcslen(PASSWORD));
std::string buf;
if (HttpSendRequest(hResourceHandle, szHeaders, 0, NULL, 0))
    while (true)
        std::string part;
        DWORD size;
        if (!InternetQueryDataAvailable(hResourceHandle, &size, 0, 0))break;
        if (size == 0)break;
        part.resize(size);
        if (!InternetReadFile(hResourceHandle, &part[0], part.size(), &size))break;
        if (size == 0)break;
        part.resize(size);
        buf.append(part);
if (!buf.empty())
    // Get data back
InternetCloseHandle(hResourceHandle);
InternetCloseHandle(hConnectHandle);
InternetCloseHandle(hOpenHandle);

That should work on a Win32 API environment.

Here is an example.

"Gateway" is just a generic word for the URI (en.wikipedia.org/wiki/Uniform_Resource_Identifier) provided by the service provider. This has nothing to do with Windows. – Michael Haephrati May 24, 2019 at 11:12 Ah, thanks. I never heard that expression to be used for URL, so that kinda confused me. Thanks for clarification. – Tomáš Zato May 24, 2019 at 12:12 Ok, I tested the code and your example does not add up. InternetConnect returns null when full URL is given, but returns non-null value when only the domain name is provided. So when/where do I use full URL to get the page that I want to download? – Tomáš Zato May 24, 2019 at 12:52

C and C++ don't have a standard library for HTTP or even for socket connections. Over the years some portable libraries have been developed. The most widely used, as others have said, is libcurl.

Here is a list of alternatives to libcurl (coming from the libcurl's web site).

Also, for Linux, this is a simple HTTP client. You could implement your own simple HTTP GET client, but this won't work if there are authentication or redirects involved or if you need to work behind a proxy. For these cases you need a full-blown library like libcurl.

For source code with libcurl, this is the closest to what you want (Libcurl has many examples). Look at the main function. The html content will be copied to the buffer, after a successfully connection. Just replace parseHtml with your own function.

The HTTP protocol is very simple, so it is very simple to write a HTTP client. Here is one

https://github.com/pedro-vicente/lib_netsockets

It uses HTTP GET to retrieve a file from a web server, both server and file are command line parameters. The remote file is saved to a local copy.

Disclaimer: I am the author

check http.cc https://github.com/pedro-vicente/lib_netsockets/blob/master/src/http.cc

int http_client_t::get(const char *path_remote_file)
  char buf_request[1024];
  //construct request message using class input parameters
  sprintf(buf_request, "GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", path_remote_file, m_server_ip.c_str());
  //send request, using built in tcp_client_t socket
  if (this->write_all(buf_request, (int)strlen(buf_request)) < 0)
    return -1;

EDIT: edited URL

You can use embeddedRest library. It is lightweight header-only library. So it is easy to include it to your project and it does not require compilation cause there no .cpp files in it.

Request example from readme.md from repo:

#include "UrlRequest.hpp"
//...
UrlRequest request;
request.host("api.vk.com");
const auto countryId = 1;
const auto count = 1000;
request.uri("/method/database.getCities",{
    { "lang", "ru" },
    { "country_id", countryId },
    { "count", count },
    { "need_all", "1" },
request.addHeader("Content-Type: application/json");
auto response = std::move(request.perform());
if (response.statusCode() == 200) {
  cout << "status code = " << response.statusCode() << ", body = *" << response.body() << "*" << endl;
}else{
  cout << "status code = " << response.statusCode() << ", description = " << response.statusDescription() << endl;
                @uhfocuz the lib is written for iOS and Android. But I can help you compiling it for Win32. It is not too difficult
– fnc12
                Aug 4, 2016 at 6:30
                I love how light it is for my use, it compiled just fine on my Mac but on Windows the libs are different like you dont have netdb.h etc so i'd like some help yes
– uhfocuz
                Aug 4, 2016 at 6:32
                @uhfocuz all you have to do is add conditions like #ifdef _WIN32 and add there windows specific code. Look here - there is no much difference between unix sockets and windows sockets. I see two main differences: 1) call WSAStartup first and 2) use closesocket instead of close
– fnc12
                Aug 4, 2016 at 6:38
                @uhfocuz please create an issue in my repo - I shall add win32 support once I have enough time
– fnc12
                Aug 4, 2016 at 13:53

Here is some (relatively) simple C++11 code that uses libCURL to download a URL's content into a std::vector<char>:

http_download.hh

# pragma once
#include <string>
#include <vector>
std::vector<char> download(std::string url, long* responseCode = nullptr);

http_download.cc

#include "http_download.hh"
#include <curl/curl.h>
#include <sstream>
#include <stdexcept>
using namespace std;
size_t callback(void* contents, size_t size, size_t nmemb, void* user)
  auto chunk = reinterpret_cast<char*>(contents);
  auto buffer = reinterpret_cast<vector<char>*>(user);
  size_t priorSize = buffer->size();
  size_t sizeIncrease = size * nmemb;
  buffer->resize(priorSize + sizeIncrease);
  std::copy(chunk, chunk + sizeIncrease, buffer->data() + priorSize);
  return sizeIncrease;
vector<char> download(string url, long* responseCode)
  vector<char> data;
  curl_global_init(CURL_GLOBAL_ALL);
  CURL* handle = curl_easy_init();
  curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
  curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, callback);
  curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);
  curl_easy_setopt(handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
  CURLcode result = curl_easy_perform(handle);
  if (responseCode != nullptr)
    curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, responseCode);
  curl_easy_cleanup(handle);
  curl_global_cleanup();
  if (result != CURLE_OK)
    stringstream err;
    err << "Error downloading from URL \"" << url << "\": " << curl_easy_strerror(result);
    throw runtime_error(err.str());
  return data;

Is there any way to easily make a HTTP request with C++? Specifically, I want to download the contents of a page (an API) and check the contents to see if it contains a 1 or a 0. Is it also possible to download the contents into a string?

First off ... I know this question is 12 years old. However . None of the answers provided gave an example that was "simple" without the need to build some external library

Below is the most simple solution I could come up with to retrieve and print the contents of a webpage.

Some Documentation on the functions utilized in the example below

// wininet lib :
https://learn.microsoft.com/en-us/windows/win32/api/wininet/
// wininet->internetopena();
https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetopena
// wininet->intenetopenurla();
https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetopenurla
// wininet->internetreadfile();
https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetreadfile
// wininet->internetclosehandle();
https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetclosehandle

#include <iostream>
#include <WinSock2.h>
#include <wininet.h>
#pragma comment(lib, "wininet.lib")
int main()
    //  ESTABLISH SOME LOOSE VARIABLES
    const int size = 4096;
    char buf[size];
    DWORD length;
    //  ESTABLISH CONNECTION TO THE INTERNET
    HINTERNET internet = InternetOpenA("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
    if (!internet)
        ExitProcess(EXIT_FAILURE);  //  Failed to establish connection to internet, Exit
    //  ATTEMPT TO CONNECT TO WEBSITE "google.com"
    HINTERNET response = InternetOpenUrlA(internet, "http://www.google.com", NULL, NULL, NULL, NULL);
    if (!response) {
        //  CONNECTION TO "google.com" FAILED
        InternetCloseHandle(internet);  //  Close handle to internet
        ExitProcess(EXIT_FAILURE);
    //  READ CONTENTS OF WEBPAGE IN HTML FORMAT
    if (!InternetReadFile(response, buf, size, &length)) {     
        //  FAILED TO READ CONTENTS OF WEBPAGE
        //  Close handles and Exit
        InternetCloseHandle(response);                      //  Close handle to response
        InternetCloseHandle(internet);                      //  Close handle to internet
        ExitProcess(EXIT_FAILURE);
    //  CLOSE HANDLES AND OUTPUT CONTENTS OF WEBPAGE
    InternetCloseHandle(response);                      //  Close handle to response
    InternetCloseHandle(internet);                      //  Close handle to internet
    std::cout << buf << std::endl;
    return 0;

If you are looking for a HTTP client library in C++ that is supported in multiple platforms (Linux, Windows and Mac) for consuming Restful web services. You can have below options.

  • QT Network Library - Allows the application to send network requests and receive replies
  • C++ REST SDK - An emerging third-party HTTP library with PPL support
  • Libcurl - It is probably one of the most used http lib in the native world.
  • Generally I'd recommend something cross-platform like cURL, POCO, or Qt. However, here is a Windows example!:

    #include <atlbase.h>
    #include <msxml6.h>
    #include <comutil.h> // _bstr_t
    HRESULT hr;
    CComPtr<IXMLHTTPRequest> request;
    hr = request.CoCreateInstance(CLSID_XMLHTTP60);
    hr = request->open(
        _bstr_t("GET"),
        _bstr_t("https://www.google.com/images/srpr/logo11w.png"),
        _variant_t(VARIANT_FALSE),
        _variant_t(),
        _variant_t());
    hr = request->send(_variant_t());
    // get status - 200 if succuss
    long status;
    hr = request->get_status(&status);
    // load image data (if url points to an image)
    VARIANT responseVariant;
    hr = request->get_responseStream(&responseVariant);
    IStream* stream = (IStream*)responseVariant.punkVal;
    CImage *image = new CImage();
    image->Load(stream);
    stream->Release();
    

    Although a little bit late. You may prefer https://github.com/Taymindis/backcurl .

    It allows you to do http call on mobile c++ development. Suitable for Mobile game developement

    bcl::init(); // init when using
    bcl::execute<std::string>([&](bcl::Request *req) {
        bcl::setOpts(req, CURLOPT_URL , "http://www.google.com",
                 CURLOPT_FOLLOWLOCATION, 1L,
                 CURLOPT_WRITEFUNCTION, &bcl::writeContentCallback,
                 CURLOPT_WRITEDATA, req->dataPtr,
                 CURLOPT_USERAGENT, "libcurl-agent/1.0",
                 CURLOPT_RANGE, "0-200000"
    }, [&](bcl::Response * resp) {
        std::string ret =  std::string(resp->getBody<std::string>()->c_str());
        printf("Sync === %s\n", ret.c_str());
    bcl::cleanUp(); // clean up when no more using
    

    All the answers above are helpful. My answer just adds some additions:

  • Use boost beast, sync example, async example, ssl example
  • Use nghttp2, example, It supports SSL, HTTP/2
  • Use Facebook proxygen, this project comprises the core C++ HTTP abstractions used at Facebook. It's aimed at high performance and concurrency. I recommend installing it with vcpkg or you will struggle with the dependencies management. It supports SSL. It also support some advanced protocols:HTTP/1.1, SPDY/3, SPDY/3.1, HTTP/2, and HTTP/3
  • Both nghttp2 and proxygen are stable, can be considered to use in production.

    //HTTP Request Header char* szRequest = "GET /video/nice.mp4 HTTP/1.1\r\nHost: example.com\r\n\r\n"; int ilen = strlen(szRequest); //our buffer char output[16*1024]; ACE_INET_Addr server (80, "example.com"); ACE_SOCK_Stream peer; ACE_SOCK_Connector connector; int ires = connector.connect(peer, server); int sum = 0; peer.send(szRequest, ilen); while (true) ACE_Time_Value timeout = ACE_Time_Value(15); int rc = peer.recv_n(output, 16*1024, &timeout); if (rc == -1) break; sum += rc; peer.close(); printf("Bytes transffered: %d",sum); return 0;

    CppRest SDK by MS is what I just found and after about 1/2 hour had my first simple web service call working. Compared that to others mentioned here where I was not able to get anything even installed after hours of looking, I'd say it is pretty impressive

    https://github.com/microsoft/cpprestsdk

    Scroll down and click on Documentation, then click on Getting Started Tutorial and you will have a simple app running in no time.

    quote from cpprestsdk: "cpprestsdk is in maintenance mode and we do not recommend its use in new projects. We will continue to fix critical bugs and address security issues." – Bernhard Leichtle Jun 22, 2022 at 14:00

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.