Skip to content

Instantly share code, notes, and snippets.

@bw2012
Created April 6, 2019 19:41
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bw2012/4f7bd6f47b219d5d7450a064b59167d9 to your computer and use it in GitHub Desktop.
Save bw2012/4f7bd6f47b219d5d7450a064b59167d9 to your computer and use it in GitHub Desktop.
C++ http download file
#include <iostream>
#include <stdio.h>
#include <sys/socket.h>
//#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
//#include <unistd.h>
#include <vector>
#include <fstream>
class HttpDownloader {
public:
int download(const std::string& host, const std::string& path, const std::string& file){
const std::string& remoteHostName = host;
int port = 80;
std::string remoteIP;
std::string request;
request.append("GET " + path + " HTTP/1.1\r\n");
request.append("Host: " + remoteHostName + "\r\n");
request.append("Connection: close\r\n\r\n");
struct hostent* ghbn = gethostbyname(remoteHostName.c_str());
if (!ghbn) {
printf("Unable to resolve host: %s \n", ghbn->h_name);
return -1;
}
remoteIP = inet_ntoa(*(struct in_addr *)ghbn->h_addr_list[0]);
printf("Connecting to host: %s => %s\n", ghbn->h_name, remoteIP.c_str());
struct sockaddr_in serv_addr;
int socket_;
if ((socket_ = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("Socket creation error \n");
return -2;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
if(inet_pton(AF_INET, remoteIP.c_str(), &serv_addr.sin_addr)<=0) {
printf("Invalid address or address not supported \n");
return -3;
}
if (connect(socket_, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("Connection failed \n");
return -4;
}
if(send(socket_, request.c_str(), strlen(request.c_str()), 0) == -1) {
return -5;
}
std::string rcvStr;
char buffer[1024] = {0};
int valread = 0;
bool isHeader = true;
std::vector<std::string> header;
std::vector<char> data;
std::ofstream fout(file, std::ios::out | std::ios::binary);
int totalBytes = 0;
int endOffset = 0;
while ((valread = recv(socket_, buffer, 1024, 0)) > 0) {
if(isHeader){
for(int i = 0; i < valread; i++) {
if(buffer[i] == '\n') {
if(rcvStr.length() > 1){
//printf("TEST -> %d %s\n", rcvStr.length(), rcvStr.c_str());
header.push_back(rcvStr);
rcvStr.clear();
} else {
isHeader = false;
endOffset = i + 1;
break;
}
} else {
rcvStr += buffer[i];
}
}
}
fout.write(&buffer[0] + endOffset, valread - endOffset);
totalBytes += valread - endOffset;
endOffset = 0;
}
fout.close();
printf("total bytes %d \n", totalBytes);
return 0;
}
};
int main(int argc, char **argv) {
HttpDownloader t;
t.download("example.com", "/test", "test.tmp");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment