#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
void parseURL(std::string url, std::string& host, std::string& request, int& port)
{
// Parse the URL to get the host, request, and port
std::stringstream ss(url);
std::getline(ss, host, '/');
std::getline(ss, request, '/');
// Check if a specific port is provided in the URL
std::stringstream portStream(host.substr(host.find(':') + 1));
if (portStream >> port)
{
host = host.substr(0, host.find(':'));
}
}
void connectToServer(int socketFD, std::string host, int port)
{
struct hostent* server;
struct sockaddr_in serverAddress;
// Get the IP address of the host
server = gethostbyname(host.c_str());
if (server == NULL)
{
std::cerr << "Could not resolve host. Error: " << h_errno << std::endl;
close(socketFD);
exit(1);
}
// Fill in the server address
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(port);
serverAddress.sin_addr.s_addr = *((unsigned long*)server->h_addr);
// Connect to the server
if (connect(socketFD, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1)
{
std::cerr << "Could not connect to server. Error: " << errno << std::endl;
close(socketFD);
exit(1);
}
}
void sendRequest(int socketFD, std::string host, std::string request)
{
// Send the request
std::string httpRequest = "GET /" + request + " HTTP/1.1\r\nHost: " + host + "\r\nConnection: close\r\n\r\n";
if (send(socketFD, httpRequest.c_str(), httpRequest.size(), 0) == -1)
{
std::cerr << "Could not send request. Error: " << errno << std::endl;
close(socketFD);
exit(1);
}
}
void downloadFile(int socketFD, std::string destination)
{
// Download the file
std::ofstream outputFile;
outputFile.open(destination, std::ios::binary);
char buffer[1024];
int bytesReceived;
while ((bytesReceived = recv(socketFD, buffer, sizeof(buffer), 0)) > 0)
{
outputFile.write(buffer, bytesReceived);
}
outputFile.close();
close(socketFD);
}
int main(int argc, char* argv[])
{
// Check for the correct number of arguments
if (argc != 3)
{
std::cerr << "Usage: " << argv[0] << " [URL] [destination]" << std::endl;
return 1;
}
std::string url = argv[1];
std::string destination = argv[2];
std::string host;
std::string request;
int port = 80;
parseURL(url, host, request, port);
int socketFD = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
connectToServer(socketFD, host, port);
sendRequest(socketFD, host, request);
downloadFile(socketFD, destination);
std::cout << "File downloaded and saved to: " << destination << std::endl;
return 0;
}