src: Use StringRef inside LinkHeader

This commit is contained in:
Tatsuhiro Tsujikawa 2016-03-03 23:31:44 +09:00
parent aaf0177318
commit 1e8bea15e5
3 changed files with 23 additions and 24 deletions

View File

@ -892,26 +892,26 @@ std::pair<LinkHeader, const char *>
parse_next_link_header_once(const char *first, const char *last) { parse_next_link_header_once(const char *first, const char *last) {
first = skip_to_next_field(first, last); first = skip_to_next_field(first, last);
if (first == last || *first != '<') { if (first == last || *first != '<') {
return {{{nullptr, nullptr}}, last}; return {{StringRef{}}, last};
} }
auto url_first = ++first; auto url_first = ++first;
first = std::find(first, last, '>'); first = std::find(first, last, '>');
if (first == last) { if (first == last) {
return {{{nullptr, nullptr}}, first}; return {{StringRef{}}, first};
} }
auto url_last = first++; auto url_last = first++;
if (first == last) { if (first == last) {
return {{{nullptr, nullptr}}, first}; return {{StringRef{}}, first};
} }
// we expect ';' or ',' here // we expect ';' or ',' here
switch (*first) { switch (*first) {
case ',': case ',':
return {{{nullptr, nullptr}}, ++first}; return {{StringRef{}}, ++first};
case ';': case ';':
++first; ++first;
break; break;
default: default:
return {{{nullptr, nullptr}}, last}; return {{StringRef{}}, last};
} }
auto ok = false; auto ok = false;
@ -919,7 +919,7 @@ parse_next_link_header_once(const char *first, const char *last) {
for (;;) { for (;;) {
first = skip_lws(first, last); first = skip_lws(first, last);
if (first == last) { if (first == last) {
return {{{nullptr, nullptr}}, first}; return {{StringRef{}}, first};
} }
// we expect link-param // we expect link-param
@ -943,7 +943,7 @@ parse_next_link_header_once(const char *first, const char *last) {
} }
if (start == first) { if (start == first) {
return {{{nullptr, nullptr}}, last}; return {{StringRef{}}, last};
} }
if (!ok && start + PLTLEN == first && if (!ok && start + PLTLEN == first &&
@ -958,7 +958,7 @@ parse_next_link_header_once(const char *first, const char *last) {
start = first; start = first;
} }
if (first == last) { if (first == last) {
return {{{nullptr, nullptr}}, first}; return {{StringRef{}}, first};
} }
assert(*first == '"'); assert(*first == '"');
++first; ++first;
@ -970,7 +970,7 @@ parse_next_link_header_once(const char *first, const char *last) {
// parse next link-param // parse next link-param
continue; continue;
} }
return {{{nullptr, nullptr}}, last}; return {{StringRef{}}, last};
} }
// we are only interested in rel=preload parameter. Others are // we are only interested in rel=preload parameter. Others are
// simply skipped. // simply skipped.
@ -1045,11 +1045,11 @@ parse_next_link_header_once(const char *first, const char *last) {
if (*first == '=' || *first == ';' || *first == ',') { if (*first == '=' || *first == ';' || *first == ',') {
break; break;
} }
return {{{nullptr, nullptr}}, last}; return {{StringRef{}}, last};
} }
if (param_first == first) { if (param_first == first) {
// empty parmname // empty parmname
return {{{nullptr, nullptr}}, last}; return {{StringRef{}}, last};
} }
// link-param without value is acceptable (see link-extension) if // link-param without value is acceptable (see link-extension) if
// it is not followed by '=' // it is not followed by '='
@ -1066,13 +1066,13 @@ parse_next_link_header_once(const char *first, const char *last) {
++first; ++first;
if (first == last) { if (first == last) {
// empty value is not acceptable // empty value is not acceptable
return {{{nullptr, nullptr}}, first}; return {{StringRef{}}, first};
} }
if (*first == '"') { if (*first == '"') {
// quoted-string // quoted-string
first = skip_to_right_dquote(first + 1, last); first = skip_to_right_dquote(first + 1, last);
if (first == last) { if (first == last) {
return {{{nullptr, nullptr}}, first}; return {{StringRef{}}, first};
} }
++first; ++first;
if (first == last || *first == ',') { if (first == last || *first == ',') {
@ -1083,12 +1083,12 @@ parse_next_link_header_once(const char *first, const char *last) {
// parse next link-param // parse next link-param
continue; continue;
} }
return {{{nullptr, nullptr}}, last}; return {{StringRef{}}, last};
} }
// not quoted-string, skip to next ',' or ';' // not quoted-string, skip to next ',' or ';'
if (*first == ',' || *first == ';') { if (*first == ',' || *first == ';') {
// empty value // empty value
return {{{nullptr, nullptr}}, last}; return {{StringRef{}}, last};
} }
for (; first != last; ++first) { for (; first != last; ++first) {
if (*first == ',' || *first == ';') { if (*first == ',' || *first == ';') {
@ -1112,7 +1112,7 @@ almost_done:
if (ok && !ign) { if (ok && !ign) {
return {{{url_first, url_last}}, first}; return {{{url_first, url_last}}, first};
} }
return {{{nullptr, nullptr}}, first}; return {{StringRef{}}, first};
} }
} // namespace } // namespace
@ -1123,8 +1123,9 @@ std::vector<LinkHeader> parse_link_header(const char *src, size_t len) {
for (; first != last;) { for (; first != last;) {
auto rv = parse_next_link_header_once(first, last); auto rv = parse_next_link_header_once(first, last);
first = rv.second; first = rv.second;
if (rv.first.uri.first != nullptr && rv.first.uri.second != nullptr) { auto &link = rv.first;
res.push_back(rv.first); if (!link.uri.empty()) {
res.push_back(link);
} }
} }
return res; return res;

View File

@ -287,8 +287,8 @@ Headers::value_type *get_header(const HeaderIndex &hdidx, int32_t token,
Headers &nva); Headers &nva);
struct LinkHeader { struct LinkHeader {
// The region of URI is [uri.first, uri.second). // The region of URI. This might not be NULL-terminated.
std::pair<const char *, const char *> uri; StringRef uri;
}; };
// Returns next URI-reference in Link header field value |src| of // Returns next URI-reference in Link header field value |src| of

View File

@ -1752,14 +1752,12 @@ int Http2Upstream::prepare_push_promise(Downstream *downstream) {
for (auto &link : for (auto &link :
http2::parse_link_header(kv.value.c_str(), kv.value.size())) { http2::parse_link_header(kv.value.c_str(), kv.value.size())) {
auto uri = link.uri.first;
auto len = link.uri.second - link.uri.first;
const std::string *scheme_ptr, *authority_ptr; const std::string *scheme_ptr, *authority_ptr;
std::string scheme, authority, path; std::string scheme, authority, path;
rv = http2::construct_push_component(scheme, authority, path, base, rv = http2::construct_push_component(scheme, authority, path, base,
baselen, uri, len); baselen, link.uri.c_str(),
link.uri.size());
if (rv != 0) { if (rv != 0) {
continue; continue;
} }