1 // Copyright (c) 2012 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 "net/url_request/url_request_test_util.h" 6 7 #include "base/compiler_specific.h" 8 #include "base/logging.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/threading/thread.h" 11 #include "base/threading/worker_pool.h" 12 #include "net/base/host_port_pair.h" 13 #include "net/cert/cert_verifier.h" 14 #include "net/dns/mock_host_resolver.h" 15 #include "net/http/http_network_session.h" 16 #include "net/http/http_response_headers.h" 17 #include "net/http/http_server_properties_impl.h" 18 #include "net/http/transport_security_state.h" 19 #include "net/ssl/default_server_bound_cert_store.h" 20 #include "net/ssl/server_bound_cert_service.h" 21 #include "net/url_request/static_http_user_agent_settings.h" 22 #include "net/url_request/url_request_job_factory_impl.h" 23 #include "testing/gtest/include/gtest/gtest.h" 24 25 namespace net { 26 27 namespace { 28 29 // These constants put the NetworkDelegate events of TestNetworkDelegate 30 // into an order. They are used in conjunction with 31 // |TestNetworkDelegate::next_states_| to check that we do not send 32 // events in the wrong order. 33 const int kStageBeforeURLRequest = 1 << 0; 34 const int kStageBeforeSendHeaders = 1 << 1; 35 const int kStageSendHeaders = 1 << 2; 36 const int kStageHeadersReceived = 1 << 3; 37 const int kStageAuthRequired = 1 << 4; 38 const int kStageBeforeRedirect = 1 << 5; 39 const int kStageResponseStarted = 1 << 6; 40 const int kStageCompletedSuccess = 1 << 7; 41 const int kStageCompletedError = 1 << 8; 42 const int kStageURLRequestDestroyed = 1 << 9; 43 const int kStageDestruction = 1 << 10; 44 45 } // namespace 46 47 TestURLRequestContext::TestURLRequestContext() 48 : initialized_(false), 49 client_socket_factory_(NULL), 50 context_storage_(this) { 51 Init(); 52 } 53 54 TestURLRequestContext::TestURLRequestContext(bool delay_initialization) 55 : initialized_(false), 56 client_socket_factory_(NULL), 57 context_storage_(this) { 58 if (!delay_initialization) 59 Init(); 60 } 61 62 TestURLRequestContext::~TestURLRequestContext() { 63 DCHECK(initialized_); 64 } 65 66 void TestURLRequestContext::Init() { 67 DCHECK(!initialized_); 68 initialized_ = true; 69 70 if (!host_resolver()) 71 context_storage_.set_host_resolver( 72 scoped_ptr<HostResolver>(new MockCachingHostResolver())); 73 if (!proxy_service()) 74 context_storage_.set_proxy_service(ProxyService::CreateDirect()); 75 if (!cert_verifier()) 76 context_storage_.set_cert_verifier(CertVerifier::CreateDefault()); 77 if (!transport_security_state()) 78 context_storage_.set_transport_security_state(new TransportSecurityState); 79 if (!ssl_config_service()) 80 context_storage_.set_ssl_config_service(new SSLConfigServiceDefaults); 81 if (!http_auth_handler_factory()) { 82 context_storage_.set_http_auth_handler_factory( 83 HttpAuthHandlerFactory::CreateDefault(host_resolver())); 84 } 85 if (!http_server_properties()) { 86 context_storage_.set_http_server_properties( 87 scoped_ptr<HttpServerProperties>(new HttpServerPropertiesImpl())); 88 } 89 if (!transport_security_state()) { 90 context_storage_.set_transport_security_state( 91 new TransportSecurityState()); 92 } 93 if (http_transaction_factory()) { 94 // Make sure we haven't been passed an object we're not going to use. 95 EXPECT_FALSE(client_socket_factory_); 96 } else { 97 HttpNetworkSession::Params params; 98 if (http_network_session_params_) 99 params = *http_network_session_params_; 100 params.client_socket_factory = client_socket_factory(); 101 params.host_resolver = host_resolver(); 102 params.cert_verifier = cert_verifier(); 103 params.transport_security_state = transport_security_state(); 104 params.proxy_service = proxy_service(); 105 params.ssl_config_service = ssl_config_service(); 106 params.http_auth_handler_factory = http_auth_handler_factory(); 107 params.network_delegate = network_delegate(); 108 params.http_server_properties = http_server_properties(); 109 params.net_log = net_log(); 110 context_storage_.set_http_transaction_factory(new HttpCache( 111 new HttpNetworkSession(params), 112 HttpCache::DefaultBackend::InMemory(0))); 113 } 114 // In-memory cookie store. 115 if (!cookie_store()) 116 context_storage_.set_cookie_store(new CookieMonster(NULL, NULL)); 117 // In-memory origin bound cert service. 118 if (!server_bound_cert_service()) { 119 context_storage_.set_server_bound_cert_service( 120 new ServerBoundCertService( 121 new DefaultServerBoundCertStore(NULL), 122 base::WorkerPool::GetTaskRunner(true))); 123 } 124 if (!http_user_agent_settings()) { 125 context_storage_.set_http_user_agent_settings( 126 new StaticHttpUserAgentSettings("en-us,fr", std::string())); 127 } 128 if (!job_factory()) 129 context_storage_.set_job_factory(new URLRequestJobFactoryImpl); 130 } 131 132 TestURLRequest::TestURLRequest(const GURL& url, 133 RequestPriority priority, 134 Delegate* delegate, 135 TestURLRequestContext* context) 136 : URLRequest(url, priority, delegate, context) {} 137 138 TestURLRequest::~TestURLRequest() { 139 } 140 141 TestURLRequestContextGetter::TestURLRequestContextGetter( 142 const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner) 143 : network_task_runner_(network_task_runner) { 144 DCHECK(network_task_runner_.get()); 145 } 146 147 TestURLRequestContextGetter::TestURLRequestContextGetter( 148 const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner, 149 scoped_ptr<TestURLRequestContext> context) 150 : network_task_runner_(network_task_runner), context_(context.Pass()) { 151 DCHECK(network_task_runner_.get()); 152 } 153 154 TestURLRequestContextGetter::~TestURLRequestContextGetter() {} 155 156 TestURLRequestContext* TestURLRequestContextGetter::GetURLRequestContext() { 157 if (!context_.get()) 158 context_.reset(new TestURLRequestContext); 159 return context_.get(); 160 } 161 162 scoped_refptr<base::SingleThreadTaskRunner> 163 TestURLRequestContextGetter::GetNetworkTaskRunner() const { 164 return network_task_runner_; 165 } 166 167 TestDelegate::TestDelegate() 168 : cancel_in_rr_(false), 169 cancel_in_rs_(false), 170 cancel_in_rd_(false), 171 cancel_in_rd_pending_(false), 172 quit_on_complete_(true), 173 quit_on_redirect_(false), 174 quit_on_before_network_start_(false), 175 allow_certificate_errors_(false), 176 response_started_count_(0), 177 received_bytes_count_(0), 178 received_redirect_count_(0), 179 received_before_network_start_count_(0), 180 received_data_before_response_(false), 181 request_failed_(false), 182 have_certificate_errors_(false), 183 certificate_errors_are_fatal_(false), 184 auth_required_(false), 185 have_full_request_headers_(false), 186 buf_(new IOBuffer(kBufferSize)) { 187 } 188 189 TestDelegate::~TestDelegate() {} 190 191 void TestDelegate::ClearFullRequestHeaders() { 192 full_request_headers_.Clear(); 193 have_full_request_headers_ = false; 194 } 195 196 void TestDelegate::OnReceivedRedirect(URLRequest* request, 197 const GURL& new_url, 198 bool* defer_redirect) { 199 EXPECT_TRUE(request->is_redirecting()); 200 201 have_full_request_headers_ = 202 request->GetFullRequestHeaders(&full_request_headers_); 203 204 received_redirect_count_++; 205 if (quit_on_redirect_) { 206 *defer_redirect = true; 207 base::MessageLoop::current()->PostTask(FROM_HERE, 208 base::MessageLoop::QuitClosure()); 209 } else if (cancel_in_rr_) { 210 request->Cancel(); 211 } 212 } 213 214 void TestDelegate::OnBeforeNetworkStart(URLRequest* request, bool* defer) { 215 received_before_network_start_count_++; 216 if (quit_on_before_network_start_) { 217 *defer = true; 218 base::MessageLoop::current()->PostTask(FROM_HERE, 219 base::MessageLoop::QuitClosure()); 220 } 221 } 222 223 void TestDelegate::OnAuthRequired(URLRequest* request, 224 AuthChallengeInfo* auth_info) { 225 auth_required_ = true; 226 if (!credentials_.Empty()) { 227 request->SetAuth(credentials_); 228 } else { 229 request->CancelAuth(); 230 } 231 } 232 233 void TestDelegate::OnSSLCertificateError(URLRequest* request, 234 const SSLInfo& ssl_info, 235 bool fatal) { 236 // The caller can control whether it needs all SSL requests to go through, 237 // independent of any possible errors, or whether it wants SSL errors to 238 // cancel the request. 239 have_certificate_errors_ = true; 240 certificate_errors_are_fatal_ = fatal; 241 if (allow_certificate_errors_) 242 request->ContinueDespiteLastError(); 243 else 244 request->Cancel(); 245 } 246 247 void TestDelegate::OnResponseStarted(URLRequest* request) { 248 // It doesn't make sense for the request to have IO pending at this point. 249 DCHECK(!request->status().is_io_pending()); 250 EXPECT_FALSE(request->is_redirecting()); 251 252 have_full_request_headers_ = 253 request->GetFullRequestHeaders(&full_request_headers_); 254 255 response_started_count_++; 256 if (cancel_in_rs_) { 257 request->Cancel(); 258 OnResponseCompleted(request); 259 } else if (!request->status().is_success()) { 260 DCHECK(request->status().status() == URLRequestStatus::FAILED || 261 request->status().status() == URLRequestStatus::CANCELED); 262 request_failed_ = true; 263 OnResponseCompleted(request); 264 } else { 265 // Initiate the first read. 266 int bytes_read = 0; 267 if (request->Read(buf_.get(), kBufferSize, &bytes_read)) 268 OnReadCompleted(request, bytes_read); 269 else if (!request->status().is_io_pending()) 270 OnResponseCompleted(request); 271 } 272 } 273 274 void TestDelegate::OnReadCompleted(URLRequest* request, int bytes_read) { 275 // It doesn't make sense for the request to have IO pending at this point. 276 DCHECK(!request->status().is_io_pending()); 277 278 if (response_started_count_ == 0) 279 received_data_before_response_ = true; 280 281 if (cancel_in_rd_) 282 request->Cancel(); 283 284 if (bytes_read >= 0) { 285 // There is data to read. 286 received_bytes_count_ += bytes_read; 287 288 // consume the data 289 data_received_.append(buf_->data(), bytes_read); 290 } 291 292 // If it was not end of stream, request to read more. 293 if (request->status().is_success() && bytes_read > 0) { 294 bytes_read = 0; 295 while (request->Read(buf_.get(), kBufferSize, &bytes_read)) { 296 if (bytes_read > 0) { 297 data_received_.append(buf_->data(), bytes_read); 298 received_bytes_count_ += bytes_read; 299 } else { 300 break; 301 } 302 } 303 } 304 if (!request->status().is_io_pending()) 305 OnResponseCompleted(request); 306 else if (cancel_in_rd_pending_) 307 request->Cancel(); 308 } 309 310 void TestDelegate::OnResponseCompleted(URLRequest* request) { 311 if (quit_on_complete_) 312 base::MessageLoop::current()->PostTask(FROM_HERE, 313 base::MessageLoop::QuitClosure()); 314 } 315 316 TestNetworkDelegate::TestNetworkDelegate() 317 : last_error_(0), 318 error_count_(0), 319 created_requests_(0), 320 destroyed_requests_(0), 321 completed_requests_(0), 322 canceled_requests_(0), 323 cookie_options_bit_mask_(0), 324 blocked_get_cookies_count_(0), 325 blocked_set_cookie_count_(0), 326 set_cookie_count_(0), 327 has_load_timing_info_before_redirect_(false), 328 has_load_timing_info_before_auth_(false), 329 can_access_files_(true), 330 can_throttle_requests_(true) { 331 } 332 333 TestNetworkDelegate::~TestNetworkDelegate() { 334 for (std::map<int, int>::iterator i = next_states_.begin(); 335 i != next_states_.end(); ++i) { 336 event_order_[i->first] += "~TestNetworkDelegate\n"; 337 EXPECT_TRUE(i->second & kStageDestruction) << event_order_[i->first]; 338 } 339 } 340 341 bool TestNetworkDelegate::GetLoadTimingInfoBeforeRedirect( 342 LoadTimingInfo* load_timing_info_before_redirect) const { 343 *load_timing_info_before_redirect = load_timing_info_before_redirect_; 344 return has_load_timing_info_before_redirect_; 345 } 346 347 bool TestNetworkDelegate::GetLoadTimingInfoBeforeAuth( 348 LoadTimingInfo* load_timing_info_before_auth) const { 349 *load_timing_info_before_auth = load_timing_info_before_auth_; 350 return has_load_timing_info_before_auth_; 351 } 352 353 void TestNetworkDelegate::InitRequestStatesIfNew(int request_id) { 354 if (next_states_.find(request_id) == next_states_.end()) { 355 // TODO(davidben): Although the URLRequest documentation does not allow 356 // calling Cancel() before Start(), the ResourceLoader does so. URLRequest's 357 // destructor also calls Cancel. Either officially support this or fix the 358 // ResourceLoader code. 359 next_states_[request_id] = kStageBeforeURLRequest | kStageCompletedError; 360 event_order_[request_id] = ""; 361 } 362 } 363 364 int TestNetworkDelegate::OnBeforeURLRequest( 365 URLRequest* request, 366 const CompletionCallback& callback, 367 GURL* new_url ) { 368 int req_id = request->identifier(); 369 InitRequestStatesIfNew(req_id); 370 event_order_[req_id] += "OnBeforeURLRequest\n"; 371 EXPECT_TRUE(next_states_[req_id] & kStageBeforeURLRequest) << 372 event_order_[req_id]; 373 next_states_[req_id] = 374 kStageBeforeSendHeaders | 375 kStageResponseStarted | // data: URLs do not trigger sending headers 376 kStageBeforeRedirect | // a delegate can trigger a redirection 377 kStageCompletedError | // request canceled by delegate 378 kStageAuthRequired; // Auth can come next for FTP requests 379 created_requests_++; 380 return OK; 381 } 382 383 int TestNetworkDelegate::OnBeforeSendHeaders( 384 URLRequest* request, 385 const CompletionCallback& callback, 386 HttpRequestHeaders* headers) { 387 int req_id = request->identifier(); 388 InitRequestStatesIfNew(req_id); 389 event_order_[req_id] += "OnBeforeSendHeaders\n"; 390 EXPECT_TRUE(next_states_[req_id] & kStageBeforeSendHeaders) << 391 event_order_[req_id]; 392 next_states_[req_id] = 393 kStageSendHeaders | 394 kStageCompletedError; // request canceled by delegate 395 396 return OK; 397 } 398 399 void TestNetworkDelegate::OnSendHeaders( 400 URLRequest* request, 401 const HttpRequestHeaders& headers) { 402 int req_id = request->identifier(); 403 InitRequestStatesIfNew(req_id); 404 event_order_[req_id] += "OnSendHeaders\n"; 405 EXPECT_TRUE(next_states_[req_id] & kStageSendHeaders) << 406 event_order_[req_id]; 407 next_states_[req_id] = 408 kStageHeadersReceived | 409 kStageCompletedError; 410 } 411 412 int TestNetworkDelegate::OnHeadersReceived( 413 URLRequest* request, 414 const CompletionCallback& callback, 415 const HttpResponseHeaders* original_response_headers, 416 scoped_refptr<HttpResponseHeaders>* override_response_headers, 417 GURL* allowed_unsafe_redirect_url) { 418 int req_id = request->identifier(); 419 event_order_[req_id] += "OnHeadersReceived\n"; 420 InitRequestStatesIfNew(req_id); 421 EXPECT_TRUE(next_states_[req_id] & kStageHeadersReceived) << 422 event_order_[req_id]; 423 next_states_[req_id] = 424 kStageBeforeRedirect | 425 kStageResponseStarted | 426 kStageAuthRequired | 427 kStageCompletedError; // e.g. proxy resolution problem 428 429 // Basic authentication sends a second request from the URLRequestHttpJob 430 // layer before the URLRequest reports that a response has started. 431 next_states_[req_id] |= kStageBeforeSendHeaders; 432 433 if (!redirect_on_headers_received_url_.is_empty()) { 434 *override_response_headers = 435 new net::HttpResponseHeaders(original_response_headers->raw_headers()); 436 (*override_response_headers)->ReplaceStatusLine("HTTP/1.1 302 Found"); 437 (*override_response_headers)->RemoveHeader("Location"); 438 (*override_response_headers)->AddHeader( 439 "Location: " + redirect_on_headers_received_url_.spec()); 440 441 redirect_on_headers_received_url_ = GURL(); 442 443 if (!allowed_unsafe_redirect_url_.is_empty()) 444 *allowed_unsafe_redirect_url = allowed_unsafe_redirect_url_; 445 } 446 447 return OK; 448 } 449 450 void TestNetworkDelegate::OnBeforeRedirect(URLRequest* request, 451 const GURL& new_location) { 452 load_timing_info_before_redirect_ = LoadTimingInfo(); 453 request->GetLoadTimingInfo(&load_timing_info_before_redirect_); 454 has_load_timing_info_before_redirect_ = true; 455 EXPECT_FALSE(load_timing_info_before_redirect_.request_start_time.is_null()); 456 EXPECT_FALSE(load_timing_info_before_redirect_.request_start.is_null()); 457 458 int req_id = request->identifier(); 459 InitRequestStatesIfNew(req_id); 460 event_order_[req_id] += "OnBeforeRedirect\n"; 461 EXPECT_TRUE(next_states_[req_id] & kStageBeforeRedirect) << 462 event_order_[req_id]; 463 next_states_[req_id] = 464 kStageBeforeURLRequest | // HTTP redirects trigger this. 465 kStageBeforeSendHeaders | // Redirects from the network delegate do not 466 // trigger onBeforeURLRequest. 467 kStageCompletedError; 468 469 // A redirect can lead to a file or a data URL. In this case, we do not send 470 // headers. 471 next_states_[req_id] |= kStageResponseStarted; 472 } 473 474 void TestNetworkDelegate::OnResponseStarted(URLRequest* request) { 475 LoadTimingInfo load_timing_info; 476 request->GetLoadTimingInfo(&load_timing_info); 477 EXPECT_FALSE(load_timing_info.request_start_time.is_null()); 478 EXPECT_FALSE(load_timing_info.request_start.is_null()); 479 480 int req_id = request->identifier(); 481 InitRequestStatesIfNew(req_id); 482 event_order_[req_id] += "OnResponseStarted\n"; 483 EXPECT_TRUE(next_states_[req_id] & kStageResponseStarted) << 484 event_order_[req_id]; 485 next_states_[req_id] = kStageCompletedSuccess | kStageCompletedError; 486 if (request->status().status() == URLRequestStatus::FAILED) { 487 error_count_++; 488 last_error_ = request->status().error(); 489 } 490 } 491 492 void TestNetworkDelegate::OnRawBytesRead(const URLRequest& request, 493 int bytes_read) { 494 } 495 496 void TestNetworkDelegate::OnCompleted(URLRequest* request, bool started) { 497 int req_id = request->identifier(); 498 InitRequestStatesIfNew(req_id); 499 event_order_[req_id] += "OnCompleted\n"; 500 // Expect "Success -> (next_states_ & kStageCompletedSuccess)" 501 // is logically identical to 502 // Expect "!(Success) || (next_states_ & kStageCompletedSuccess)" 503 EXPECT_TRUE(!request->status().is_success() || 504 (next_states_[req_id] & kStageCompletedSuccess)) << 505 event_order_[req_id]; 506 EXPECT_TRUE(request->status().is_success() || 507 (next_states_[req_id] & kStageCompletedError)) << 508 event_order_[req_id]; 509 next_states_[req_id] = kStageURLRequestDestroyed; 510 completed_requests_++; 511 if (request->status().status() == URLRequestStatus::FAILED) { 512 error_count_++; 513 last_error_ = request->status().error(); 514 } else if (request->status().status() == URLRequestStatus::CANCELED) { 515 canceled_requests_++; 516 } else { 517 DCHECK_EQ(URLRequestStatus::SUCCESS, request->status().status()); 518 } 519 } 520 521 void TestNetworkDelegate::OnURLRequestDestroyed(URLRequest* request) { 522 int req_id = request->identifier(); 523 InitRequestStatesIfNew(req_id); 524 event_order_[req_id] += "OnURLRequestDestroyed\n"; 525 EXPECT_TRUE(next_states_[req_id] & kStageURLRequestDestroyed) << 526 event_order_[req_id]; 527 next_states_[req_id] = kStageDestruction; 528 destroyed_requests_++; 529 } 530 531 void TestNetworkDelegate::OnPACScriptError(int line_number, 532 const base::string16& error) { 533 } 534 535 NetworkDelegate::AuthRequiredResponse TestNetworkDelegate::OnAuthRequired( 536 URLRequest* request, 537 const AuthChallengeInfo& auth_info, 538 const AuthCallback& callback, 539 AuthCredentials* credentials) { 540 load_timing_info_before_auth_ = LoadTimingInfo(); 541 request->GetLoadTimingInfo(&load_timing_info_before_auth_); 542 has_load_timing_info_before_auth_ = true; 543 EXPECT_FALSE(load_timing_info_before_auth_.request_start_time.is_null()); 544 EXPECT_FALSE(load_timing_info_before_auth_.request_start.is_null()); 545 546 int req_id = request->identifier(); 547 InitRequestStatesIfNew(req_id); 548 event_order_[req_id] += "OnAuthRequired\n"; 549 EXPECT_TRUE(next_states_[req_id] & kStageAuthRequired) << 550 event_order_[req_id]; 551 next_states_[req_id] = kStageBeforeSendHeaders | 552 kStageAuthRequired | // For example, proxy auth followed by server auth. 553 kStageHeadersReceived | // Request canceled by delegate simulates empty 554 // response. 555 kStageResponseStarted | // data: URLs do not trigger sending headers 556 kStageBeforeRedirect | // a delegate can trigger a redirection 557 kStageCompletedError; // request cancelled before callback 558 return NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; 559 } 560 561 bool TestNetworkDelegate::OnCanGetCookies(const URLRequest& request, 562 const CookieList& cookie_list) { 563 bool allow = true; 564 if (cookie_options_bit_mask_ & NO_GET_COOKIES) 565 allow = false; 566 567 if (!allow) { 568 blocked_get_cookies_count_++; 569 } 570 571 return allow; 572 } 573 574 bool TestNetworkDelegate::OnCanSetCookie(const URLRequest& request, 575 const std::string& cookie_line, 576 CookieOptions* options) { 577 bool allow = true; 578 if (cookie_options_bit_mask_ & NO_SET_COOKIE) 579 allow = false; 580 581 if (!allow) { 582 blocked_set_cookie_count_++; 583 } else { 584 set_cookie_count_++; 585 } 586 587 return allow; 588 } 589 590 bool TestNetworkDelegate::OnCanAccessFile(const URLRequest& request, 591 const base::FilePath& path) const { 592 return can_access_files_; 593 } 594 595 bool TestNetworkDelegate::OnCanThrottleRequest( 596 const URLRequest& request) const { 597 return can_throttle_requests_; 598 } 599 600 int TestNetworkDelegate::OnBeforeSocketStreamConnect( 601 SocketStream* socket, 602 const CompletionCallback& callback) { 603 return OK; 604 } 605 606 // static 607 std::string ScopedCustomUrlRequestTestHttpHost::value_("127.0.0.1"); 608 609 ScopedCustomUrlRequestTestHttpHost::ScopedCustomUrlRequestTestHttpHost( 610 const std::string& new_value) 611 : old_value_(value_), 612 new_value_(new_value) { 613 value_ = new_value_; 614 } 615 616 ScopedCustomUrlRequestTestHttpHost::~ScopedCustomUrlRequestTestHttpHost() { 617 DCHECK_EQ(value_, new_value_); 618 value_ = old_value_; 619 } 620 621 // static 622 const std::string& ScopedCustomUrlRequestTestHttpHost::value() { 623 return value_; 624 } 625 626 TestJobInterceptor::TestJobInterceptor() : main_intercept_job_(NULL) { 627 } 628 629 URLRequestJob* TestJobInterceptor::MaybeCreateJob( 630 URLRequest* request, 631 NetworkDelegate* network_delegate) const { 632 URLRequestJob* job = main_intercept_job_; 633 main_intercept_job_ = NULL; 634 return job; 635 } 636 637 void TestJobInterceptor::set_main_intercept_job(URLRequestJob* job) { 638 main_intercept_job_ = job; 639 } 640 641 } // namespace net 642