summaryrefslogtreecommitdiff
path: root/chromium/content/browser/frame_host/navigation_request.h
blob: c8bb29613a1831eb725568ec6aa831858727b426 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
// Copyright 2014 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.

#ifndef CONTENT_BROWSER_FRAME_HOST_NAVIGATION_REQUEST_H_
#define CONTENT_BROWSER_FRAME_HOST_NAVIGATION_REQUEST_H_

#include <memory>

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/loader/navigation_url_loader_delegate.h"
#include "content/common/content_export.h"
#include "content/common/frame_message_enums.h"
#include "content/common/navigation_params.h"
#include "content/public/browser/navigation_throttle.h"

namespace content {

class FrameNavigationEntry;
class FrameTreeNode;
class NavigationControllerImpl;
class NavigationHandleImpl;
class NavigationURLLoader;
class NavigationData;
class NavigatorDelegate;
class ResourceRequestBody;
class SiteInstanceImpl;
class StreamHandle;
struct NavigationRequestInfo;

// PlzNavigate
// A UI thread object that owns a navigation request until it commits. It
// ensures the UI thread can start a navigation request in the
// ResourceDispatcherHost (that lives on the IO thread).
// TODO(clamy): Describe the interactions between the UI and IO thread during
// the navigation following its refactoring.
class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
 public:
  // Keeps track of the various stages of a NavigationRequest.
  enum NavigationState {
    // Initial state.
    NOT_STARTED = 0,

    // Waiting for a BeginNavigation IPC from the renderer in a
    // browser-initiated navigation. If there is no live renderer when the
    // request is created, this stage is skipped.
    WAITING_FOR_RENDERER_RESPONSE,

    // The request was sent to the IO thread.
    STARTED,

    // The response started on the IO thread and is ready to be committed. This
    // is one of the two final states for the request.
    RESPONSE_STARTED,

    // The request failed on the IO thread and an error page should be
    // displayed. This is one of the two final states for the request.
    FAILED,
  };

  // The SiteInstance currently associated with the navigation. Note that the
  // final value will only be known when the response is received, or the
  // navigation fails, as server redirects can modify the SiteInstance to use
  // for the navigation.
  enum class AssociatedSiteInstanceType {
    NONE = 0,
    CURRENT,
    SPECULATIVE,
  };

  // Creates a request for a browser-intiated navigation.
  static std::unique_ptr<NavigationRequest> CreateBrowserInitiated(
      FrameTreeNode* frame_tree_node,
      const GURL& dest_url,
      const Referrer& dest_referrer,
      const FrameNavigationEntry& frame_entry,
      const NavigationEntryImpl& entry,
      FrameMsg_Navigate_Type::Value navigation_type,
      LoFiState lofi_state,
      bool is_same_document_history_load,
      const base::TimeTicks& navigation_start,
      NavigationControllerImpl* controller);

  // Creates a request for a renderer-intiated navigation.
  // Note: |body| is sent to the IO thread when calling BeginNavigation, and
  // should no longer be manipulated afterwards on the UI thread.
  // TODO(clamy): see if ResourceRequestBody could be un-refcounted to avoid
  // threading subtleties.
  static std::unique_ptr<NavigationRequest> CreateRendererInitiated(
      FrameTreeNode* frame_tree_node,
      const CommonNavigationParams& common_params,
      const BeginNavigationParams& begin_params,
      scoped_refptr<ResourceRequestBody> body,
      int current_history_list_offset,
      int current_history_list_length);

  ~NavigationRequest() override;

  // Called on the UI thread by the Navigator to start the navigation.
  void BeginNavigation();

  const CommonNavigationParams& common_params() const { return common_params_; }

  const BeginNavigationParams& begin_params() const { return begin_params_; }

  const RequestNavigationParams& request_params() const {
    return request_params_;
  }

  NavigationURLLoader* loader_for_testing() const { return loader_.get(); }

  NavigationState state() const { return state_; }

  FrameTreeNode* frame_tree_node() const { return frame_tree_node_; }

  SiteInstanceImpl* source_site_instance() const {
    return source_site_instance_.get();
  }

  SiteInstanceImpl* dest_site_instance() const {
    return dest_site_instance_.get();
  }

  NavigationEntryImpl::RestoreType restore_type() const {
    return restore_type_;
  };

  bool is_view_source() const { return is_view_source_; };

  int bindings() const { return bindings_; };

  bool browser_initiated() const { return browser_initiated_ ; }

  void SetWaitingForRendererResponse() {
    DCHECK(state_ == NOT_STARTED);
    state_ = WAITING_FOR_RENDERER_RESPONSE;
  }

