summaryrefslogtreecommitdiff
path: root/chromium/content/browser/loader/certificate_resource_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/loader/certificate_resource_handler.cc')
-rw-r--r--chromium/content/browser/loader/certificate_resource_handler.cc151
1 files changed, 151 insertions, 0 deletions
diff --git a/chromium/content/browser/loader/certificate_resource_handler.cc b/chromium/content/browser/loader/certificate_resource_handler.cc
new file mode 100644
index 00000000000..9d995428b61
--- /dev/null
+++ b/chromium/content/browser/loader/certificate_resource_handler.cc
@@ -0,0 +1,151 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/certificate_resource_handler.h"
+
+#include "base/strings/string_util.h"
+#include "content/browser/loader/resource_request_info_impl.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/common/resource_response.h"
+#include "net/base/io_buffer.h"
+#include "net/base/mime_sniffer.h"
+#include "net/base/mime_util.h"
+#include "net/http/http_response_headers.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_status.h"
+
+namespace content {
+
+CertificateResourceHandler::CertificateResourceHandler(
+ net::URLRequest* request,
+ int render_process_host_id,
+ int render_view_id)
+ : request_(request),
+ content_length_(0),
+ read_buffer_(NULL),
+ resource_buffer_(NULL),
+ render_process_host_id_(render_process_host_id),
+ render_view_id_(render_view_id),
+ cert_type_(net::CERTIFICATE_MIME_TYPE_UNKNOWN) {
+}
+
+CertificateResourceHandler::~CertificateResourceHandler() {
+}
+
+bool CertificateResourceHandler::OnUploadProgress(int request_id,
+ uint64 position,
+ uint64 size) {
+ return true;
+}
+
+bool CertificateResourceHandler::OnRequestRedirected(int request_id,
+ const GURL& url,
+ ResourceResponse* resp,
+ bool* defer) {
+ url_ = url;
+ return true;
+}
+
+bool CertificateResourceHandler::OnResponseStarted(int request_id,
+ ResourceResponse* resp,
+ bool* defer) {
+ cert_type_ = net::GetCertificateMimeTypeForMimeType(resp->head.mime_type);
+ return cert_type_ != net::CERTIFICATE_MIME_TYPE_UNKNOWN;
+}
+
+bool CertificateResourceHandler::OnWillStart(int request_id,
+ const GURL& url,
+ bool* defer) {
+ return true;
+}
+
+bool CertificateResourceHandler::OnWillRead(int request_id,
+ net::IOBuffer** buf,
+ int* buf_size,
+ int min_size) {
+ static const int kReadBufSize = 32768;
+
+ // TODO(gauravsh): Should we use 'min_size' here?
+ DCHECK(buf && buf_size);
+ if (!read_buffer_.get()) {
+ read_buffer_ = new net::IOBuffer(kReadBufSize);
+ }
+ *buf = read_buffer_.get();
+ *buf_size = kReadBufSize;
+
+ return true;
+}
+
+bool CertificateResourceHandler::OnReadCompleted(int request_id,
+ int bytes_read,
+ bool* defer) {
+ if (!bytes_read)
+ return true;
+
+ // We have more data to read.
+ DCHECK(read_buffer_.get());
+ content_length_ += bytes_read;
+
+ // Release the ownership of the buffer, and store a reference
+ // to it. A new one will be allocated in OnWillRead().
+ net::IOBuffer* buffer = NULL;
+ read_buffer_.swap(&buffer);
+ // TODO(gauravsh): Should this be handled by a separate thread?
+ buffer_.push_back(std::make_pair(buffer, bytes_read));
+
+ return true;
+}
+
+bool CertificateResourceHandler::OnResponseCompleted(
+ int request_id,
+ const net::URLRequestStatus& urs,
+ const std::string& sec_info) {
+ if (urs.status() != net::URLRequestStatus::SUCCESS)
+ return false;
+
+ AssembleResource();
+
+ const void* content_bytes = NULL;
+ if (resource_buffer_.get())
+ content_bytes = resource_buffer_->data();
+
+ // Note that it's up to the browser to verify that the certificate
+ // data is well-formed.
+ GetContentClient()->browser()->AddCertificate(
+ request_, cert_type_, content_bytes, content_length_,
+ render_process_host_id_, render_view_id_);
+
+ return true;
+}
+
+void CertificateResourceHandler::AssembleResource() {
+ // 0-length IOBuffers are not allowed.
+ if (content_length_ == 0) {
+ resource_buffer_ = NULL;
+ return;
+ }
+
+ // Create the new buffer.
+ resource_buffer_ = new net::IOBuffer(content_length_);
+
+ // Copy the data into it.
+ size_t bytes_copied = 0;
+ for (size_t i = 0; i < buffer_.size(); ++i) {
+ net::IOBuffer* data = buffer_[i].first.get();
+ size_t data_len = buffer_[i].second;
+ DCHECK(data != NULL);
+ DCHECK_LE(bytes_copied + data_len, content_length_);
+ memcpy(resource_buffer_->data() + bytes_copied, data->data(), data_len);
+ bytes_copied += data_len;
+ }
+ DCHECK_EQ(content_length_, bytes_copied);
+}
+
+void CertificateResourceHandler::OnDataDownloaded(
+ int request_id,
+ int bytes_downloaded) {
+ NOTREACHED();
+}
+
+} // namespace content