OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 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/detachable_resource_handler.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/logging.h" | |
10 #include "base/macros.h" | |
11 #include "base/memory/ptr_util.h" | |
12 #include "base/memory/weak_ptr.h" | |
13 #include "base/single_thread_task_runner.h" | |
14 #include "base/threading/thread_task_runner_handle.h" | |
15 #include "base/time/time.h" | |
16 #include "content/browser/loader/mock_resource_loader.h" | |
17 #include "content/browser/loader/resource_controller.h" | |
18 #include "content/browser/loader/test_resource_handler.h" | |
19 #include "content/public/browser/resource_request_info.h" | |
20 #include "content/public/common/resource_response.h" | |
21 #include "content/public/test/test_browser_thread_bundle.h" | |
22 #include "net/base/net_errors.h" | |
23 #include "net/url_request/redirect_info.h" | |
24 #include "net/url_request/url_request_context.h" | |
25 #include "net/url_request/url_request_status.h" | |
26 #include "net/url_request/url_request_test_util.h" | |
27 #include "testing/gtest/include/gtest/gtest.h" | |
28 #include "url/gurl.h" | |
29 | |
30 namespace content { | |
31 | |
32 namespace { | |
33 | |
34 // Full response body. | |
35 const char kResponseBody[] = "Nifty response body."; | |
36 // Two separate reads allow for testing cancellation in the middle of one read, | |
37 // and between reads. | |
38 const char kFirstBodyRead[] = "Nifty"; | |
39 const char kSecondBodyRead[] = " response body."; | |
40 | |
41 enum class DetachPhase { | |
42 DETACHED_FROM_CREATION, | |
43 ON_WILL_START, | |
44 REQUEST_REDIRECTED, | |
45 ON_RESPONSE_STARTED, | |
46 FIRST_ON_WILL_READ, | |
47 FIRST_ON_READ_COMPLETED, | |
48 SECOND_ON_WILL_READ, | |
49 SECOND_ON_READ_COMPLETED, | |
50 ON_READ_EOF, | |
51 ON_RESPONSE_COMPLETED, | |
52 NEVER_DETACH, | |
53 }; | |
54 | |
55 class DetachableResourceHandlerTest | |
56 : public testing::TestWithParam<DetachPhase> { | |
Charlie Harrison
2017/02/16 21:25:04
Very clever
| |
57 public: | |
58 DetachableResourceHandlerTest() | |
59 : request_(context_.CreateRequest(GURL("http://foo/"), | |
60 net::DEFAULT_PRIORITY, | |
61 nullptr)) { | |
62 ResourceRequestInfo::AllocateForTesting(request_.get(), | |
63 RESOURCE_TYPE_MAIN_FRAME, | |
64 nullptr, // context | |
65 0, // render_process_id | |
66 0, // render_view_id | |
67 0, // render_frame_id | |
68 true, // is_main_frame | |
69 false, // parent_is_main_frame | |
70 true, // allow_download | |
71 true, // is_async | |
72 PREVIEWS_OFF); // previews_state | |
73 | |
74 std::unique_ptr<TestResourceHandler> test_handler; | |
75 if (GetParam() != DetachPhase::DETACHED_FROM_CREATION) { | |
76 test_handler = base::MakeUnique<TestResourceHandler>(); | |
77 test_handler_ = test_handler->GetWeakPtr(); | |
78 } | |
79 // TODO(mmenke): This file currently has no timeout tests. Should it? | |
Charlie Harrison
2017/02/16 21:25:04
You have a bunch of double spaces here and in a fe
mmenke
2017/03/08 19:16:07
It doesn't. And you're supposed to use double-spa
Charlie Harrison
2017/03/08 21:12:46
OK. It doesn't matter to me as long as it's consis
| |
80 detachable_handler_ = base::MakeUnique<DetachableResourceHandler>( | |
81 request_.get(), base::TimeDelta::FromMinutes(30), | |
82 std::move(test_handler)); | |
83 mock_loader_ = | |
84 base::MakeUnique<MockResourceLoader>(detachable_handler_.get()); | |
85 } | |
86 | |
87 protected: | |
88 TestBrowserThreadBundle thread_bundle_; | |
89 net::TestURLRequestContext context_; | |
90 std::unique_ptr<net::URLRequest> request_; | |
91 | |
92 base::WeakPtr<TestResourceHandler> test_handler_; | |
93 | |
94 std::unique_ptr<DetachableResourceHandler> detachable_handler_; | |
95 std::unique_ptr<MockResourceLoader> mock_loader_; | |
96 }; | |
97 | |
98 // Tests where ResourceHandler completes synchronously. Handler is detached | |
99 // just before the phase indicated by the DetachPhase parameter. | |
100 TEST_P(DetachableResourceHandlerTest, Sync) { | |
101 if (GetParam() == DetachPhase::ON_WILL_START) { | |
Charlie Harrison
2017/02/16 21:25:04
One way to condense these tests would be to do som
mmenke
2017/03/08 19:16:06
Done. Not sure it makes the tests any easier to r
Charlie Harrison
2017/03/08 21:12:45
Thanks. For me these tests are now much easier to
| |
102 detachable_handler_->Detach(); | |
103 ASSERT_FALSE(test_handler_); | |
104 } | |
105 ASSERT_EQ(MockResourceLoader::Status::IDLE, | |
106 mock_loader_->OnWillStart(request_->url())); | |
107 if (GetParam() > DetachPhase::ON_WILL_START) { | |
108 EXPECT_EQ(1, test_handler_->on_will_start_called()); | |
109 EXPECT_EQ(0, test_handler_->on_request_redirected_called()); | |
110 } else { | |
111 EXPECT_FALSE(test_handler_); | |
112 } | |
113 | |
114 if (GetParam() == DetachPhase::REQUEST_REDIRECTED) { | |
115 detachable_handler_->Detach(); | |
116 ASSERT_FALSE(test_handler_); | |
117 } | |
118 ASSERT_EQ( | |
119 MockResourceLoader::Status::IDLE, | |
120 mock_loader_->OnRequestRedirected( | |
121 net::RedirectInfo(), make_scoped_refptr(new ResourceResponse()))); | |
122 if (GetParam() > DetachPhase::REQUEST_REDIRECTED) { | |
123 EXPECT_EQ(1, test_handler_->on_request_redirected_called()); | |
124 EXPECT_EQ(0, test_handler_->on_response_started_called()); | |
125 } else { | |
126 EXPECT_FALSE(test_handler_); | |
127 } | |
128 | |
129 if (GetParam() == DetachPhase::ON_RESPONSE_STARTED) { | |
130 detachable_handler_->Detach(); | |
131 ASSERT_FALSE(test_handler_); | |
132 } | |
133 ASSERT_EQ(MockResourceLoader::Status::IDLE, | |
134 mock_loader_->OnResponseStarted( | |
135 make_scoped_refptr(new ResourceResponse()))); | |
136 if (GetParam() > DetachPhase::ON_RESPONSE_STARTED) { | |
137 EXPECT_EQ(1, test_handler_->on_request_redirected_called()); | |
138 EXPECT_EQ(1, test_handler_->on_response_started_called()); | |
139 EXPECT_EQ(0, test_handler_->on_will_read_called()); | |
140 } else { | |
141 EXPECT_FALSE(test_handler_); | |
142 } | |
143 | |
144 if (GetParam() == DetachPhase::FIRST_ON_WILL_READ) { | |
145 detachable_handler_->Detach(); | |
146 ASSERT_FALSE(test_handler_); | |
147 } | |
148 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead()); | |
149 if (GetParam() > DetachPhase::FIRST_ON_WILL_READ) { | |
150 EXPECT_EQ(1, test_handler_->on_will_read_called()); | |
151 EXPECT_EQ(0, test_handler_->on_read_completed_called()); | |
152 } else { | |
153 EXPECT_FALSE(test_handler_); | |
154 } | |
155 | |
156 if (GetParam() == DetachPhase::FIRST_ON_READ_COMPLETED) { | |
157 detachable_handler_->Detach(); | |
158 ASSERT_FALSE(test_handler_); | |
159 } | |
160 ASSERT_EQ(MockResourceLoader::Status::IDLE, | |
161 mock_loader_->OnReadCompleted(kFirstBodyRead)); | |
162 if (GetParam() > DetachPhase::FIRST_ON_READ_COMPLETED) { | |
163 EXPECT_EQ(1, test_handler_->on_read_completed_called()); | |
164 EXPECT_EQ(kFirstBodyRead, test_handler_->body()); | |
165 } else { | |
166 EXPECT_FALSE(test_handler_); | |
167 } | |
168 | |
169 if (GetParam() == DetachPhase::SECOND_ON_WILL_READ) { | |
170 detachable_handler_->Detach(); | |
171 ASSERT_FALSE(test_handler_); | |
172 } | |
173 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead()); | |
174 if (GetParam() > DetachPhase::SECOND_ON_WILL_READ) { | |
175 EXPECT_EQ(2, test_handler_->on_will_read_called()); | |
176 EXPECT_EQ(1, test_handler_->on_read_completed_called()); | |
177 } else { | |
178 EXPECT_FALSE(test_handler_); | |
179 } | |
180 | |
181 if (GetParam() == DetachPhase::SECOND_ON_READ_COMPLETED) { | |
182 detachable_handler_->Detach(); | |
183 ASSERT_FALSE(test_handler_); | |
184 } | |
185 ASSERT_EQ(MockResourceLoader::Status::IDLE, | |
186 mock_loader_->OnReadCompleted(kSecondBodyRead)); | |
187 if (GetParam() > DetachPhase::SECOND_ON_READ_COMPLETED) { | |
188 EXPECT_EQ(2, test_handler_->on_will_read_called()); | |
189 EXPECT_EQ(2, test_handler_->on_read_completed_called()); | |
190 EXPECT_EQ(kResponseBody, test_handler_->body()); | |
191 } else { | |
192 EXPECT_FALSE(test_handler_); | |
193 } | |
194 | |
195 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead()); | |
196 if (GetParam() > DetachPhase::SECOND_ON_READ_COMPLETED) { | |
197 EXPECT_EQ(3, test_handler_->on_will_read_called()); | |
198 EXPECT_EQ(2, test_handler_->on_read_completed_called()); | |
199 EXPECT_EQ(0, test_handler_->on_response_completed_called()); | |
200 } else { | |
201 EXPECT_FALSE(test_handler_); | |
202 } | |
203 | |
204 if (GetParam() == DetachPhase::ON_READ_EOF) { | |
205 detachable_handler_->Detach(); | |
206 ASSERT_FALSE(test_handler_); | |
207 } | |
208 ASSERT_EQ(MockResourceLoader::Status::IDLE, | |
209 mock_loader_->OnReadCompleted("")); | |
210 if (GetParam() > DetachPhase::ON_READ_EOF) { | |
211 EXPECT_EQ(3, test_handler_->on_read_completed_called()); | |
212 EXPECT_EQ(1, test_handler_->on_read_eof_called()); | |
213 EXPECT_EQ(0, test_handler_->on_response_completed_called()); | |
214 } else { | |
215 EXPECT_FALSE(test_handler_); | |
216 } | |
217 | |
218 if (GetParam() == DetachPhase::ON_RESPONSE_COMPLETED) { | |
219 detachable_handler_->Detach(); | |
220 ASSERT_FALSE(test_handler_); | |
221 } | |
222 ASSERT_EQ(MockResourceLoader::Status::IDLE, | |
223 mock_loader_->OnResponseCompleted( | |
224 net::URLRequestStatus::FromError(net::OK))); | |
225 if (GetParam() > DetachPhase::ON_RESPONSE_COMPLETED) { | |
226 EXPECT_EQ(1, test_handler_->on_response_completed_called()); | |
227 EXPECT_EQ(kResponseBody, test_handler_->body()); | |
228 } else { | |
229 EXPECT_FALSE(test_handler_); | |
230 } | |
231 } | |
232 | |
233 // Tests where ResourceHandler completes asynchronously. Handler is detached | |
234 // during the phase indicated by the DetachPhase parameter. Async casees where | |
Charlie Harrison
2017/02/16 21:25:04
s/casees/cases
mmenke
2017/03/08 19:16:07
Done.
| |
235 // the handler is detached between phases are similar enough to the sync tests | |
236 // that they wouldn't provide meaningfully better test coverage. | |
237 // | |
238 // Before the handler is detached, all calls complete asynchronously. | |
239 // Afterwards, they all complete synchronously. | |
240 TEST_P(DetachableResourceHandlerTest, Async) { | |
241 if (GetParam() != DetachPhase::DETACHED_FROM_CREATION) { | |
242 test_handler_->set_defer_on_will_start(true); | |
243 test_handler_->set_defer_on_request_redirected(true); | |
244 test_handler_->set_defer_on_response_started(true); | |
245 test_handler_->set_defer_on_will_read(true); | |
246 test_handler_->set_defer_on_read_completed(true); | |
247 test_handler_->set_defer_on_read_eof(true); | |
248 // Note: Can't set |defer_on_response_completed|, since the | |
249 // DetachableResourceHandler DCHECKs when the next handler tried to defer | |
250 // the ERR_ABORTED message it sends downstream. | |
251 } | |
252 | |
253 if (GetParam() < DetachPhase::ON_WILL_START) { | |
254 ASSERT_EQ(MockResourceLoader::Status::IDLE, | |
255 mock_loader_->OnWillStart(request_->url())); | |
256 } else { | |
257 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING, | |
258 mock_loader_->OnWillStart(request_->url())); | |
259 EXPECT_EQ(1, test_handler_->on_will_start_called()); | |
260 EXPECT_EQ(0, test_handler_->on_request_redirected_called()); | |
261 if (GetParam() == DetachPhase::ON_WILL_START) { | |
262 detachable_handler_->Detach(); | |
263 ASSERT_FALSE(test_handler_); | |
264 } else { | |
265 test_handler_->Resume(); | |
266 } | |
267 } | |
268 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status()); | |
269 | |
270 if (GetParam() < DetachPhase::REQUEST_REDIRECTED) { | |
Charlie Harrison
2017/02/16 21:25:04
I don't think we could use the helper methods I de
mmenke
2017/03/08 19:16:07
Done.
| |
271 EXPECT_FALSE(test_handler_); | |
272 ASSERT_EQ( | |
273 MockResourceLoader::Status::IDLE, | |
274 mock_loader_->OnRequestRedirected( | |
275 net::RedirectInfo(), make_scoped_refptr(new ResourceResponse()))); | |
276 } else { | |
277 ASSERT_EQ( | |
278 MockResourceLoader::Status::CALLBACK_PENDING, | |
279 mock_loader_->OnRequestRedirected( | |
280 net::RedirectInfo(), make_scoped_refptr(new ResourceResponse()))); | |
281 EXPECT_EQ(1, test_handler_->on_request_redirected_called()); | |
282 EXPECT_EQ(0, test_handler_->on_response_started_called()); | |
283 if (GetParam() == DetachPhase::REQUEST_REDIRECTED) { | |
284 detachable_handler_->Detach(); | |
285 ASSERT_FALSE(test_handler_); | |
286 } else { | |
287 test_handler_->Resume(); | |
288 } | |
289 } | |
290 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status()); | |
291 | |
292 if (GetParam() < DetachPhase::ON_RESPONSE_STARTED) { | |
293 EXPECT_FALSE(test_handler_); | |
294 ASSERT_EQ(MockResourceLoader::Status::IDLE, | |
295 mock_loader_->OnResponseStarted( | |
296 make_scoped_refptr(new ResourceResponse()))); | |
297 } else { | |
298 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING, | |
299 mock_loader_->OnResponseStarted( | |
300 make_scoped_refptr(new ResourceResponse()))); | |
301 EXPECT_EQ(1, test_handler_->on_request_redirected_called()); | |
302 EXPECT_EQ(1, test_handler_->on_response_started_called()); | |
303 EXPECT_EQ(0, test_handler_->on_will_read_called()); | |
304 if (GetParam() == DetachPhase::ON_RESPONSE_STARTED) { | |
305 detachable_handler_->Detach(); | |
306 ASSERT_FALSE(test_handler_); | |
307 } else { | |
308 test_handler_->Resume(); | |
309 } | |
310 } | |
311 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status()); | |
312 | |
313 if (GetParam() < DetachPhase::FIRST_ON_WILL_READ) { | |
314 EXPECT_FALSE(test_handler_); | |
315 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead()); | |
316 } else { | |
317 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING, | |
318 mock_loader_->OnWillRead()); | |
319 EXPECT_EQ(1, test_handler_->on_will_read_called()); | |
320 EXPECT_EQ(0, test_handler_->on_read_completed_called()); | |
321 if (GetParam() == DetachPhase::FIRST_ON_WILL_READ) { | |
322 detachable_handler_->Detach(); | |
323 ASSERT_FALSE(test_handler_); | |
324 } else { | |
325 test_handler_->Resume(); | |
326 } | |
327 } | |
328 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status()); | |
329 | |
330 if (GetParam() < DetachPhase::FIRST_ON_READ_COMPLETED) { | |
331 EXPECT_FALSE(test_handler_); | |
332 ASSERT_EQ(MockResourceLoader::Status::IDLE, | |
333 mock_loader_->OnReadCompleted(kFirstBodyRead)); | |
334 } else { | |
335 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING, | |
336 mock_loader_->OnReadCompleted(kFirstBodyRead)); | |
337 EXPECT_EQ(1, test_handler_->on_read_completed_called()); | |
338 EXPECT_EQ(kFirstBodyRead, test_handler_->body()); | |
339 if (GetParam() == DetachPhase::FIRST_ON_READ_COMPLETED) { | |
340 detachable_handler_->Detach(); | |
341 ASSERT_FALSE(test_handler_); | |
342 } else { | |
343 test_handler_->Resume(); | |
344 } | |
345 } | |
346 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status()); | |
347 | |
348 if (GetParam() < DetachPhase::SECOND_ON_WILL_READ) { | |
349 EXPECT_FALSE(test_handler_); | |
350 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead()); | |
351 } else { | |
352 test_handler_->set_defer_on_will_read(true); | |
353 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING, | |
354 mock_loader_->OnWillRead()); | |
355 EXPECT_EQ(2, test_handler_->on_will_read_called()); | |
356 EXPECT_EQ(1, test_handler_->on_read_completed_called()); | |
357 if (GetParam() == DetachPhase::SECOND_ON_WILL_READ) { | |
358 detachable_handler_->Detach(); | |
359 ASSERT_FALSE(test_handler_); | |
360 } else { | |
361 test_handler_->Resume(); | |
362 } | |
363 } | |
364 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status()); | |
365 | |
366 if (GetParam() < DetachPhase::SECOND_ON_READ_COMPLETED) { | |
367 EXPECT_FALSE(test_handler_); | |
368 ASSERT_EQ(MockResourceLoader::Status::IDLE, | |
369 mock_loader_->OnReadCompleted(kSecondBodyRead)); | |
370 } else { | |
371 test_handler_->set_defer_on_read_completed(true); | |
372 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING, | |
373 mock_loader_->OnReadCompleted(kSecondBodyRead)); | |
374 EXPECT_EQ(2, test_handler_->on_will_read_called()); | |
375 EXPECT_EQ(2, test_handler_->on_read_completed_called()); | |
376 EXPECT_EQ(kResponseBody, test_handler_->body()); | |
377 if (GetParam() == DetachPhase::SECOND_ON_READ_COMPLETED) { | |
378 detachable_handler_->Detach(); | |
379 ASSERT_FALSE(test_handler_); | |
380 } else { | |
381 test_handler_->Resume(); | |
382 } | |
383 } | |
384 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status()); | |
385 | |
386 // Test doesn't check detaching on thie third OnWillRead call. | |
Charlie Harrison
2017/02/16 21:25:04
s/thie/the
mmenke
2017/03/08 19:16:07
Done.
| |
387 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead()); | |
388 if (GetParam() > DetachPhase::SECOND_ON_READ_COMPLETED) { | |
389 EXPECT_EQ(3, test_handler_->on_will_read_called()); | |
390 EXPECT_EQ(2, test_handler_->on_read_completed_called()); | |
391 EXPECT_EQ(0, test_handler_->on_response_completed_called()); | |
392 } else { | |
393 EXPECT_FALSE(test_handler_); | |
394 } | |
395 | |
396 if (GetParam() < DetachPhase::ON_READ_EOF) { | |
397 EXPECT_FALSE(test_handler_); | |
398 ASSERT_EQ(MockResourceLoader::Status::IDLE, | |
399 mock_loader_->OnReadCompleted("")); | |
400 } else { | |
401 test_handler_->set_defer_on_read_completed(true); | |
402 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING, | |
403 mock_loader_->OnReadCompleted("")); | |
404 EXPECT_EQ(3, test_handler_->on_read_completed_called()); | |
405 EXPECT_EQ(1, test_handler_->on_read_eof_called()); | |
406 EXPECT_EQ(0, test_handler_->on_response_completed_called()); | |
407 if (GetParam() == DetachPhase::ON_READ_EOF) { | |
408 detachable_handler_->Detach(); | |
409 ASSERT_FALSE(test_handler_); | |
410 } else { | |
411 test_handler_->Resume(); | |
412 } | |
413 } | |
414 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status()); | |
415 | |
416 if (GetParam() < DetachPhase::ON_RESPONSE_COMPLETED) { | |
417 EXPECT_FALSE(test_handler_); | |
418 ASSERT_EQ(MockResourceLoader::Status::IDLE, | |
419 mock_loader_->OnResponseCompleted( | |
420 net::URLRequestStatus::FromError(net::OK))); | |
421 } else { | |
422 test_handler_->set_defer_on_response_completed(true); | |
423 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING, | |
424 mock_loader_->OnResponseCompleted( | |
425 net::URLRequestStatus::FromError(net::OK))); | |
426 EXPECT_EQ(1, test_handler_->on_response_completed_called()); | |
427 EXPECT_EQ(kResponseBody, test_handler_->body()); | |
428 if (GetParam() == DetachPhase::ON_RESPONSE_COMPLETED) { | |
429 detachable_handler_->Detach(); | |
430 ASSERT_FALSE(test_handler_); | |
431 } else { | |
432 test_handler_->Resume(); | |
433 } | |
434 } | |
435 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status()); | |
436 } | |
437 | |
438 INSTANTIATE_TEST_CASE_P(/* No prefix needed*/, | |
439 DetachableResourceHandlerTest, | |
440 testing::Values(DetachPhase::DETACHED_FROM_CREATION, | |
441 DetachPhase::ON_WILL_START, | |
442 DetachPhase::REQUEST_REDIRECTED, | |
443 DetachPhase::ON_RESPONSE_STARTED, | |
444 DetachPhase::FIRST_ON_WILL_READ, | |
445 DetachPhase::FIRST_ON_READ_COMPLETED, | |
446 DetachPhase::SECOND_ON_WILL_READ, | |
447 DetachPhase::SECOND_ON_READ_COMPLETED, | |
448 DetachPhase::ON_READ_EOF, | |
449 DetachPhase::ON_RESPONSE_COMPLETED, | |
450 DetachPhase::NEVER_DETACH)); | |
451 | |
452 } // namespace | |
453 | |
454 } // namespace content | |
OLD | NEW |