asio: Add host_service_from_uri() to extract remote address from URI

This commit is contained in:
Tatsuhiro Tsujikawa 2015-03-06 23:53:19 +09:00
parent 2cadd38b6b
commit 5dccc88a7c
5 changed files with 72 additions and 3 deletions

View File

@ -34,19 +34,33 @@ using namespace nghttp2::asio_http2::client;
int main(int argc, char *argv[]) {
try {
if (argc < 2) {
std::cerr << "Usage: asio-cl URI" << std::endl;
return 1;
}
boost::system::error_code ec;
boost::asio::io_service io_service;
std::string uri = argv[1];
std::string scheme, host, service;
if (host_service_from_uri(ec, scheme, host, service, uri)) {
std::cerr << "error: bad URI: " << ec.message() << std::endl;
return 1;
}
boost::asio::ssl::context tls_ctx(boost::asio::ssl::context::sslv23);
tls_ctx.set_default_verify_paths();
// disabled to make development easier...
// tls_ctx.set_verify_mode(boost::asio::ssl::verify_peer);
configure_tls_context(ec, tls_ctx);
session sess(io_service, tls_ctx, "localhost", "3000");
sess.on_connect([&sess](tcp::resolver::iterator endpoint_it) {
auto sess = scheme == "https" ? session(io_service, tls_ctx, host, service)
: session(io_service, host, service);
sess.on_connect([&sess, &uri](tcp::resolver::iterator endpoint_it) {
boost::system::error_code ec;
auto req = sess.submit(ec, "GET", "https://localhost:3000/");
auto req = sess.submit(ec, "GET", uri);
if (ec) {
std::cerr << "error: " << ec.message() << std::endl;

View File

@ -49,6 +49,17 @@ session::session(boost::asio::io_service &io_service,
session::~session() {}
session::session(session &&other) : impl_(std::move(other.impl_)) {}
session &session::operator=(session &&other) {
if (this == &other) {
return *this;
}
impl_ = std::move(other.impl_);
return *this;
}
void session::on_connect(connect_cb cb) const {
impl_->on_connect(std::move(cb));
}

View File

@ -28,6 +28,7 @@
#include "util.h"
#include "template.h"
#include "http2.h"
namespace nghttp2 {
namespace asio_http2 {
@ -112,5 +113,36 @@ std::string percent_decode(const std::string &s) {
std::string http_date(int64_t t) { return util::http_date(t); }
boost::system::error_code host_service_from_uri(boost::system::error_code &ec,
std::string &scheme,
std::string &host,
std::string &service,
const std::string &uri) {
ec.clear();
http_parser_url u{};
if (http_parser_parse_url(uri.c_str(), uri.size(), 0, &u) != 0) {
ec = make_error_code(boost::system::errc::invalid_argument);
return ec;
}
if ((u.field_set & (1 << UF_SCHEMA)) == 0 ||
(u.field_set & (1 << UF_HOST)) == 0) {
ec = make_error_code(boost::system::errc::invalid_argument);
return ec;
}
http2::copy_url_component(scheme, &u, UF_SCHEMA, uri.c_str());
http2::copy_url_component(host, &u, UF_HOST, uri.c_str());
if (u.field_set & (1 << UF_PORT)) {
http2::copy_url_component(service, &u, UF_PORT, uri.c_str());
} else {
service = scheme;
}
return ec;
}
} // namespace asio_http2
} // namespace nghttp2

View File

@ -123,6 +123,15 @@ std::string percent_decode(const std::string &s);
// Returns HTTP date representation of current posix time |t|.
std::string http_date(int64_t t);
// Parses |uri| and extract scheme, host and service. The service is
// port component of URI (e.g., "8443") if available, otherwise it is
// scheme (e.g., "https").
boost::system::error_code host_service_from_uri(boost::system::error_code &ec,
std::string &scheme,
std::string &host,
std::string &service,
const std::string &uri);
} // namespace asio_http2
} // namespace nghttp2

View File

@ -128,6 +128,9 @@ public:
const std::string &service);
~session();
session(session &&other);
session &operator=(session &&other);
// Sets callback which is invoked after connection is established.
void on_connect(connect_cb cb) const;