Commit 0cda2282 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

asio: Assign values to uri_ref directly

parent 566baab3
...@@ -80,26 +80,12 @@ void request_impl::uri(uri_ref uri) { uri_ = std::move(uri); } ...@@ -80,26 +80,12 @@ void request_impl::uri(uri_ref uri) { uri_ = std::move(uri); }
const uri_ref &request_impl::uri() const { return 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); } 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_; }
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 client
} // namespace asio_http2 } // namespace asio_http2
} // namespace nghttp2 } // namespace nghttp2
...@@ -65,22 +65,11 @@ public: ...@@ -65,22 +65,11 @@ public:
void uri(uri_ref uri); void uri(uri_ref uri);
const uri_ref &uri() const; const uri_ref &uri() const;
uri_ref &uri();
void method(std::string s); void method(std::string s);
const std::string &method() const; 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: private:
header_map header_; header_map header_;
response_cb response_cb_; response_cb response_cb_;
...@@ -90,10 +79,6 @@ private: ...@@ -90,10 +79,6 @@ private:
class stream *strm_; class stream *strm_;
uri_ref uri_; uri_ref uri_;
std::string method_; std::string method_;
std::string scheme_;
std::string path_;
std::string authority_;
std::string host_;
}; };
} // namespace client } // namespace client
......
...@@ -162,24 +162,25 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame, ...@@ -162,24 +162,25 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
} }
auto &req = strm->request().impl(); auto &req = strm->request().impl();
auto &uri = req.uri();
switch (http2::lookup_token(name, namelen)) { switch (http2::lookup_token(name, namelen)) {
case http2::HD__METHOD: case http2::HD__METHOD:
req.method(std::string(value, value + valuelen)); req.method(std::string(value, value + valuelen));
break; break;
case http2::HD__SCHEME: case http2::HD__SCHEME:
req.scheme(std::string(value, value + valuelen)); uri.scheme.assign(value, value + valuelen);
break; break;
case http2::HD__PATH: case http2::HD__PATH:
req.path(std::string(value, value + valuelen)); split_path(uri, value, value + valuelen);
break; break;
case http2::HD__AUTHORITY: case http2::HD__AUTHORITY:
req.authority(std::string(value, value + valuelen)); uri.host.assign(value, value + valuelen);
// host defaults to authority value
req.host(std::string(value, value + valuelen));
break; break;
case http2::HD_HOST: case http2::HD_HOST:
req.host(std::string(value, value + valuelen)); if (uri.host.empty()) {
uri.host.assign(value, value + valuelen);
}
// fall through // fall through
default: default:
req.header().emplace(std::string(name, name + namelen), req.header().emplace(std::string(name, name + namelen),
...@@ -246,11 +247,6 @@ int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame, ...@@ -246,11 +247,6 @@ 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;
...@@ -392,16 +388,13 @@ const request *session_impl::submit(boost::system::error_code &ec, ...@@ -392,16 +388,13 @@ 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));
{ auto &uref = req.uri();
std::string scheme, host, raw_path, raw_query; http2::copy_url_component(uref.scheme, &u, UF_SCHEMA, uri.c_str());
http2::copy_url_component(scheme, &u, UF_SCHEMA, uri.c_str()); http2::copy_url_component(uref.host, &u, UF_HOST, uri.c_str());
http2::copy_url_component(host, &u, UF_HOST, uri.c_str()); http2::copy_url_component(uref.raw_path, &u, UF_PATH, uri.c_str());
http2::copy_url_component(raw_path, &u, UF_PATH, uri.c_str()); http2::copy_url_component(uref.raw_query, &u, UF_QUERY, uri.c_str());
http2::copy_url_component(raw_query, &u, UF_QUERY, uri.c_str());
uref.path = percent_decode(uref.raw_path);
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,28 +57,5 @@ read_cb string_reader(std::string data) { ...@@ -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 asio_http2
} // namespace nghttp2 } // namespace nghttp2
...@@ -31,20 +31,32 @@ ...@@ -31,20 +31,32 @@
#include <nghttp2/asio_http2.h> #include <nghttp2/asio_http2.h>
#include "util.h"
namespace nghttp2 { namespace nghttp2 {
namespace asio_http2 { namespace asio_http2 {
read_cb string_reader(std::string data); 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, template <typename InputIt>
std::string raw_query); void split_path(uri_ref &dst, InputIt first, InputIt last) {
auto path_last = std::find(first, last, '?');
uri_ref make_uri_ref(std::string scheme, std::string host, InputIt query_first;
const std::string &raw_path_query); 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 asio_http2
} // namespace nghttp2 } // namespace nghttp2
#endif // ASIO_COMMON_H #endif // ASIO_COMMON_H
...@@ -79,6 +79,7 @@ struct uri_ref { ...@@ -79,6 +79,7 @@ struct uri_ref {
std::string host; std::string host;
// percent-decoded form // percent-decoded form
std::string path; std::string path;
std::string raw_path;
std::string raw_query; std::string raw_query;
std::string fragment; std::string fragment;
}; };
......
...@@ -137,25 +137,6 @@ uint32_t hex_to_uint(char c) { ...@@ -137,25 +137,6 @@ uint32_t hex_to_uint(char c) {
return 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) { std::string quote_string(const std::string &target) {
auto cnt = std::count(std::begin(target), std::end(target), '"'); auto cnt = std::count(std::begin(target), std::end(target), '"');
......
...@@ -175,8 +175,24 @@ std::string percentEncode(const unsigned char *target, size_t len); ...@@ -175,8 +175,24 @@ std::string percentEncode(const unsigned char *target, size_t len);
std::string percentEncode(const std::string &target); std::string percentEncode(const std::string &target);
std::string percentDecode(std::string::const_iterator first, template <typename InputIt>
std::string::const_iterator last); 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 '%'. // Percent encode |target| if character is not in token or '%'.
std::string percent_encode_token(const std::string &target); std::string percent_encode_token(const std::string &target);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment