1// Copyright (c) 2011 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#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_REQUEST_HANDLER_H_
6#define CONTENT_BROWSER_APPCACHE_APPCACHE_REQUEST_HANDLER_H_
7
8#include "base/compiler_specific.h"
9#include "base/supports_user_data.h"
10#include "content/browser/appcache/appcache_entry.h"
11#include "content/browser/appcache/appcache_host.h"
12#include "content/common/content_export.h"
13#include "content/public/common/resource_type.h"
14
15namespace net {
16class NetworkDelegate;
17class URLRequest;
18class URLRequestJob;
19}  // namespace net
20
21namespace content {
22class AppCacheRequestHandlerTest;
23class AppCacheURLRequestJob;
24
25// An instance is created for each net::URLRequest. The instance survives all
26// http transactions involved in the processing of its net::URLRequest, and is
27// given the opportunity to hijack the request along the way. Callers
28// should use AppCacheHost::CreateRequestHandler to manufacture instances
29// that can retrieve resources for a particular host.
30class CONTENT_EXPORT AppCacheRequestHandler
31    : public base::SupportsUserData::Data,
32      public AppCacheHost::Observer,
33      public AppCacheStorage::Delegate  {
34 public:
35  virtual ~AppCacheRequestHandler();
36
37  // These are called on each request intercept opportunity.
38  AppCacheURLRequestJob* MaybeLoadResource(
39      net::URLRequest* request, net::NetworkDelegate* network_delegate);
40  AppCacheURLRequestJob* MaybeLoadFallbackForRedirect(
41      net::URLRequest* request,
42      net::NetworkDelegate* network_delegate,
43      const GURL& location);
44  AppCacheURLRequestJob* MaybeLoadFallbackForResponse(
45      net::URLRequest* request, net::NetworkDelegate* network_delegate);
46
47  void GetExtraResponseInfo(int64* cache_id, GURL* manifest_url);
48
49  // Methods to support cross site navigations.
50  void PrepareForCrossSiteTransfer(int old_process_id);
51  void CompleteCrossSiteTransfer(int new_process_id, int new_host_id);
52
53  static bool IsMainResourceType(ResourceType type) {
54    return IsResourceTypeFrame(type) ||
55           type == RESOURCE_TYPE_SHARED_WORKER;
56  }
57
58 private:
59  friend class AppCacheHost;
60
61  // Callers should use AppCacheHost::CreateRequestHandler.
62  AppCacheRequestHandler(AppCacheHost* host, ResourceType resource_type);
63
64  // AppCacheHost::Observer override
65  virtual void OnDestructionImminent(AppCacheHost* host) OVERRIDE;
66
67  // Helpers to instruct a waiting job with what response to
68  // deliver for the request we're handling.
69  void DeliverAppCachedResponse(const AppCacheEntry& entry, int64 cache_id,
70                                int64 group_id, const GURL& manifest_url,
71                                bool is_fallback,
72                                const GURL& namespace_entry_url);
73  void DeliverNetworkResponse();
74  void DeliverErrorResponse();
75
76  // Helper to retrieve a pointer to the storage object.
77  AppCacheStorage* storage() const;
78
79  bool is_main_resource() const {
80    return IsMainResourceType(resource_type_);
81  }
82
83  // Main-resource loading -------------------------------------
84  // Frame and SharedWorker main resources are handled here.
85
86  void MaybeLoadMainResource(net::URLRequest* request,
87                             net::NetworkDelegate* network_delegate);
88
89  // AppCacheStorage::Delegate methods
90  virtual void OnMainResponseFound(
91      const GURL& url, const AppCacheEntry& entry,
92      const GURL& fallback_url, const AppCacheEntry& fallback_entry,
93      int64 cache_id, int64 group_id, const GURL& mainfest_url) OVERRIDE;
94
95  // Sub-resource loading -------------------------------------
96  // Dedicated worker and all manner of sub-resources are handled here.
97
98  void MaybeLoadSubResource(net::URLRequest* request,
99                            net::NetworkDelegate* network_delegate);
100  void ContinueMaybeLoadSubResource();
101
102  // AppCacheHost::Observer override
103  virtual void OnCacheSelectionComplete(AppCacheHost* host) OVERRIDE;
104
105  // Data members -----------------------------------------------
106
107  // What host we're servicing a request for.
108  AppCacheHost* host_;
109
110  // Frame vs subresource vs sharedworker loads are somewhat different.
111  ResourceType resource_type_;
112
113  // Subresource requests wait until after cache selection completes.
114  bool is_waiting_for_cache_selection_;
115
116  // Info about the type of response we found for delivery.
117  // These are relevant for both main and subresource requests.
118  int64 found_group_id_;
119  int64 found_cache_id_;
120  AppCacheEntry found_entry_;
121  AppCacheEntry found_fallback_entry_;
122  GURL found_namespace_entry_url_;
123  GURL found_manifest_url_;
124  bool found_network_namespace_;
125
126  // True if a cache entry this handler attempted to return was
127  // not found in the disk cache. Once set, the handler will take
128  // no action on all subsequent intercept opportunities, so the
129  // request and any redirects will be handled by the network library.
130  bool cache_entry_not_found_;
131
132  // True if this->MaybeLoadResource(...) has been called in the past.
133  bool maybe_load_resource_executed_;
134
135  // The job we use to deliver a response.
136  scoped_refptr<AppCacheURLRequestJob> job_;
137
138  // During a cross site navigation, we transfer ownership the AppcacheHost
139  // from the old processes structures over to the new structures.
140  scoped_ptr<AppCacheHost> host_for_cross_site_transfer_;
141
142  friend class content::AppCacheRequestHandlerTest;
143  DISALLOW_COPY_AND_ASSIGN(AppCacheRequestHandler);
144};
145
146}  // namespace content
147
148#endif  // CONTENT_BROWSER_APPCACHE_APPCACHE_REQUEST_HANDLER_H_
149