27 #include <boost/regex.hpp>
28 #include <boost/algorithm/string.hpp>
32 namespace autoconfig {
43 Url(
const std::string& url)
46 static const boost::regex protocolExp(
"(\\w+\\d?(\\+\\w+)?)://([^/]*)(\\/[^?]*)?");
47 boost::smatch protocolMatch;
48 if (!boost::regex_match(url, protocolMatch, protocolExp)) {
51 m_scheme = protocolMatch[1];
52 const std::string& authority = protocolMatch[3];
53 m_path = protocolMatch[4];
56 static const boost::regex v6Exp(
"^\\[([a-fA-F0-9:]+)\\](?:\\:(\\d+))?$");
58 static const boost::regex v4MappedV6Exp(
"^\\[::ffff:(\\d+(?:\\.\\d+){3})\\](?:\\:(\\d+))?$");
60 static const boost::regex v4HostExp(
"^([^:]+)(?:\\:(\\d+))?$");
62 if (authority.empty()) {
67 bool isV6 = boost::regex_match(authority, match, v6Exp);
69 boost::regex_match(authority, match, v4MappedV6Exp) ||
70 boost::regex_match(authority, match, v4HostExp)) {
119 std::string m_scheme;
125 class HttpException :
public std::runtime_error
129 HttpException(
const std::string& what)
130 :
std::runtime_error(what)
136 const std::string& url,
138 :
Base(face, keyChain, nextStageOnFailure)
147 using namespace boost::asio::ip;
148 tcp::iostream requestStream;
150 requestStream.expires_from_now(boost::posix_time::milliseconds(3000));
153 if (!url.isValid()) {
154 BOOST_THROW_EXCEPTION(HttpException(
"Invalid NDN-FCH URL: " + m_url));
157 if (!boost::iequals(url.getScheme(),
"http")) {
158 BOOST_THROW_EXCEPTION(HttpException(
"Only http:// NDN-FCH URLs are supported"));
161 requestStream.connect(url.getHost(), url.getPort());
163 if (!requestStream) {
164 BOOST_THROW_EXCEPTION(HttpException(
"HTTP connection error to " + m_url));
167 requestStream <<
"GET " << url.getPath() <<
" HTTP/1.0\r\n";
168 requestStream <<
"Host: " << url.getHost() <<
":" << url.getPort() <<
"\r\n";
169 requestStream <<
"Accept: */*\r\n";
170 requestStream <<
"Cache-Control: no-cache\r\n";
171 requestStream <<
"Connection: close\r\n\r\n";
172 requestStream.flush();
174 std::string statusLine;
175 std::getline(requestStream, statusLine);
176 if (!requestStream) {
177 BOOST_THROW_EXCEPTION(HttpException(
"HTTP communication error"));
180 std::stringstream responseStream(statusLine);
181 std::string httpVersion;
182 responseStream >> httpVersion;
183 unsigned int statusCode;
184 responseStream >> statusCode;
185 std::string statusMessage;
187 std::getline(responseStream, statusMessage);
188 if (!static_cast<bool>(requestStream) || httpVersion.substr(0, 5) !=
"HTTP/") {
189 throw HttpException(
"HTTP communication error");
191 if (statusCode != 200) {
192 boost::trim(statusMessage);
193 throw HttpException(
"HTTP request failed: " +
194 std::to_string(statusCode) +
" " + statusMessage);
197 while (std::getline(requestStream, header) && header !=
"\r")
201 requestStream >> hubHost;
203 if (hubHost.empty()) {
204 throw HttpException(
"NDN-FCH did not return hub host");
209 catch (
const std::runtime_error& e) {
210 m_nextStageOnFailure(std::string(
"Failed to find NDN router using NDN-FCH service (") + e.what() +
")");
Copyright (c) 2014-2016, Regents of the University of California, Arizona Board of Regents...