28 #include <boost/algorithm/string.hpp>
29 #include <boost/asio/ip/tcp.hpp>
45 Url(
const std::string& url)
48 static const std::regex protocolExp(
"(\\w+\\d?(\\+\\w+)?)://([^/]*)(\\/[^?]*)?");
49 std::smatch protocolMatch;
50 if (!std::regex_match(url, protocolMatch, protocolExp)) {
53 m_scheme = protocolMatch[1];
54 std::string authority = protocolMatch[3];
55 m_path = protocolMatch[4];
58 static const std::regex v6Exp(
"^\\[([a-fA-F0-9:]+)\\](?:\\:(\\d+))?$");
60 static const std::regex v4MappedV6Exp(
"^\\[::ffff:(\\d+(?:\\.\\d+){3})\\](?:\\:(\\d+))?$");
62 static const std::regex v4HostExp(
"^([^:]+)(?:\\:(\\d+))?$");
64 if (authority.empty()) {
69 bool isV6 = std::regex_match(authority, match, v6Exp);
71 std::regex_match(authority, match, v4MappedV6Exp) ||
72 std::regex_match(authority, match, v4HostExp)) {
121 std::string m_scheme;
127 class HttpException :
public std::runtime_error
130 using std::runtime_error::runtime_error;
139 NdnFchDiscovery::doStart()
142 boost::asio::ip::tcp::iostream requestStream;
143 #if BOOST_VERSION >= 106700
144 requestStream.expires_after(std::chrono::seconds(3));
146 requestStream.expires_from_now(boost::posix_time::seconds(3));
150 if (!url.isValid()) {
151 NDN_THROW(HttpException(
"Invalid NDN-FCH URL: " + m_url));
153 if (!boost::iequals(url.getScheme(),
"http")) {
154 NDN_THROW(HttpException(
"Only http:// NDN-FCH URLs are supported"));
157 requestStream.connect(url.getHost(), url.getPort());
158 if (!requestStream) {
159 NDN_THROW(HttpException(
"HTTP connection error to " + m_url));
162 requestStream <<
"GET " << url.getPath() <<
" HTTP/1.0\r\n";
163 requestStream <<
"Host: " << url.getHost() <<
":" << url.getPort() <<
"\r\n";
164 requestStream <<
"Accept: */*\r\n";
165 requestStream <<
"Cache-Control: no-cache\r\n";
166 requestStream <<
"Connection: close\r\n\r\n";
167 requestStream.flush();
169 std::string statusLine;
170 std::getline(requestStream, statusLine);
171 if (!requestStream) {
172 NDN_THROW(HttpException(
"HTTP communication error"));
175 std::stringstream responseStream(statusLine);
176 std::string httpVersion;
177 responseStream >> httpVersion;
178 unsigned int statusCode;
179 responseStream >> statusCode;
180 std::string statusMessage;
182 std::getline(responseStream, statusMessage);
183 if (!
static_cast<bool>(requestStream) || httpVersion.substr(0, 5) !=
"HTTP/") {
184 NDN_THROW(HttpException(
"HTTP communication error"));
186 if (statusCode != 200) {
187 boost::trim(statusMessage);
188 NDN_THROW(HttpException(
"HTTP request failed: " + to_string(statusCode) +
" " + statusMessage));
191 while (std::getline(requestStream, header) && header !=
"\r")
195 requestStream >> hubHost;
196 if (hubHost.empty()) {
197 NDN_THROW(HttpException(
"NDN-FCH did not return hub host"));
202 catch (
const std::runtime_error& e) {
203 this->
fail(e.what());
NdnFchDiscovery(const std::string &url)
Create stage to discover NDN hub using NDN-FCH protocol.
void provideHubFaceUri(const std::string &s)
Parse HUB FaceUri from string and declare success.
void fail(const std::string &msg)