2016-08-22 3 views
-6

Ich bin derzeit mit dieser Funktion Dateien von http herunterladen kann es aber nicht mit https für Urls funktioniert:C++ Download-Datei von 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; 
} 

Gibt es eine Möglichkeit, um Dateien von https herunterladen, ohne curl ? Ich würde es vorziehen, wenn möglich mit Sockets oder Boost fertig zu sein. Wenn nötig, möchte ich eine Datei von BitBucket herunterladen.

Vielen Dank!

+1

Überprüfen Sie [libcurl] (https://curl.haxx.se/libcurl/) oder ein spezifisches Beispiel für [URL herunterladen in Datei] (https://curl.haxx.se/libcurl/c/url2file.html). – mvp

+0

Mögliches Duplikat von [SSL-Zertifikaten und Boost asio] (http://stackoverflow.com/questions/28264313/ssl-certificates-and-boost-asio) – TessellatingHeckler

+0

Ihr Code funktioniert nicht mit HTTPS, weil es nicht versucht wird alles mit SSL/TLS. Wenn Sie cURL nicht verwenden möchten, müssen Sie eine SSL/TLS-Bibliothek über Ihrem Socket-Code verwenden, z. B. OpenSSL, Microsoft SChannel oder möglicherweise WinSock Security Extensions. Oder verwenden Sie eine Socket-Bibliothek von Drittanbietern wie Asio. SSL/TLS ist eine Menge Arbeit, um manuell zu implementieren. –

Antwort

0

Wenn Sie Linux verwenden, können Sie mit C++ Shell-Befehle aufrufen und problemlos herunterladen. Ich fand es viel einfacher als den tatsächlichen C++ Code dafür zu schreiben.