#ifndef NET_PROXY_RESOLUTION_PAC_FILE_DECIDER_H_
#define NET_PROXY_RESOLUTION_PAC_FILE_DECIDER_H_
#include <stddef.h>
#include <memory>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_export.h"
#include "net/dns/host_resolver.h"
#include "net/log/net_log_with_source.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_with_annotation.h"
#include "net/proxy_resolution/proxy_resolver.h"
#include "url/gurl.h"
namespace net {
class DhcpPacFileFetcher;
class NetLog;
class ProxyResolver;
class PacFileFetcher;
struct NET_EXPORT_PRIVATE PacFileDataWithSource {
PacFileDataWithSource();
PacFileDataWithSource(const PacFileDataWithSource&);
~PacFileDataWithSource();
PacFileDataWithSource& operator=(const PacFileDataWithSource&);
scoped_refptr<PacFileData> data;
bool from_auto_detect = false;
};
class NET_EXPORT_PRIVATE PacFileDecider {
public:
PacFileDecider(PacFileFetcher* pac_file_fetcher,
DhcpPacFileFetcher* dhcp_pac_file_fetcher,
NetLog* net_log);
PacFileDecider(const PacFileDecider&) = delete;
PacFileDecider& operator=(const PacFileDecider&) = delete;
~PacFileDecider();
int Start(const ProxyConfigWithAnnotation& config,
const base::TimeDelta wait_delay,
bool fetch_pac_bytes,
CompletionOnceCallback callback);
void OnShutdown();
const ProxyConfigWithAnnotation& effective_config() const;
const PacFileDataWithSource& script_data() const;
void set_quick_check_enabled(bool enabled) { quick_check_enabled_ = enabled; }
bool quick_check_enabled() const { return quick_check_enabled_; }
private:
struct PacSource {
enum Type { WPAD_DHCP, WPAD_DNS, CUSTOM };
PacSource(Type type, const GURL& url) : type(type), url(url) {}
base::Value::Dict NetLogParams(const GURL& effective_pac_url) const;
Type type;
GURL url;
};
typedef std::vector<PacSource> PacSourceList;
enum State {
STATE_NONE,
STATE_WAIT,
STATE_WAIT_COMPLETE,
STATE_QUICK_CHECK,
STATE_QUICK_CHECK_COMPLETE,
STATE_FETCH_PAC_SCRIPT,
STATE_FETCH_PAC_SCRIPT_COMPLETE,
STATE_VERIFY_PAC_SCRIPT,
STATE_VERIFY_PAC_SCRIPT_COMPLETE,
};
PacSourceList BuildPacSourcesFallbackList(const ProxyConfig& config) const;
void OnIOCompletion(int result);
int DoLoop(int result);
int DoWait();
int DoWaitComplete(int result);
int DoQuickCheck();
int DoQuickCheckComplete(int result);
int DoFetchPacScript();
int DoFetchPacScriptComplete(int result);
int DoVerifyPacScript();
int DoVerifyPacScriptComplete(int result);
int TryToFallbackPacSource(int error);
State GetStartState() const;
void DetermineURL(const PacSource& pac_source, GURL* effective_pac_url);
const PacSource& current_pac_source() const;
void OnWaitTimerFired();
void DidComplete();
void Cancel();
raw_ptr<PacFileFetcher> pac_file_fetcher_;
raw_ptr<DhcpPacFileFetcher> dhcp_pac_file_fetcher_;
CompletionOnceCallback callback_;
size_t current_pac_source_index_ = 0u;
std::u16string pac_script_;
bool pac_mandatory_ = false;
bool have_custom_pac_url_;
std::vector<ProxyConfig::ProxyOverrideRule> proxy_override_rules_;
PacSourceList pac_sources_;
State next_state_ = STATE_NONE;
NetLogWithSource net_log_;
bool fetch_pac_bytes_ = false;
base::TimeDelta wait_delay_;
base::OneShotTimer wait_timer_;
net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
bool quick_check_enabled_ = true;
ProxyConfigWithAnnotation effective_config_;
PacFileDataWithSource script_data_;
std::unique_ptr<HostResolver::ResolveHostRequest> resolve_request_;
base::OneShotTimer quick_check_timer_;
};
}
#endif