1// Copyright (c) 2010 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 "chrome/browser/net/connect_interceptor.h"
6
7#include "chrome/browser/net/predictor_api.h"
8#include "net/base/load_flags.h"
9
10namespace chrome_browser_net {
11
12ConnectInterceptor::ConnectInterceptor() {
13  net::URLRequest::RegisterRequestInterceptor(this);
14}
15
16ConnectInterceptor::~ConnectInterceptor() {
17  net::URLRequest::UnregisterRequestInterceptor(this);
18}
19
20net::URLRequestJob* ConnectInterceptor::MaybeIntercept(
21    net::URLRequest* request) {
22  GURL request_scheme_host(request->url().GetWithEmptyPath());
23
24  // Learn what URLs are likely to be needed during next startup.
25  LearnAboutInitialNavigation(request_scheme_host);
26
27  bool redirected_host = false;
28  if (request->referrer().empty()) {
29    if (request->url() != request->original_url()) {
30      // This request was completed with a redirect.
31      GURL original_scheme_host(request->original_url().GetWithEmptyPath());
32      if (request_scheme_host != original_scheme_host) {
33        redirected_host = true;
34        // Don't learn from redirects that take path as an argument, but do
35        // learn from short-hand typing entries, such as "cnn.com" redirects to
36        // "www.cnn.com".  We can't just check for has_path(), as a mere "/"
37        // will count as a path, so we check that the path is at most a "/"
38        // (1 character long) to decide the redirect is "definitive" and has no
39        // significant path.
40        // TODO(jar): It may be ok to learn from all redirects, as the adaptive
41        // system will not respond until several identical redirects have taken
42        // place.  Hence a use of a path (that changes) wouldn't really be
43        // learned from anyway.
44        if (request->original_url().path().length() <= 1) {
45          // TODO(jar): These definite redirects could be learned much faster.
46          LearnFromNavigation(original_scheme_host, request_scheme_host);
47        }
48      }
49    }
50  } else {
51    GURL referring_scheme_host = GURL(request->referrer()).GetWithEmptyPath();
52    bool is_subresource = !(request->load_flags() & net::LOAD_MAIN_FRAME);
53    // Learn about our referring URL, for use in the future.
54    if (is_subresource)
55      LearnFromNavigation(referring_scheme_host, request_scheme_host);
56    if (referring_scheme_host == request_scheme_host) {
57      // We've already made any/all predictions when we navigated to the
58      // referring host, so we can bail out here.
59      return NULL;
60    }
61  }
62
63  // Subresources for main frames usually get predicted when we detected the
64  // main frame request - way back in RenderViewHost::Navigate.  So only handle
65  // predictions now for subresources or for redirected hosts.
66  if ((request->load_flags() & net::LOAD_SUB_FRAME) || redirected_host)
67    PredictFrameSubresources(request_scheme_host);
68  return NULL;
69}
70
71net::URLRequestJob* ConnectInterceptor::MaybeInterceptResponse(
72    net::URLRequest* request) {
73  return NULL;
74}
75
76net::URLRequestJob* ConnectInterceptor::MaybeInterceptRedirect(
77    net::URLRequest* request,
78    const GURL& location) {
79  return NULL;
80}
81
82}  // namespace chrome_browser_net
83