Repository navigation
Expand file tree
/
Copy pathDownloadResource.cpp
More file actions
98 lines (76 loc) · 2.67 KB
/
Copy pathDownloadResource.cpp
File metadata and controls
98 lines (76 loc) · 2.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "DownloadResource.h"
#include <chrono>
#include <iostream>
#include <SFML/Network.hpp>
struct Redirected
{
URL url;
};
const size_t download_HTTP_content_type = 0;
const size_t download_HTTP_content_data = 1;
std::tuple<ContentType, ResourceData> download_HTTP(Host const& host, URI const& uri, std::chrono::milliseconds timeout)
{
sf::Http http;
http.setHost(host);
sf::Http::Request request;
request.setMethod(sf::Http::Request::Get);
request.setUri(uri);
request.setHttpVersion(1, 1); // HTTP 1.1
sf::Http::Response response = http.sendRequest(request, sf::milliseconds(timeout.count()));
//handle status and throw errors
sf::Http::Response::Status status = response.getStatus();
if(status == sf::Http::Response::Ok)
{
return std::make_tuple(response.getField("Content-Type").substr(0, response.getField("Content-Type").find(';')), response.getBody());
}
else if(status == sf::Http::Response::MovedTemporarily || status == sf::Http::Response::MovedPermanently)
{
throw Redirected{response.getField("Location")};
}
throw ImpossibleAccess{"http://" + host + uri, status};
}
WebRessource downloadFromURL(URL const& url, unsigned int redirect_TTL)
{
if(redirect_TTL == 0)
{
throw ImpossibleAccess{url};
}
WebRessource web_res;
web_res.url = url;
Protocol protocol = protocol_of_url(url);
if(protocol == "http")
{
try
{
auto download_result = download_HTTP(host_of_url(url), uri_of_url(url), std::chrono::milliseconds(2000));
web_res.content_type = std::move(std::get<download_HTTP_content_type>(download_result));
web_res.data = std::move(std::get<download_HTTP_content_data>(download_result));
}
catch(Redirected const& e)
{
return downloadFromURL(e.url, redirect_TTL - 1);
}
}
else if(protocol == "ftp")
{
sf::Ftp ftp;
auto res = ftp.connect(host_of_url(url));
if(!res.isOk())
throw ImpossibleAccess{url, res.getStatus()};
res = ftp.login();
if(!res.isOk())
throw ImpossibleAccess{url, res.getStatus()};
URI uri = uri_of_url(url);
auto listing_res = ftp.getDirectoryListing(uri);
if(!listing_res.isOk())
throw ImpossibleAccess{url, listing_res.getStatus()};
if(std::find(begin(listing_res.getListing()), end(listing_res.getListing()), uri) == end(listing_res.getListing()))
throw ImpossibleAccess{url, 0};
web_res.content_type = "ftp/file";
}
else
{
throw UnknownProtocol{protocol};
}
return web_res;
}