Commit 9ad5e09c authored by Kunihiko Sakamoto's avatar Kunihiko Sakamoto Committed by Commit Bot

Move response header handling logic to SignedExchangeHeader

After this refactoring, SignedExchangeHeader
- Validates response header names and values, and
- Constructs HttpResponseHeaders from the response header map.

Bug: 803774
Change-Id: I25c91db1f07c4fcd0e6c62a9d4aa409838361349
Reviewed-on: https://chromium-review.googlesource.com/958647Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Commit-Queue: Kunihiko Sakamoto <ksakamoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542687}
parent 5529bc63
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include "content/browser/web_package/signed_exchange_handler.h" #include "content/browser/web_package/signed_exchange_handler.h"
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/loader/merkle_integrity_source_stream.h" #include "content/browser/loader/merkle_integrity_source_stream.h"
#include "content/browser/web_package/signed_exchange_cert_fetcher.h" #include "content/browser/web_package/signed_exchange_cert_fetcher.h"
#include "content/browser/web_package/signed_exchange_consts.h" #include "content/browser/web_package/signed_exchange_consts.h"
...@@ -20,8 +19,6 @@ ...@@ -20,8 +19,6 @@
#include "net/cert/cert_verifier.h" #include "net/cert/cert_verifier.h"
#include "net/cert/x509_certificate.h" #include "net/cert/x509_certificate.h"
#include "net/filter/source_stream.h" #include "net/filter/source_stream.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/ssl/ssl_config.h" #include "net/ssl/ssl_config.h"
#include "net/ssl/ssl_config_service.h" #include "net/ssl/ssl_config_service.h"
#include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context.h"
...@@ -169,44 +166,6 @@ bool SignedExchangeHandler::ParseHeadersAndFetchCertificate() { ...@@ -169,44 +166,6 @@ bool SignedExchangeHandler::ParseHeadersAndFetchCertificate() {
return false; return false;
} }
// TODO(https://crbug.com/803774): implement the following logic in
// SignedExchangeHeaderParser.
std::string fake_header_str("HTTP/1.1 ");
fake_header_str.append(base::NumberToString(header_->response_code()));
fake_header_str.append(" ");
fake_header_str.append(net::GetHttpReasonPhrase(header_->response_code()));
fake_header_str.append(" \r\n");
for (const auto& it : header_->response_headers()) {
if (!net::HttpUtil::IsValidHeaderName(it.first)) {
DVLOG(1) << "Invalid header name";
return false;
}
if (!net::HttpUtil::IsValidHeaderValue(it.second)) {
DVLOG(1) << "Invalid header value";
return false;
}
fake_header_str.append(it.first);
fake_header_str.append(": ");
fake_header_str.append(it.second);
fake_header_str.append("\r\n");
}
fake_header_str.append("\r\n");
response_head_.headers = base::MakeRefCounted<net::HttpResponseHeaders>(
net::HttpUtil::AssembleRawHeaders(fake_header_str.c_str(),
fake_header_str.size()));
// TODO(https://crbug.com/803774): |mime_type| should be derived from
// "Content-Type" header.
response_head_.mime_type = "text/html";
std::string mi_header_value;
if (!response_head_.headers->EnumerateHeader(nullptr, kMiHeader,
&mi_header_value)) {
DVLOG(1) << "Signed exchange has no MI: header";
return false;
}
mi_stream_ = std::make_unique<MerkleIntegritySourceStream>(
mi_header_value, std::move(source_));
const GURL cert_url = header_->signature().cert_url; const GURL cert_url = header_->signature().cert_url;
// TODO(https://crbug.com/819467): When we will support ed25519Key, |cert_url| // TODO(https://crbug.com/819467): When we will support ed25519Key, |cert_url|
// may be empty. // may be empty.
...@@ -287,6 +246,22 @@ void SignedExchangeHandler::OnCertVerifyComplete(int result) { ...@@ -287,6 +246,22 @@ void SignedExchangeHandler::OnCertVerifyComplete(int result) {
return; return;
} }
network::ResourceResponseHead response_head;
response_head.headers = header_->BuildHttpResponseHeaders();
// TODO(https://crbug.com/803774): |mime_type| should be derived from
// "Content-Type" header.
response_head.mime_type = "text/html";
std::string mi_header_value;
if (!response_head.headers->EnumerateHeader(nullptr, kMiHeader,
&mi_header_value)) {
DVLOG(1) << "Signed exchange has no MI: header";
RunErrorCallback(net::ERR_FAILED);
return;
}
auto mi_stream = std::make_unique<MerkleIntegritySourceStream>(
mi_header_value, std::move(source_));
net::SSLInfo ssl_info; net::SSLInfo ssl_info;
ssl_info.cert = cert_verify_result_.verified_cert; ssl_info.cert = cert_verify_result_.verified_cert;
ssl_info.unverified_cert = unverified_cert_; ssl_info.unverified_cert = unverified_cert_;
...@@ -301,7 +276,7 @@ void SignedExchangeHandler::OnCertVerifyComplete(int result) { ...@@ -301,7 +276,7 @@ void SignedExchangeHandler::OnCertVerifyComplete(int result) {
// TODO(https://crbug.com/815025): Verify the Certificate Transparency status. // TODO(https://crbug.com/815025): Verify the Certificate Transparency status.
std::move(headers_callback_) std::move(headers_callback_)
.Run(net::OK, header_->request_url(), header_->request_method(), .Run(net::OK, header_->request_url(), header_->request_method(),
response_head_, std::move(mi_stream_), ssl_info); response_head, std::move(mi_stream), ssl_info);
state_ = State::kHeadersCallbackCalled; state_ = State::kHeadersCallbackCalled;
} }
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "net/cert/cert_verify_result.h" #include "net/cert/cert_verify_result.h"
#include "net/log/net_log_with_source.h" #include "net/log/net_log_with_source.h"
#include "net/ssl/ssl_info.h" #include "net/ssl/ssl_info.h"
#include "services/network/public/cpp/resource_response.h"
#include "url/gurl.h" #include "url/gurl.h"
#include "url/origin.h" #include "url/origin.h"
...@@ -31,12 +30,15 @@ class URLRequestContextGetter; ...@@ -31,12 +30,15 @@ class URLRequestContextGetter;
class X509Certificate; class X509Certificate;
} // namespace net } // namespace net
namespace network {
struct ResourceResponseHead;
}
namespace content { namespace content {
class SharedURLLoaderFactory; class SharedURLLoaderFactory;
class SignedExchangeCertFetcher; class SignedExchangeCertFetcher;
class URLLoaderThrottle; class URLLoaderThrottle;
class MerkleIntegritySourceStream;
// IMPORTANT: Currenly SignedExchangeHandler partially implements the verifying // IMPORTANT: Currenly SignedExchangeHandler partially implements the verifying
// logic. // logic.
...@@ -95,9 +97,6 @@ class CONTENT_EXPORT SignedExchangeHandler { ...@@ -95,9 +97,6 @@ class CONTENT_EXPORT SignedExchangeHandler {
scoped_refptr<net::X509Certificate> cert); scoped_refptr<net::X509Certificate> cert);
void OnCertVerifyComplete(int result); void OnCertVerifyComplete(int result);
// Signed exchange contents.
network::ResourceResponseHead response_head_;
ExchangeHeadersCallback headers_callback_; ExchangeHeadersCallback headers_callback_;
std::unique_ptr<net::SourceStream> source_; std::unique_ptr<net::SourceStream> source_;
...@@ -109,7 +108,6 @@ class CONTENT_EXPORT SignedExchangeHandler { ...@@ -109,7 +108,6 @@ class CONTENT_EXPORT SignedExchangeHandler {
size_t headers_length_ = 0; size_t headers_length_ = 0;
base::Optional<SignedExchangeHeader> header_; base::Optional<SignedExchangeHeader> header_;
std::unique_ptr<MerkleIntegritySourceStream> mi_stream_;
// Used to create |cert_fetcher_|. // Used to create |cert_fetcher_|.
url::Origin request_initiator_; url::Origin request_initiator_;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
#include "components/cbor/cbor_reader.h" #include "components/cbor/cbor_reader.h"
#include "content/browser/web_package/signed_exchange_consts.h" #include "content/browser/web_package/signed_exchange_consts.h"
#include "net/http/http_util.h"
namespace content { namespace content {
...@@ -77,8 +78,16 @@ bool ParseResponseMap(const cbor::CBORValue& value, SignedExchangeHeader* out) { ...@@ -77,8 +78,16 @@ bool ParseResponseMap(const cbor::CBORValue& value, SignedExchangeHeader* out) {
base::StringPiece name_str = it.first.GetBytestringAsString(); base::StringPiece name_str = it.first.GetBytestringAsString();
if (name_str == kStatusKey) if (name_str == kStatusKey)
continue; continue;
if (!net::HttpUtil::IsValidHeaderName(name_str)) {
DVLOG(1) << "Invalid header name";
return false;
}
base::StringPiece value_str = it.second.GetBytestringAsString(); base::StringPiece value_str = it.second.GetBytestringAsString();
if (!net::HttpUtil::IsValidHeaderValue(value_str)) {
DVLOG(1) << "Invalid header value";
return false;
}
out->AddResponseHeader(name_str, value_str); out->AddResponseHeader(name_str, value_str);
} }
...@@ -159,4 +168,23 @@ void SignedExchangeHeader::AddResponseHeader(base::StringPiece name, ...@@ -159,4 +168,23 @@ void SignedExchangeHeader::AddResponseHeader(base::StringPiece name,
response_headers_[name_string] = value_string; response_headers_[name_string] = value_string;
} }
scoped_refptr<net::HttpResponseHeaders>
SignedExchangeHeader::BuildHttpResponseHeaders() const {
std::string fake_header_str("HTTP/1.1 ");
fake_header_str.append(base::NumberToString(response_code()));
fake_header_str.append(" ");
fake_header_str.append(net::GetHttpReasonPhrase(response_code()));
fake_header_str.append(" \r\n");
for (const auto& it : response_headers()) {
fake_header_str.append(it.first);
fake_header_str.append(": ");
fake_header_str.append(it.second);
fake_header_str.append("\r\n");
}
fake_header_str.append("\r\n");
return base::MakeRefCounted<net::HttpResponseHeaders>(
net::HttpUtil::AssembleRawHeaders(fake_header_str.c_str(),
fake_header_str.size()));
}
} // namespace content } // namespace content
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
#include "content/browser/web_package/signed_exchange_header_parser.h" #include "content/browser/web_package/signed_exchange_header_parser.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h" #include "net/http/http_status_code.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -54,6 +55,7 @@ class CONTENT_EXPORT SignedExchangeHeader { ...@@ -54,6 +55,7 @@ class CONTENT_EXPORT SignedExchangeHeader {
~SignedExchangeHeader(); ~SignedExchangeHeader();
void AddResponseHeader(base::StringPiece name, base::StringPiece value); void AddResponseHeader(base::StringPiece name, base::StringPiece value);
scoped_refptr<net::HttpResponseHeaders> BuildHttpResponseHeaders() const;
const GURL& request_url() const { return request_url_; }; const GURL& request_url() const { return request_url_; };
void set_request_url(GURL url) { request_url_ = std::move(url); } void set_request_url(GURL url) { request_url_ = std::move(url); }
......
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