Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(382)

Unified Diff: ios/web/net/request_tracker_impl.h

Issue 1043243003: Upstream most of ios/web/net (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove accidentally-added clients Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ios/web/net/request_tracker_factory_impl.mm ('k') | ios/web/net/request_tracker_impl.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ios/web/net/request_tracker_impl.h
diff --git a/ios/web/net/request_tracker_impl.h b/ios/web/net/request_tracker_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..45aaa0361b195c8309904c2e20dc8c4a432de5f6
--- /dev/null
+++ b/ios/web/net/request_tracker_impl.h
@@ -0,0 +1,399 @@
+// 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 IOS_WEB_NET_REQUEST_TRACKER_IMPL_H_
+#define IOS_WEB_NET_REQUEST_TRACKER_IMPL_H_
+
+#import <Foundation/Foundation.h>
+#include <map>
+#include <set>
+
+#include "base/callback_forward.h"
+#include "base/mac/scoped_nsobject.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_vector.h"
+#include "base/memory/weak_ptr.h"
+#import "ios/net/request_tracker.h"
+#import "ios/web/net/crw_request_tracker_delegate.h"
+#include "ios/web/public/web_thread.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "url/gurl.h"
+
+@class SSLCarrier;
+@class CRWSSLCarrier;
+class SSLErrorInfo;
+struct TrackerCounts;
+
+namespace content {
+struct SSLStatus;
+}
+
+namespace net {
+class HttpResponseHeaders;
+class URLRequest;
+class URLRequestContext;
+class SSLInfo;
+class X509Certificate;
+}
+
+namespace web {
+
+class BrowserState;
+class CertificatePolicyCache;
+
+// Structure to capture the current state of a page.
+struct PageCounts {
+ public:
+ PageCounts() : finished(0),
+ finished_bytes(0),
+ unfinished(0),
+ unfinished_no_estimate(0),
+ unfinished_no_estimate_bytes_done(0),
+ unfinished_estimated_bytes_left(0),
+ unfinished_estimate_bytes_done(0),
+ largest_byte_size_known(0) {
+ };
+
+ // Count of finished requests.
+ uint64_t finished;
+ // Total bytes count dowloaded for all finished requests.
+ uint64_t finished_bytes;
+ // Count of unfinished requests.
+ uint64_t unfinished;
+ // Count of unfinished requests with unknown size.
+ uint64_t unfinished_no_estimate;
+ // Total bytes count dowloaded for unfinished requests of unknown size.
+ uint64_t unfinished_no_estimate_bytes_done;
+ // Count of unfinished requests with an estimated size.
+ uint64_t unfinished_estimated_bytes_left;
+ // Total bytes count dowloaded for unfinished requests with an estimated size.
+ uint64_t unfinished_estimate_bytes_done;
+ // Size of the request with the most bytes on the page.
+ uint64_t largest_byte_size_known;
+};
+
+// RequestTrackerImpl captures and stores all the network requests that
+// initiated from a particular tab. It only keeps the URLs and eventually, if
+// available, the expected length of the result and the length of the received
+// data so far as this is used to build a progress bar for a page.
+// Note that the Request tracker has no notion of a page, it only tracks the
+// requests by tab. In order for the tracker to know that a request is for a
+// page or a subresource it is necessary for the tab to call StartPageLoad()
+// with the URL of the page once it is known to avoid storing all the requests
+// forever.
+//
+// The consumer needs to implement the CRWRequestTrackerImplDelegate protocol
+// and needs to call StartPageLoad() and FinishPageLoad() to indicate the page
+// boundaries. StartPageLoad() will also have the side effect of clearing past
+// requests from memory. The consumer is assumed to be on the UI thread at all
+// times.
+//
+// RequestTrackerImpl objects are created and destroyed on the UI thread and
+// must be owned by some other object on the UI thread by way of a
+// scoped_refptr, as returned by the public static constructor method,
+// CreateTrackerForRequestGroupID. All consumer API methods will be called
+// through this pointer.
+
+class RequestTrackerImpl;
+
+struct RequestTrackerImplTraits {
+ static void Destruct(const RequestTrackerImpl* t);
+};
+
+class RequestTrackerImpl
+ : public base::RefCountedThreadSafe<RequestTrackerImpl,
+ RequestTrackerImplTraits>,
+ public net::RequestTracker {
+ public:
+#pragma mark Public Consumer API
+ // Consumer API methods should only be called on the UI thread.
+
+ // Create a new RequestTrackerImpl associated with a particular tab. The
+ // profile must be the one associated to the given tab. This method has to be
+ // called *once* per tab and needs to be called before triggering any network
+ // request. The caller of CreateTrackerForRequestGroupID owns the tracker, and
+ // this class also keeps a global map of all active trackers. When the owning
+ // object releases it, the class removes it from the global map.
+ static scoped_refptr<RequestTrackerImpl> CreateTrackerForRequestGroupID(
+ NSString* request_group_id,
+ BrowserState* browser_state,
+ net::URLRequestContextGetter* context_getter,
+ id<CRWRequestTrackerDelegate> delegate);
+
+ // The network layer has no way to know which network request is the primary
+ // one for a page load. The tab knows, either because it initiated the page
+ // load via the URL or received a callback informing it of the page change.
+ // Every time this happens the tab should call this method to clear the
+ // resources tracked.
+ // This will forget all the finished requests made before this URL in history.
+ // user_info is to be used by the consumer to store more additional specific
+ // info about the page, as an URL is not unique.
+ void StartPageLoad(const GURL& url, id user_info);
+
+ // In order to properly provide progress information the tracker needs to know
+ // when the page is fully loaded. |load_success| indicates if the page
+ // successfully loaded.
+ void FinishPageLoad(const GURL& url, bool load_success);
+
+ // Tells the tracker that history.pushState() or history.replaceState()
+ // changed the page URL.
+ void HistoryStateChange(const GURL& url);
+
+ // Marks the tracker as closed. An owner must call this before the tracker is
+ // deleted. Once closed, no further calls will be made to the delegate.
+ void Close();
+
+ // Call |callback| on the UI thread after any pending request cancellations
+ // have completed on the IO thread.
+ // This should be used to delete a profile for which all of the trackers
+ // that use the profile's request context are closed.
+ static void RunAfterRequestsCancel(const base::Closure& callback);
+
+ // Block until all pending IO thread activity has completed. This should only
+ // be used when Chrome is shutting down, and after all request trackers have
+ // had Close() called on them.
+ static void BlockUntilTrackersShutdown();
+
+#pragma mark Client utility methods.
+
+ // Finds the tracker given the tab ID. As calling this method involves a lock
+ // it is expected that the provider will call it only once.
+ // Returns a weak pointer, which should only be dereferenced on the IO thread.
+ // Returns NULL if no tracker exists for |request_group_id|.
+ static RequestTrackerImpl* GetTrackerForRequestGroupID(
+ NSString* request_group_id);
+
+ // Callback from the UI to allow or deny a particular certificate.
+ void ErrorCallback(CRWSSLCarrier* carrier, bool allow);
+
+ // Utility method for clients to post tasks to the IO thread from the UI
+ // thread.
+ void PostIOTask(const base::Closure& task);
+
+ // Utility method for clients to post tasks to the IO thread from the IO
+ // thread.
+ void ScheduleIOTask(const base::Closure& task);
+
+ // Utility method for clients to conditionally post tasks to the UI thread
+ // from the IO thread. The task will not be posted if the request tracker
+ // is in the process of closing (thus it "is open").
+ void PostUITaskIfOpen(const base::Closure& task);
+ // Static version of the method, where |tracker| is a RequestTrackerImpl
+ // passed as a base::WeakPtr<RequestTracker>.
+ static void PostUITaskIfOpen(const base::WeakPtr<RequestTracker> tracker,
+ const base::Closure& task);
+
+ // Sets the cache mode. Must be called from the UI thread.
+ void SetCacheModeFromUIThread(RequestTracker::CacheMode mode);
+
+#pragma mark Testing methods
+
+ void SetCertificatePolicyCacheForTest(web::CertificatePolicyCache* cache);
+
+#pragma mark Accessors used by internal classes and network clients.
+ int identifier() { return identifier_; }
+ bool has_mixed_content() { return has_mixed_content_; }
+
+ // RequestTracker implementation.
+ void StartRequest(net::URLRequest* request) override;
+ void CaptureHeaders(net::URLRequest* request) override;
+ void CaptureExpectedLength(const net::URLRequest* request,
+ uint64_t length) override;
+ void CaptureReceivedBytes(const net::URLRequest* request,
+ uint64_t byte_count) override;
+ void CaptureCertificatePolicyCache(
+ const net::URLRequest* request,
+ const SSLCallback& should_continue) override;
+ void StopRequest(net::URLRequest* request) override;
+ void StopRedirectedRequest(net::URLRequest* request) override;
+ void OnSSLCertificateError(const net::URLRequest* request,
+ const net::SSLInfo& ssl_info,
+ bool recoverable,
+ const SSLCallback& should_continue) override;
+ net::URLRequestContext* GetRequestContext() override;
+
+ private:
+ friend class base::RefCountedThreadSafe<RequestTrackerImpl>;
+ friend struct RequestTrackerImplTraits;
+
+#pragma mark Object lifecycle API
+ // Private. RequestTrackerImpls are created through
+ // CreateTrackerForRequestGroupID().
+ RequestTrackerImpl(NSString* request_group_id,
+ net::URLRequestContextGetter* context_getter,
+ id<CRWRequestTrackerDelegate> delegate);
+
+ void InitOnIOThread(
+ const scoped_refptr<web::CertificatePolicyCache>& policy_cache);
+
+ // Private destructor because the object is reference counted. A no-op; the
+ // useful destruction work happens in Destruct().
+ ~RequestTrackerImpl() override;
+
+ // Handles pre-destruction destruction tasks. This is invoked by
+ // RequestTrackerImplTraits::Destruct whenever the reference count of a
+ // RequestTrackerImpl is zero, and this will untimately delete the
+ // RequestTrackerImpl.
+ void Destruct();
+
+#pragma mark Private Provider API
+ // Private methods that implement provider API features. All are only called
+ // on the IO thread.
+
+ // Called when something has changed (network load progress or SSL status)
+ // that the consumer should know about. Notifications are asynchronous and
+ // batched.
+ void Notify();
+
+ // If no other notifications are pending, notifies the consumer of SSL status
+ // and load progress.
+ void StackNotification();
+
+ // Notify the consumer about the SSL status of this tracker's page load.
+ void SSLNotify();
+
+ // If the counts is for a request currently waiting for the user to approve it
+ // will reevaluate the approval.
+ void EvaluateSSLCallbackForCounts(TrackerCounts* counts);
+
+ // Loop through all the requests waiting for approval and invoke
+ // |-evaluateSSLCallbackForCounts:| on all the ones with an |UNKNOWN|
+ // judgment.
+ void ReevaluateCallbacksForAllCounts();
+
+ // To cancel a rejected request due to a SSL issue.
+ void CancelRequestForCounts(TrackerCounts* counts);
+
+ // Estimate the page load progress. Returns -1 if the progress didn't change
+ // since the last time this method was invoked.
+ float EstimatedProgress();
+
+ // The URL change notification is often late, therefore the mixed content
+ // status and the certificate policies may need to be recomputed.
+ void RecomputeMixedContent(const TrackerCounts* split_position);
+ void RecomputeCertificatePolicy(const TrackerCounts* split_position);
+
+ // Remove all finished request up to the last instance of |url|. If url is not
+ // found, this will clear all the requests.
+ void TrimToURL(const GURL& url, id user_info);
+
+ // Sets page_url_ to the new URL if it's a valid history state change (i.e.
+ // the URL's have the same origin) and if the tab is currently loading.
+ void HistoryStateChangeToURL(const GURL& full_url);
+
+ // Note that the page started by a call to Trim is no longer loading.
+ // |load_success| indicates if the page successfully loaded.
+ void StopPageLoad(const GURL& url, bool load_success);
+
+ // Cancels all the requests in |live_requests_|.
+ void CancelRequests();
+
+#pragma mark Private Consumer API
+ // Private methods that call into delegate methods.
+
+ // Notify* methods are posted to the UI thread by the provider API
+ // methods.
+
+ // Has the delegate handle |headers| for |request_url|.
+ void NotifyResponseHeaders(net::HttpResponseHeaders* headers,
+ const GURL& request_url);
+
+ // Notifies the deleage of certificate use.
+ void NotifyCertificateUsed(net::X509Certificate* certificate,
+ const std::string& host,
+ net::CertStatus status);
+
+ // Notifies the deleate of a load completion estimate.
+ void NotifyUpdatedProgress(float estimate);
+
+ // Has the delegate clear SSL certificates.
+ void NotifyClearCertificates();
+
+ // Notifies the delegate of an SSL status update.
+ void NotifyUpdatedSSLStatus(base::scoped_nsobject<CRWSSLCarrier> carrier);
+
+ // Calls the delegate method to present an SSL error interstitial.
+ void NotifyPresentSSLError(base::scoped_nsobject<CRWSSLCarrier> carrier,
+ bool recoverable);
+
+#pragma mark Internal utilities for task posting
+ // Posts |task| to |thread|. Must not be called from |thread|. If |thread| is
+ // the IO thread, silently returns if |is_closing_| is true.
+ void PostTask(const base::Closure& task, web::WebThread::ID thread);
+
+ // Posts |block| to |thread|, safely passing in |caller| to |block|.
+ void PostBlock(id caller, void (^block)(id), web::WebThread::ID thread);
+
+#pragma mark Other internal methods.
+ // Returns the current state of the page.
+ PageCounts pageCounts();
+
+ // Like description, but cannot be called from any thread. It must be called
+ // only from the IO thread.
+ NSString* UnsafeDescription();
+
+ // Generates a string unique to this RequestTrackerImpl to use with the
+ // CRWNetworkActivityIndicatorManager.
+ NSString* GetNetworkActivityKey();
+
+#pragma mark Non thread-safe fields, only accessed from the main thread.
+ // The RequestTrackerImpl delegate. All changes and access to this object
+ // should be done on the main thread.
+ id<CRWRequestTrackerDelegate> delegate_; // Weak.
+
+#pragma mark Non thread-safe fields, only accessed from the IO thread.
+ // All the tracked requests for the page, indexed by net::URLRequest (Cast as
+ // a void* to avoid the temptation of accessing it from the wrong thread).
+ // This map is not exhaustive: it is only meant to estimate the loading
+ // progress, and thus requests corresponding to old navigation events are not
+ // in it.
+ std::map<const void*, TrackerCounts*> counts_by_request_;
+ // All the live requests associated with the tracker.
+ std::set<net::URLRequest*> live_requests_;
+ // A list of all the TrackerCounts, including the finished ones.
+ ScopedVector<TrackerCounts> counts_;
+ // The system shall never allow the page load estimate to go back.
+ float previous_estimate_;
+ // Index of the first request to consider for building the estimation.
+ unsigned int estimate_start_index_;
+ // How many notifications are currently queued, to avoid notifying too often.
+ int notification_depth_;
+ // The tracker containing the error currently presented to the user.
+ TrackerCounts* current_ssl_error_;
+ // Set to |YES| if the page has mixed content
+ bool has_mixed_content_;
+ // Set to true if between TrimToURL and StopPageLoad.
+ bool is_loading_;
+ // Set to true in TrimToURL if starting a new estimate round. Set to false by
+ // StartRequest once the new round is started.
+ bool new_estimate_round_;
+
+#pragma mark Other fields.
+ scoped_refptr<web::CertificatePolicyCache> policy_cache_;
+ // If |true| all the requests should be static file requests, otherwise all
+ // the requests should be network requests. This is a constant initialized
+ // in the constructor and read in IO and UI threads.
+ const bool is_for_static_file_requests_;
+
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
+ // Current page URL, as far as we know.
+ GURL page_url_;
+ // Userinfo attached to the page, passed back by the delegate.
+ base::scoped_nsobject<id> user_info_;
+ // A tracker identifier (a simple increasing number) used to store
+ // certificates.
+ int identifier_;
+ // The string that identifies the tab this tracker serves. Used to index
+ // g_trackers.
+ base::scoped_nsobject<NSString> request_group_id_;
+ // Flag to synchronize deletion and callback creation. Lives on the IO thread.
+ // True when this tracker has beed Close()d. If this is the case, no further
+ // references to it should be generated (for example by binding it into a
+ // callback), and the expectation is that it will soon be deleted.
+ bool is_closing_;
+};
+
+} // namespace web
+
+#endif // IOS_WEB_NET_REQUEST_TRACKER_IMPL_H_
« no previous file with comments | « ios/web/net/request_tracker_factory_impl.mm ('k') | ios/web/net/request_tracker_impl.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698