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 #ifndef NET_PROXY_RESOLUTION_PAC_FILE_FETCHER_IMPL_H_ 6 #define NET_PROXY_RESOLUTION_PAC_FILE_FETCHER_IMPL_H_ 7 8 #include <stddef.h> 9 10 #include <memory> 11 #include <string> 12 13 #include "base/compiler_specific.h" 14 #include "base/macros.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/memory/weak_ptr.h" 17 #include "base/strings/string16.h" 18 #include "base/time/time.h" 19 #include "net/base/completion_once_callback.h" 20 #include "net/base/isolation_info.h" 21 #include "net/base/net_export.h" 22 #include "net/proxy_resolution/pac_file_fetcher.h" 23 #include "net/traffic_annotation/network_traffic_annotation.h" 24 #include "net/url_request/url_request.h" 25 26 class GURL; 27 28 namespace net { 29 30 class URLRequestContext; 31 32 // Implementation of PacFileFetcher that downloads scripts using the 33 // specified request context. 34 class NET_EXPORT PacFileFetcherImpl : public PacFileFetcher, 35 public URLRequest::Delegate { 36 public: 37 // Creates a PacFileFetcher that issues requests through 38 // |url_request_context|. |url_request_context| must remain valid for the 39 // lifetime of PacFileFetcherImpl. 40 // Note that while a request is in progress, we will be holding a reference 41 // to |url_request_context|. Be careful not to create cycles between the 42 // fetcher and the context; you can break such cycles by calling Cancel(). 43 // 44 // Fetch() supports the following URL schemes, provided the underlying 45 // |url_request_context| also supports them: 46 // 47 // * http:// 48 // * https:// 49 // * ftp:// 50 // * data: 51 static std::unique_ptr<PacFileFetcherImpl> Create( 52 URLRequestContext* url_request_context); 53 54 ~PacFileFetcherImpl() override; 55 56 // Used by unit-tests to modify the default limits. 57 base::TimeDelta SetTimeoutConstraint(base::TimeDelta timeout); 58 size_t SetSizeConstraint(size_t size_bytes); 59 60 void OnResponseCompleted(URLRequest* request, int net_error); 61 62 // PacFileFetcher methods: 63 int Fetch(const GURL& url, 64 base::string16* text, 65 CompletionOnceCallback callback, 66 const NetworkTrafficAnnotationTag traffic_annotation) override; 67 void Cancel() override; 68 URLRequestContext* GetRequestContext() const override; 69 void OnShutdown() override; 70 71 // URLRequest::Delegate methods: 72 void OnReceivedRedirect(URLRequest* request, 73 const RedirectInfo& redirect_info, 74 bool* defer_redirect) override; 75 void OnAuthRequired(URLRequest* request, 76 const AuthChallengeInfo& auth_info) override; 77 void OnSSLCertificateError(URLRequest* request, 78 int net_error, 79 const SSLInfo& ssl_info, 80 bool is_hsts_ok) override; 81 void OnResponseStarted(URLRequest* request, int net_error) override; 82 void OnReadCompleted(URLRequest* request, int num_bytes) override; 83 isolation_info_for_testing()84 const IsolationInfo& isolation_info_for_testing() { return isolation_info_; } 85 86 private: 87 enum { kBufSize = 4096 }; 88 89 explicit PacFileFetcherImpl(URLRequestContext* url_request_context); 90 91 // Returns true if |url| has an acceptable URL scheme (i.e. http://, https://, 92 // etc). 93 bool IsUrlSchemeAllowed(const GURL& url) const; 94 95 // Read more bytes from the response. 96 void ReadBody(URLRequest* request); 97 98 // Handles a response from Read(). Returns true if we should continue trying 99 // to read. |num_bytes| is 0 for EOF, and < 0 on errors. 100 bool ConsumeBytesRead(URLRequest* request, int num_bytes); 101 102 // Called once the request has completed to notify the caller of 103 // |response_code_| and |response_text_|. 104 void FetchCompleted(); 105 106 // Clear out the state for the current request. 107 void ResetCurRequestState(); 108 109 // Callback for time-out task of request with id |id|. 110 void OnTimeout(int id); 111 112 // The context used for making network requests. Set to nullptr by 113 // OnShutdown. 114 URLRequestContext* url_request_context_; 115 116 // Transient IsolationInfo used to fetch PAC scripts. 117 const IsolationInfo isolation_info_; 118 119 // Buffer that URLRequest writes into. 120 scoped_refptr<IOBuffer> buf_; 121 122 // The next ID to use for |cur_request_| (monotonically increasing). 123 int next_id_; 124 125 // The current (in progress) request, or NULL. 126 std::unique_ptr<URLRequest> cur_request_; 127 128 // State for current request (only valid when |cur_request_| is not NULL): 129 130 // Unique ID for the current request. 131 int cur_request_id_; 132 133 // Callback to invoke on completion of the fetch. 134 CompletionOnceCallback callback_; 135 136 // Holds the error condition that was hit on the current request, or OK. 137 int result_code_; 138 139 // Holds the bytes read so far. Will not exceed |max_response_bytes|. 140 std::string bytes_read_so_far_; 141 142 // This buffer is owned by the owner of |callback|, and will be filled with 143 // UTF16 response on completion. 144 base::string16* result_text_; 145 146 // The maximum number of bytes to allow in responses. 147 size_t max_response_bytes_; 148 149 // The maximum amount of time to wait for download to complete. 150 base::TimeDelta max_duration_; 151 152 // The time that the fetch started. 153 base::TimeTicks fetch_start_time_; 154 155 // The time that the first byte was received. 156 base::TimeTicks fetch_time_to_first_byte_; 157 158 // Factory for creating the time-out task. This takes care of revoking 159 // outstanding tasks when |this| is deleted. 160 base::WeakPtrFactory<PacFileFetcherImpl> weak_factory_{this}; 161 162 DISALLOW_COPY_AND_ASSIGN(PacFileFetcherImpl); 163 }; 164 165 } // namespace net 166 167 #endif // NET_PROXY_RESOLUTION_PAC_FILE_FETCHER_IMPL_H_ 168