| Index: content/browser/transition_request_manager.cc
|
| diff --git a/content/browser/transition_request_manager.cc b/content/browser/transition_request_manager.cc
|
| index ab651fed5511c1bd461fd06db8be13115107433e..133dc3c5bea7fa8d2fb4c1c128770363168e9661 100644
|
| --- a/content/browser/transition_request_manager.cc
|
| +++ b/content/browser/transition_request_manager.cc
|
| @@ -5,10 +5,94 @@
|
| #include "content/browser/transition_request_manager.h"
|
|
|
| #include "base/memory/singleton.h"
|
| +#include "base/strings/string_util.h"
|
| #include "content/public/browser/browser_thread.h"
|
| +#include "net/http/http_response_headers.h"
|
| +#include "net/http/http_util.h"
|
| +
|
| +namespace {
|
| +
|
| +// Enumerate all Link: headers with the specified relation in this
|
| +// response, and optionally returns the URL and any additional attributes of
|
| +// each one. See EnumerateHeaders for |iter| usage.
|
| +bool EnumerateLinkHeaders(
|
| + const scoped_refptr<net::HttpResponseHeaders>& headers,
|
| + void** iter,
|
| + const std::string& rel,
|
| + std::string* url,
|
| + std::vector<std::pair<std::string, std::string> >* attributes) {
|
| + std::string header_body;
|
| + bool rel_matched = false;
|
| + while (!rel_matched && headers->EnumerateHeader(iter, "link", &header_body)) {
|
| + const std::string::const_iterator begin = header_body.begin();
|
| + size_t url_start = header_body.find_first_of('<');
|
| + size_t url_end = header_body.find_first_of('>');
|
| + if (url_start == std::string::npos || url_end == std::string::npos ||
|
| + url_start > url_end) {
|
| + break;
|
| + }
|
| +
|
| + if (attributes)
|
| + attributes->clear();
|
| +
|
| + net::HttpUtil::NameValuePairsIterator param_iter(
|
| + begin + url_end + 1, header_body.end(), ';');
|
| +
|
| + while (param_iter.GetNext()) {
|
| + if (LowerCaseEqualsASCII(
|
| + param_iter.name_begin(), param_iter.name_end(), "rel")) {
|
| + if (LowerCaseEqualsASCII(param_iter.value_begin(),
|
| + param_iter.value_end(),
|
| + rel.c_str())) {
|
| + if (url) {
|
| + url->assign(begin + url_start + 1, begin + url_end);
|
| + }
|
| + rel_matched = true;
|
| + } else {
|
| + break;
|
| + }
|
| + } else if (attributes) {
|
| + std::string attribute_name(param_iter.name_begin(),
|
| + param_iter.name_end());
|
| + std::string attribute_value(param_iter.value_begin(),
|
| + param_iter.value_end());
|
| + attributes->push_back(std::make_pair(attribute_name, attribute_value));
|
| + }
|
| + }
|
| + }
|
| +
|
| + if (!rel_matched && attributes) {
|
| + attributes->clear();
|
| + }
|
| +
|
| + return rel_matched;
|
| +}
|
| +
|
| +} // namespace
|
|
|
| namespace content {
|
|
|
| +void TransitionRequestManager::ParseTransitionStylesheetsFromHeaders(
|
| + const scoped_refptr<net::HttpResponseHeaders>& headers,
|
| + std::vector<GURL>& entering_stylesheets,
|
| + const GURL& resolve_address) {
|
| + if (headers == NULL)
|
| + return;
|
| +
|
| + std::string transition_stylesheet;
|
| + std::vector<std::pair<std::string, std::string> > attributes;
|
| + void* header_iter = NULL;
|
| + while (EnumerateLinkHeaders(headers,
|
| + &header_iter,
|
| + "transition-entering-stylesheet",
|
| + &transition_stylesheet,
|
| + &attributes)) {
|
| + GURL stylesheet_url = resolve_address.Resolve(transition_stylesheet);
|
| + if (stylesheet_url.is_valid())
|
| + entering_stylesheets.push_back(stylesheet_url);
|
| + }
|
| +}
|
| +
|
| bool TransitionRequestManager::HasPendingTransitionRequest(
|
| int process_id,
|
| int render_frame_id) {
|
|
|