-1

I'm currently using this function to download files from http but can't make it work for urls with https:

bool DownloadFile(string url, LPCSTR filename){
    string request; // HTTP Header //
    char buffer[BUFFERSIZE];
    struct sockaddr_in serveraddr;
    int sock;
    WSADATA wsaData;
    int port = 80;
    if(url.find("http://") != -1){
        string temp = url;
        url = temp.substr(url.find("http://") + 7);
    }
    int dm = url.find("/");
    string file = url.substr(dm);
    string shost = url.substr(0, dm);
    request += "GET " + file + " HTTP/1.0\r\n";
    request += "Host: " + shost + "\r\n";
    request += "\r\n";
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
        return FALSE;
    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
        return FALSE;
    memset(&serveraddr, 0, sizeof(serveraddr));
    hostent *record = gethostbyname(shost.c_str());
    in_addr *address = (in_addr * )record->h_addr;
    string ipd = inet_ntoa(* address);
    const char *ipaddr = ipd.c_str();
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(ipaddr);
    serveraddr.sin_port = htons(port);
    if (connect(sock, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
        return FALSE;
    if (send(sock, request.c_str(), request.length(), 0) != request.length())
        return FALSE;
    int nRecv, npos;
    nRecv = recv(sock, (char*)&buffer, BUFFERSIZE, 0);
    string str_buff = buffer;
    npos = str_buff.find("\r\n\r\n");
    HANDLE hFile;
    hFile = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
    DWORD ss;
    while((nRecv > 0) && (nRecv != INVALID_SOCKET)){
        if(npos > 0){
            char bf[BUFFERSIZE];
            memcpy(bf, buffer + (npos + 4), nRecv - (npos + 4));
            WriteFile(hFile, bf,nRecv - (npos + 4), &ss, NULL);
        }else{
            WriteFile(hFile, buffer, nRecv, &ss, NULL);
        }
        ZeroMemory(&buffer, sizeof(buffer));
        nRecv = recv(sock, (char*)&buffer, BUFFERSIZE, 0);
        str_buff = buffer;
        npos = str_buff.find("\r\n\r\n");
    }
    CloseHandle(hFile);
    closesocket(sock);
    WSACleanup();

    return TRUE;
}

Is there a way to download files from https without curl? I would prefer to be done with sockets or Boost if possible. If necessary, I want to download a file from BitBucket.

Many thanks!

MrWhite
  • 179
  • 3
  • 11
  • 2
    Check [libcurl](https://curl.haxx.se/libcurl/), or specific example for [url download to file](https://curl.haxx.se/libcurl/c/url2file.html). – mvp Aug 22 '16 at 23:10
  • 1
    Possible duplicate of [SSL certificates and Boost asio](http://stackoverflow.com/questions/28264313/ssl-certificates-and-boost-asio) – TessellatingHeckler Aug 22 '16 at 23:20
  • Your code doesn't work with HTTPS because it is not trying to do anything with SSL/TLS. If you don't want to use cURL, you will have to use an SSL/TLS library on top of your socket code, like OpenSSL, Microsoft’s own SChannel, or maybe WinSock Security Extensions. Or else use a 3rd party socket library like Asio. SSL/TLS is a LOT of work to implement manually. – Remy Lebeau Aug 23 '16 at 05:52
  • And FYI, your existing code is not even remotely close to being a viable or accurate HTTP client implementation. You can use Microsoft’s WinInet or WinHTTP APIs to send HTTP/HTTPS requests, if you don't want to use a 3rd party library. – Remy Lebeau Aug 23 '16 at 05:56

1 Answers1

-1

If you are using Linux, you can use C++ to call shell commands and download with ease. I found it to be much easier than writing actual C++ code for that.

Saik
  • 993
  • 1
  • 16
  • 40