asio: Assign values to uri_ref directly

This commit is contained in:
Tatsuhiro Tsujikawa 2015-03-04 21:31:27 +09:00
parent 566baab307
commit 0cda2282dd
8 changed files with 52 additions and 101 deletions

View File

@ -80,26 +80,12 @@ void request_impl::uri(uri_ref uri) { uri_ = std::move(uri); }
const uri_ref &request_impl::uri() const { return uri_; }
uri_ref &request_impl::uri() { return uri_; }
void request_impl::method(std::string s) { method_ = std::move(s); }
const std::string &request_impl::method() const { return method_; }
void request_impl::scheme(std::string s) { scheme_ = std::move(s); }
const std::string &request_impl::scheme() const { return scheme_; }
void request_impl::path(std::string s) { path_ = std::move(s); }
const std::string &request_impl::path() const { return path_; }
void request_impl::authority(std::string s) { authority_ = std::move(s); }
const std::string &request_impl::authority() const { return authority_; }
void request_impl::host(std::string s) { host_ = std::move(s); }
const std::string &request_impl::host() const { return host_; }
} // namespace client
} // namespace asio_http2
} // namespace nghttp2

View File

@ -65,22 +65,11 @@ public:
void uri(uri_ref uri);
const uri_ref &uri() const;
uri_ref &uri();
void method(std::string s);
const std::string &method() const;
void scheme(std::string s);
const std::string &scheme() const;
void path(std::string s);
const std::string &path() const;
void authority(std::string s);
const std::string &authority() const;
void host(std::string s);
const std::string &host() const;
private:
header_map header_;
response_cb response_cb_;
@ -90,10 +79,6 @@ private:
class stream *strm_;
uri_ref uri_;
std::string method_;
std::string scheme_;
std::string path_;
std::string authority_;
std::string host_;
};
} // namespace client

View File

@ -162,24 +162,25 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
}
auto &req = strm->request().impl();
auto &uri = req.uri();
switch (http2::lookup_token(name, namelen)) {
case http2::HD__METHOD:
req.method(std::string(value, value + valuelen));
break;
case http2::HD__SCHEME:
req.scheme(std::string(value, value + valuelen));
uri.scheme.assign(value, value + valuelen);
break;
case http2::HD__PATH:
req.path(std::string(value, value + valuelen));
split_path(uri, value, value + valuelen);
break;
case http2::HD__AUTHORITY:
req.authority(std::string(value, value + valuelen));
// host defaults to authority value
req.host(std::string(value, value + valuelen));
uri.host.assign(value, value + valuelen);
break;
case http2::HD_HOST:
req.host(std::string(value, value + valuelen));
if (uri.host.empty()) {
uri.host.assign(value, value + valuelen);
}
// fall through
default:
req.header().emplace(std::string(name, name + namelen),
@ -246,11 +247,6 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
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());
break;
@ -392,16 +388,13 @@ const request *session_impl::submit(boost::system::error_code &ec,
auto &req = strm->request().impl();
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());
auto &uref = req.uri();
http2::copy_url_component(uref.scheme, &u, UF_SCHEMA, uri.c_str());
http2::copy_url_component(uref.host, &u, UF_HOST, uri.c_str());
http2::copy_url_component(uref.raw_path, &u, UF_PATH, uri.c_str());
http2::copy_url_component(uref.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)));
}
uref.path = percent_decode(uref.raw_path);
nghttp2_data_provider *prdptr = nullptr;
nghttp2_data_provider prd;

View File

@ -57,28 +57,5 @@ 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 nghttp2

View File

@ -31,20 +31,32 @@
#include <nghttp2/asio_http2.h>
#include "util.h"
namespace nghttp2 {
namespace asio_http2 {
read_cb string_reader(std::string data);
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);
template <typename InputIt>
void split_path(uri_ref &dst, InputIt first, InputIt last) {
auto path_last = std::find(first, last, '?');
InputIt query_first;
if (path_last == last) {
query_first = path_last = last;
} else {
query_first = path_last + 1;
}
dst.path = util::percentDecode(first, path_last);
dst.raw_path.assign(first, path_last);
dst.raw_query.assign(query_first, last);
}
} // namespace asio_http2
} // namespace nghttp2
#endif // ASIO_COMMON_H

View File

@ -79,6 +79,7 @@ struct uri_ref {
std::string host;
// percent-decoded form
std::string path;
std::string raw_path;
std::string raw_query;
std::string fragment;
};

View File

@ -137,25 +137,6 @@ uint32_t hex_to_uint(char c) {
return c;
}
std::string percentDecode(std::string::const_iterator first,
std::string::const_iterator last) {
std::string result;
for (; first != last; ++first) {
if (*first == '%') {
if (first + 1 != last && first + 2 != last && isHexDigit(*(first + 1)) &&
isHexDigit(*(first + 2))) {
result += (hex_to_uint(*(first + 1)) << 4) + hex_to_uint(*(first + 2));
first += 2;
continue;
}
result += *first;
continue;
}
result += *first;
}
return result;
}
std::string quote_string(const std::string &target) {
auto cnt = std::count(std::begin(target), std::end(target), '"');

View File

@ -175,8 +175,24 @@ std::string percentEncode(const unsigned char *target, size_t len);
std::string percentEncode(const std::string &target);
std::string percentDecode(std::string::const_iterator first,
std::string::const_iterator last);
template <typename InputIt>
std::string percentDecode(InputIt first, InputIt last) {
std::string result;
for (; first != last; ++first) {
if (*first == '%') {
if (first + 1 != last && first + 2 != last && isHexDigit(*(first + 1)) &&
isHexDigit(*(first + 2))) {
result += (hex_to_uint(*(first + 1)) << 4) + hex_to_uint(*(first + 2));
first += 2;
continue;
}
result += *first;
continue;
}
result += *first;
}
return result;
}
// Percent encode |target| if character is not in token or '%'.
std::string percent_encode_token(const std::string &target);