asio: Introduce uri_ref
This commit is contained in:
parent
b2196f215a
commit
e15d302985
|
@ -63,6 +63,7 @@ noinst_PROGRAMS += asio-sv asio-sv2 asio-sv3 asio-cl
|
||||||
ASIOCPPFLAGS = ${BOOST_CPPFLAGS} ${AM_CPPFLAGS}
|
ASIOCPPFLAGS = ${BOOST_CPPFLAGS} ${AM_CPPFLAGS}
|
||||||
ASIOLDADD = $(top_builddir)/lib/libnghttp2.la \
|
ASIOLDADD = $(top_builddir)/lib/libnghttp2.la \
|
||||||
$(top_builddir)/src/libnghttp2_asio.la @JEMALLOC_LIBS@ \
|
$(top_builddir)/src/libnghttp2_asio.la @JEMALLOC_LIBS@ \
|
||||||
|
$(top_builddir)/third-party/libhttp-parser.la \
|
||||||
${BOOST_LDFLAGS} \
|
${BOOST_LDFLAGS} \
|
||||||
${BOOST_ASIO_LIB} \
|
${BOOST_ASIO_LIB} \
|
||||||
${BOOST_THREAD_LIB} \
|
${BOOST_THREAD_LIB} \
|
||||||
|
|
|
@ -49,9 +49,13 @@ void print_header(const response &res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_header(const request &req) {
|
void print_header(const request &req) {
|
||||||
std::cerr << req.method() << " " << req.scheme() << "://" << req.authority()
|
auto &uri = req.uri();
|
||||||
<< req.path() << " "
|
std::cerr << req.method() << " " << uri.scheme << "://" << uri.host
|
||||||
<< "HTTP/2\n";
|
<< uri.path;
|
||||||
|
if (!uri.raw_query.empty()) {
|
||||||
|
std::cerr << "?" << uri.raw_query;
|
||||||
|
}
|
||||||
|
std::cerr << " HTTP/2\n";
|
||||||
print_header(req.header());
|
print_header(req.header());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,16 +46,10 @@ void request::on_push(request_cb cb) const { impl_->on_push(std::move(cb)); }
|
||||||
|
|
||||||
void request::on_close(close_cb cb) const { impl_->on_close(std::move(cb)); }
|
void request::on_close(close_cb cb) const { impl_->on_close(std::move(cb)); }
|
||||||
|
|
||||||
|
const uri_ref &request::uri() const { return impl_->uri(); }
|
||||||
|
|
||||||
const std::string &request::method() const { return impl_->method(); }
|
const std::string &request::method() const { return impl_->method(); }
|
||||||
|
|
||||||
const std::string &request::scheme() const { return impl_->scheme(); }
|
|
||||||
|
|
||||||
const std::string &request::path() const { return impl_->path(); }
|
|
||||||
|
|
||||||
const std::string &request::authority() const { return impl_->authority(); }
|
|
||||||
|
|
||||||
const std::string &request::host() const { return impl_->host(); }
|
|
||||||
|
|
||||||
const header_map &request::header() const { return impl_->header(); }
|
const header_map &request::header() const { return impl_->header(); }
|
||||||
|
|
||||||
request_impl &request::impl() { return *impl_; }
|
request_impl &request::impl() { return *impl_; }
|
||||||
|
|
|
@ -76,6 +76,10 @@ const header_map &request_impl::header() const { return header_; }
|
||||||
|
|
||||||
void request_impl::stream(class stream *strm) { strm_ = strm; }
|
void request_impl::stream(class stream *strm) { strm_ = strm; }
|
||||||
|
|
||||||
|
void request_impl::uri(uri_ref uri) { uri_ = std::move(uri); }
|
||||||
|
|
||||||
|
const uri_ref &request_impl::uri() const { return uri_; }
|
||||||
|
|
||||||
void request_impl::method(std::string s) { method_ = std::move(s); }
|
void request_impl::method(std::string s) { method_ = std::move(s); }
|
||||||
|
|
||||||
const std::string &request_impl::method() const { return method_; }
|
const std::string &request_impl::method() const { return method_; }
|
||||||
|
|
|
@ -63,6 +63,9 @@ public:
|
||||||
|
|
||||||
void stream(class stream *strm);
|
void stream(class stream *strm);
|
||||||
|
|
||||||
|
void uri(uri_ref uri);
|
||||||
|
const uri_ref &uri() const;
|
||||||
|
|
||||||
void method(std::string s);
|
void method(std::string s);
|
||||||
const std::string &method() const;
|
const std::string &method() const;
|
||||||
|
|
||||||
|
@ -85,6 +88,7 @@ private:
|
||||||
close_cb close_cb_;
|
close_cb close_cb_;
|
||||||
read_cb read_cb_;
|
read_cb read_cb_;
|
||||||
class stream *strm_;
|
class stream *strm_;
|
||||||
|
uri_ref uri_;
|
||||||
std::string method_;
|
std::string method_;
|
||||||
std::string scheme_;
|
std::string scheme_;
|
||||||
std::string path_;
|
std::string path_;
|
||||||
|
|
|
@ -246,6 +246,11 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &req = push_strm->request().impl();
|
||||||
|
req.uri(make_uri_ref(req.scheme(),
|
||||||
|
req.authority().empty() ? req.host() : req.authority(),
|
||||||
|
req.path()));
|
||||||
|
|
||||||
strm->request().impl().call_on_push(push_strm->request());
|
strm->request().impl().call_on_push(push_strm->request());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -364,6 +369,19 @@ const request *session_impl::submit(boost::system::error_code &ec,
|
||||||
header_map h) {
|
header_map h) {
|
||||||
ec.clear();
|
ec.clear();
|
||||||
|
|
||||||
|
http_parser_url u{};
|
||||||
|
// TODO Handle CONNECT method
|
||||||
|
if (http_parser_parse_url(uri.c_str(), uri.size(), 0, &u) != 0) {
|
||||||
|
ec = make_error_code(boost::system::errc::invalid_argument);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
auto nva = std::vector<nghttp2_nv>();
|
auto nva = std::vector<nghttp2_nv>();
|
||||||
nva.reserve(3 + h.size());
|
nva.reserve(3 + h.size());
|
||||||
nva.push_back(http2::make_nv_ls(":method", method));
|
nva.push_back(http2::make_nv_ls(":method", method));
|
||||||
|
@ -379,6 +397,17 @@ const request *session_impl::submit(boost::system::error_code &ec,
|
||||||
auto &req = strm->request().impl();
|
auto &req = strm->request().impl();
|
||||||
req.header(std::move(h));
|
req.header(std::move(h));
|
||||||
|
|
||||||
|
{
|
||||||
|
std::string scheme, host, raw_path, raw_query;
|
||||||
|
http2::copy_url_component(scheme, &u, UF_SCHEMA, uri.c_str());
|
||||||
|
http2::copy_url_component(host, &u, UF_HOST, uri.c_str());
|
||||||
|
http2::copy_url_component(raw_path, &u, UF_PATH, uri.c_str());
|
||||||
|
http2::copy_url_component(raw_query, &u, UF_QUERY, uri.c_str());
|
||||||
|
|
||||||
|
req.uri(make_uri_ref(std::move(scheme), std::move(host),
|
||||||
|
std::move(raw_path), std::move(raw_query)));
|
||||||
|
}
|
||||||
|
|
||||||
nghttp2_data_provider *prdptr = nullptr;
|
nghttp2_data_provider *prdptr = nullptr;
|
||||||
nghttp2_data_provider prd;
|
nghttp2_data_provider prd;
|
||||||
|
|
||||||
|
|
|
@ -57,5 +57,28 @@ read_cb string_reader(std::string data) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uri_ref make_uri_ref(std::string scheme, std::string host, std::string raw_path,
|
||||||
|
std::string raw_query) {
|
||||||
|
return uri_ref{
|
||||||
|
std::move(scheme), std::move(host), percent_decode(raw_path),
|
||||||
|
std::move(raw_path),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
uri_ref make_uri_ref(std::string scheme, std::string host,
|
||||||
|
const std::string &raw_path_query) {
|
||||||
|
auto path_end = raw_path_query.find('?');
|
||||||
|
std::size_t query_pos;
|
||||||
|
if (path_end == std::string::npos) {
|
||||||
|
query_pos = path_end = raw_path_query.size();
|
||||||
|
} else {
|
||||||
|
query_pos = path_end + 1;
|
||||||
|
}
|
||||||
|
return uri_ref{std::move(scheme), std::move(host),
|
||||||
|
util::percentDecode(std::begin(raw_path_query),
|
||||||
|
std::begin(raw_path_query) + path_end),
|
||||||
|
raw_path_query.substr(query_pos)};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace asio_http2
|
} // namespace asio_http2
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
|
@ -38,6 +38,12 @@ read_cb string_reader(std::string data);
|
||||||
|
|
||||||
boost::system::error_code make_error_code(nghttp2_error ev);
|
boost::system::error_code make_error_code(nghttp2_error ev);
|
||||||
|
|
||||||
|
uri_ref make_uri_ref(std::string scheme, std::string host, std::string raw_path,
|
||||||
|
std::string raw_query);
|
||||||
|
|
||||||
|
uri_ref make_uri_ref(std::string scheme, std::string host,
|
||||||
|
const std::string &raw_path_query);
|
||||||
|
|
||||||
} // namespace asio_http2
|
} // namespace asio_http2
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,15 @@ using header_map = std::multimap<std::string, header_value>;
|
||||||
|
|
||||||
const boost::system::error_category &nghttp2_category() noexcept;
|
const boost::system::error_category &nghttp2_category() noexcept;
|
||||||
|
|
||||||
|
struct uri_ref {
|
||||||
|
std::string scheme;
|
||||||
|
std::string host;
|
||||||
|
// percent-decoded form
|
||||||
|
std::string path;
|
||||||
|
std::string raw_query;
|
||||||
|
std::string fragment;
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::function<void(const uint8_t *, std::size_t)> data_cb;
|
typedef std::function<void(const uint8_t *, std::size_t)> data_cb;
|
||||||
typedef std::function<void(void)> void_cb;
|
typedef std::function<void(void)> void_cb;
|
||||||
typedef std::function<void(const boost::system::error_code &ec)> error_cb;
|
typedef std::function<void(const boost::system::error_code &ec)> error_cb;
|
||||||
|
@ -320,10 +329,8 @@ public:
|
||||||
void cancel() const;
|
void cancel() const;
|
||||||
|
|
||||||
const std::string &method() const;
|
const std::string &method() const;
|
||||||
const std::string &scheme() const;
|
|
||||||
const std::string &path() const;
|
const uri_ref &uri() const;
|
||||||
const std::string &authority() const;
|
|
||||||
const std::string &host() const;
|
|
||||||
|
|
||||||
const header_map &header() const;
|
const header_map &header() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue