13345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_PROXY_INIT_PROXY_RESOLVER_H_
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_PROXY_INIT_PROXY_RESOLVER_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <vector>
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string16.h"
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/time.h"
133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/timer.h"
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "googleurl/src/gurl.h"
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/completion_callback.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h"
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net {
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ProxyConfig;
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ProxyResolver;
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ProxyScriptFetcher;
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// InitProxyResolver is a helper class used by ProxyService to
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// initialize a ProxyResolver with the PAC script data specified
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// by a particular ProxyConfig.
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This involves trying to use PAC scripts in this order:
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen//   (1) WPAD (DNS) if auto-detect is on.
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   (2) Custom PAC script if a URL was given.
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// If no PAC script was successfully downloaded + parsed, then it fails with
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// a network error. Otherwise the proxy resolver is left initialized with
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the PAC script.
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Deleting InitProxyResolver while Init() is in progress, will
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// cancel the request.
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass InitProxyResolver {
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |resolver|, |proxy_script_fetcher| and |net_log| must remain valid for
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the lifespan of InitProxyResolver.
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  InitProxyResolver(ProxyResolver* resolver,
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    ProxyScriptFetcher* proxy_script_fetcher,
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    NetLog* net_log);
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Aborts any in-progress request.
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ~InitProxyResolver();
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Applies the PAC settings of |config| to |resolver_|.
523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If |wait_delay| is positive, the initialization will pause for this
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // amount of time before getting started.
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If |effective_config| is non-NULL, then on successful initialization of
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // |resolver_| the "effective" proxy settings we ended up using will be
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // written out to |*effective_config|. Note that this may differ from
573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // |config| since we will have stripped any manual settings, and decided
583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // whether to use auto-detect or the custom PAC URL. Finally, if auto-detect
593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // was used we may now have resolved that to a specific script URL.
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int Init(const ProxyConfig& config,
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick           const base::TimeDelta wait_delay,
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick           ProxyConfig* effective_config,
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           CompletionCallback* callback);
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  struct PacURL {
6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PacURL(bool auto_detect, const GURL& url)
6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        : auto_detect(auto_detect), url(url) {}
6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool auto_detect;
7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    GURL url;
7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  };
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  typedef std::vector<PacURL> UrlList;
7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  enum State {
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_NONE,
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    STATE_WAIT,
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    STATE_WAIT_COMPLETE,
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_FETCH_PAC_SCRIPT,
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_FETCH_PAC_SCRIPT_COMPLETE,
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_SET_PAC_SCRIPT,
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_SET_PAC_SCRIPT_COMPLETE,
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns ordered list of PAC urls to try for |config|.
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  UrlList BuildPacUrlsFallbackList(const ProxyConfig& config) const;
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void OnIOCompletion(int result);
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int DoLoop(int result);
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void DoCallback(int result);
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int DoWait();
933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int DoWaitComplete(int result);
943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int DoFetchPacScript();
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int DoFetchPacScriptComplete(int result);
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int DoSetPacScript();
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int DoSetPacScriptComplete(int result);
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Tries restarting using the next fallback PAC URL:
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // |pac_urls_[++current_pac_url_index]|.
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns OK and rewinds the state machine when there
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is something to try, otherwise returns |error|.
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int TryToFallbackPacUrl(int error);
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Gets the initial state (we skip fetching when the
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ProxyResolver doesn't |expect_pac_bytes()|.
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  State GetStartState() const;
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the current PAC URL we are fetching/testing.
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const PacURL& current_pac_url() const;
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void OnWaitTimerFired();
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void DidCompleteInit();
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Cancel();
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolver* resolver_;
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyScriptFetcher* proxy_script_fetcher_;
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CompletionCallbackImpl<InitProxyResolver> io_callback_;
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CompletionCallback* user_callback_;
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t current_pac_url_index_;
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Filled when the PAC script fetch completes.
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 pac_script_;
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  UrlList pac_urls_;
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  State next_state_;
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BoundNetLog net_log_;
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  base::TimeDelta wait_delay_;
1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  base::OneShotTimer<InitProxyResolver> wait_timer_;
1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ProxyConfig* effective_config_;
1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(InitProxyResolver);
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace net
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // NET_PROXY_INIT_PROXY_RESOLVER_H_
145