Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: content/browser/loader/intercepting_resource_handler.cc

Issue 2005273002: Move MimeTypeResourceHandler before ThrottlingResourceHandler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed compilation error on Mac Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/loader/intercepting_resource_handler.h"
6
7 #include <utility>
mmenke 2016/08/22 20:39:03 What's this needed for (Sorry if I already asked t
clamy 2016/09/01 23:19:40 It was no longer needed. Removed it.
8
9 #include "base/logging.h"
10 #include "base/strings/string_util.h"
11 #include "content/public/common/resource_response.h"
12 #include "net/base/io_buffer.h"
13
14 namespace content {
15
16 InterceptingResourceHandler::InterceptingResourceHandler(
17 std::unique_ptr<ResourceHandler> next_handler,
18 net::URLRequest* request)
19 : LayeredResourceHandler(request, std::move(next_handler)),
20 state_(State::STARTING),
21 first_read_buffer_size_(0) {}
22
23 InterceptingResourceHandler::~InterceptingResourceHandler() {}
24
25 bool InterceptingResourceHandler::OnResponseStarted(ResourceResponse* response,
26 bool* defer) {
27 // If there's no need to switch handlers, just start acting as a blind
28 // pass-through ResourceHandler.
29 if (!new_handler_) {
30 state_ = State::DONE;
31 first_read_buffer_ = nullptr;
32 return next_handler_->OnResponseStarted(response, defer);
33 }
34
35 // Otherwise, switch handlers. First, inform the original ResourceHandler
36 // that this will be handled entirely by the new ResourceHandler.
37 // TODO(clamy): We will probably need to check the return values of these for
38 // PlzNavigate.
39 bool defer_ignored = false;
40 next_handler_->OnResponseStarted(response, &defer_ignored);
41
42 // Although deferring OnResponseStarted is legal, the only downstream handler
43 // which does so is CrossSiteResourceHandler. Cross-site transitions should
44 // not trigger when switching handlers.
45 DCHECK(!defer_ignored);
46
47 // Make a copy of the data in the first read buffer. This data should be
48 // passed to the alternate ResourceHandler and not to to the current
49 // ResourceHandler.
mmenke 2016/08/19 16:33:02 I think it's worth noting the weird magic here. "
clamy 2016/09/01 23:19:40 I've updated the comment and added a TODO to check
50 if (first_read_buffer_) {
51 first_read_buffer_copy_ = new net::IOBuffer(first_read_buffer_size_);
52 memcpy(first_read_buffer_copy_->data(), first_read_buffer_->data(),
53 first_read_buffer_size_);
54 }
55
56 // Send the payload to the old handler.
57 SendPayloadToOldHandler();
58 first_read_buffer_ = nullptr;
59
60 // This is now handled entirely within the new ResourceHandler, so just reset
61 // the original ResourceHandler.
mmenke 2016/08/19 16:33:02 "This" seems unclear. Maybe "The original Resourc
clamy 2016/09/01 23:19:40 Done.
62 next_handler_ = std::move(new_handler_);
63
64 state_ =
65 first_read_buffer_copy_ ? State::WAITING_FOR_BUFFER_COPY : State::DONE;
66
67 return next_handler_->OnResponseStarted(response, defer);
68 }
69
70 bool InterceptingResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
71 int* buf_size,
72 int min_size) {
73 if (state_ == State::DONE)
74 return next_handler_->OnWillRead(buf, buf_size, min_size);
75
76 DCHECK_EQ(State::STARTING, state_);
77 DCHECK_EQ(-1, min_size);
78
79 if (!next_handler_->OnWillRead(buf, buf_size, min_size))
80 return false;
81
82 first_read_buffer_ = *buf;
83 first_read_buffer_size_ = *buf_size;
84 return true;
85 }
86
87 bool InterceptingResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
88 if (state_ == State::DONE)
89 return next_handler_->OnReadCompleted(bytes_read, defer);
90
91 DCHECK_EQ(State::WAITING_FOR_BUFFER_COPY, state_);
92 state_ = State::DONE;
93
94 // Copy the data from the first read to the new ResourceHandler.
95 scoped_refptr<net::IOBuffer> buf;
96 int buf_len = 0;
97 if (!next_handler_->OnWillRead(&buf, &buf_len, bytes_read))
98 return false;
99
100 CHECK((buf_len >= bytes_read) && (bytes_read >= 0));
mmenke 2016/08/22 20:39:04 Split this in two - makes it clearer which one fai
clamy 2016/09/01 23:19:40 Done.
101 CHECK_GE(first_read_buffer_size_, static_cast<size_t>(bytes_read));
mmenke 2016/08/22 20:39:04 CHECK -> DCHECK (x2)
clamy 2016/09/01 23:19:40 Considering we're about to write memory in the mem
102 memcpy(buf->data(), first_read_buffer_copy_->data(), bytes_read);
103
104 first_read_buffer_copy_ = nullptr;
105
106 return next_handler_->OnReadCompleted(bytes_read, defer);
mmenke 2016/08/22 20:39:03 No unit tests make sure we pass through defer here
clamy 2016/09/01 23:19:40 Added a TODO.
107 }
108
109 void InterceptingResourceHandler::UseNewHandler(
110 std::unique_ptr<ResourceHandler> new_handler,
111 const std::string& payload_for_old_handler) {
112 new_handler_ = std::move(new_handler);
113 new_handler_->SetController(controller());
114 payload_for_old_handler_ = payload_for_old_handler;
115 }
116
117 void InterceptingResourceHandler::SendPayloadToOldHandler() {
118 bool defer_ignored = false;
119 if (payload_for_old_handler_.empty()) {
120 // If there is no payload, just finalize the request on the old handler.
121 net::URLRequestStatus status(net::URLRequestStatus::CANCELED,
122 net::ERR_ABORTED);
123 next_handler_->OnResponseCompleted(status, std::string(), &defer_ignored);
124 DCHECK(!defer_ignored);
125 return;
126 }
127
128 // Ensure the old ResourceHandler has a buffer that can store the payload.
129 scoped_refptr<net::IOBuffer> buf;
130 int size = 0;
131 if (first_read_buffer_) {
132 // The first read buffer can be reused. The data inside it has been copied
133 // before calling this function, so it can safely be overriden.
134 buf = first_read_buffer_;
135 size = first_read_buffer_size_;
136 }
137
138 // If there is no first read buffer, ask the old ResourceHandler to create a
139 // buffer that can contain payload.
140 if (!buf)
141 next_handler_->OnWillRead(&buf, &size, -1);
142
143 CHECK(buf);
144 CHECK_GE(size, static_cast<int>(payload_for_old_handler_.length()));
mmenke 2016/08/22 20:39:04 CHECK->DCHECK (x2)
clamy 2016/09/01 23:19:40 Same comment as before. I left these as CHECKs bec
145 memcpy(buf->data(), payload_for_old_handler_.c_str(),
146 payload_for_old_handler_.length());
147 next_handler_->OnReadCompleted(payload_for_old_handler_.length(),
mmenke 2016/08/22 20:39:03 I assume payload_for_old_handler_ is short enough
clamy 2016/09/01 23:19:40 I now reset it to an empty string.
148 &defer_ignored);
149 DCHECK(!defer_ignored);
150
151 // Finalize the request.
152 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
153 next_handler_->OnResponseCompleted(status, std::string(), &defer_ignored);
154 DCHECK(!defer_ignored);
155 }
156
157 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698