  AssociatedSiteInstanceType associated_site_instance_type() const {
    return associated_site_instance_type_;
  }
  void set_associated_site_instance_type(AssociatedSiteInstanceType type) {
    associated_site_instance_type_ = type;
  }

  NavigationHandleImpl* navigation_handle() const {
    return navigation_handle_.get();
  }

  // Creates a NavigationHandle. This should be called after any previous
  // NavigationRequest for the FrameTreeNode has been destroyed.
  void CreateNavigationHandle(int pending_nav_entry_id);

  // Transfers the ownership of the NavigationHandle to |render_frame_host|.
  // This should be called when the navigation is ready to commit, because the
  // NavigationHandle outlives the NavigationRequest. The NavigationHandle's
  // lifetime is the entire navigation, while the NavigationRequest is
  // destroyed when a navigation is ready for commit.
  void TransferNavigationHandleOwnership(
      RenderFrameHostImpl* render_frame_host);

 private:
  NavigationRequest(FrameTreeNode* frame_tree_node,
                    const CommonNavigationParams& common_params,
                    const BeginNavigationParams& begin_params,
                    const RequestNavigationParams& request_params,
                    scoped_refptr<ResourceRequestBody> body,
                    bool browser_initiated,
                    const FrameNavigationEntry* frame_navigation_entry,
                    const NavigationEntryImpl* navitation_entry);

  // NavigationURLLoaderDelegate implementation.
  void OnRequestRedirected(
      const net::RedirectInfo& redirect_info,
      const scoped_refptr<ResourceResponse>& response) override;
  void OnResponseStarted(
      const scoped_refptr<ResourceResponse>& response,
      std::unique_ptr<StreamHandle> body,
      std::unique_ptr<NavigationData> navigation_data) override;
  void OnRequestFailed(bool has_stale_copy_in_cache, int net_error) override;
  void OnRequestStarted(base::TimeTicks timestamp) override;

  // Called when the NavigationThrottles have been checked by the
  // NavigationHandle.
  void OnStartChecksComplete(NavigationThrottle::ThrottleCheckResult result);
  void OnRedirectChecksComplete(NavigationThrottle::ThrottleCheckResult result);
  void OnWillProcessResponseChecksComplete(
      NavigationThrottle::ThrottleCheckResult result);

  // Have a RenderFrameHost commit the navigation. The NavigationRequest will
  // be destroyed after this call.
  void CommitNavigation();

  // Called when the navigation is about to be sent to the IO thread.
  void InitializeServiceWorkerHandleIfNeeded();

  FrameTreeNode* frame_tree_node_;

  // Initialized on creation of the NavigationRequest. Sent to the renderer when
  // the navigation is ready to commit.
  // Note: When the navigation is ready to commit, the url in |common_params|
  // will be set to the final navigation url, obtained after following all
  // redirects.
  // Note: |common_params_| and |begin_params_| are not const as they can be
  // modified during redirects.
  // Note: |request_params_| is not const because service_worker_provider_id
  // and should_create_service_worker will be set in OnResponseStarted.
  CommonNavigationParams common_params_;
  BeginNavigationParams begin_params_;
  RequestNavigationParams request_params_;
  const bool browser_initiated_;

  NavigationState state_;


  // The parameters to send to the IO thread. |loader_| takes ownership of
  // |info_| after calling BeginNavigation.
  std::unique_ptr<NavigationRequestInfo> info_;

  std::unique_ptr<NavigationURLLoader> loader_;

  // These next items are used in browser-initiated navigations to store
  // information from the NavigationEntryImpl that is required after request
  // creation time.
  scoped_refptr<SiteInstanceImpl> source_site_instance_;
  scoped_refptr<SiteInstanceImpl> dest_site_instance_;
  NavigationEntryImpl::RestoreType restore_type_;
  bool is_view_source_;
  int bindings_;

  // The type of SiteInstance associated with this navigation.
  AssociatedSiteInstanceType associated_site_instance_type_;

  std::unique_ptr<NavigationHandleImpl> navigation_handle_;

  // Holds the ResourceResponse and the StreamHandle for the navigation while
  // the WillProcessResponse checks are performed by the NavigationHandle.
  scoped_refptr<ResourceResponse> response_;
  std::unique_ptr<StreamHandle> body_;

  DISALLOW_COPY_AND_ASSIGN(NavigationRequest);
};

}  // namespace content

#endif  // CONTENT_BROWSER_FRAME_HOST_NAVIGATION_REQUEST_H_