PageRenderTime 264ms CodeModel.GetById 141ms app.highlight 8ms RepoModel.GetById 113ms app.codeStats 0ms

/mordor/http/proxy.h

http://github.com/mozy/mordor
C Header | 143 lines | 81 code | 31 blank | 31 comment | 0 complexity | 8a2bfb15fa17e0353455d37ef5e7e2ab MD5 | raw file
  1#ifndef __MORDOR_HTTP_PROXY_H__
  2#define __MORDOR_HTTP_PROXY_H__
  3// Copyright (c) 2009 - Mozy, Inc.
  4
  5#include "mordor/uri.h"
  6
  7#ifdef WINDOWS
  8#include <winhttp.h>
  9#elif defined (OSX)
 10#include <queue>
 11#include <boost/thread.hpp>
 12#include <SystemConfiguration/SystemConfiguration.h>
 13#include "mordor/util.h"
 14#include "mordor/http/broker.h"
 15#endif
 16
 17namespace Mordor {
 18
 19class Stream;
 20
 21namespace HTTP {
 22
 23class RequestBroker;
 24
 25// Functions to use for the proxyForURIDg
 26
 27// The default; if you've done Config::loadFromEnvironment, this will use the
 28// HTTP_PROXY environment variable (passing it to proxyFromList)
 29std::vector<URI> proxyFromConfig(const URI &uri);
 30
 31// This parses proxy and bypassList according to the WINHTTP_PROXY_INFO
 32// structure; additionally if bypassList is blank, it will look for a !
 33// in the proxy, and use that to separate the proxy from the
 34// bypassList
 35std::vector<URI> proxyFromList(const URI &uri,
 36                               std::string proxy,
 37                               std::string bypassList = std::string());
 38
 39#ifdef WINDOWS
 40std::vector<URI> proxyFromMachineDefault(const URI &uri);
 41
 42struct ProxySettings
 43{
 44    bool autoDetect;
 45    std::string pacScript;
 46    std::string proxy;
 47    std::string bypassList;
 48};
 49
 50ProxySettings getUserProxySettings();
 51
 52class ProxyCache
 53{
 54public:
 55    ProxyCache(const std::string &userAgent = std::string());
 56    ~ProxyCache();
 57
 58    // Use the user's global proxy settings (which may specify a
 59    // proxy server, url to a configuration script or autodetection)
 60    std::vector<URI> proxyFromUserSettings(const URI &uri);
 61
 62    // Determine the Proxy URIs, if any, to use to reach the specified uri
 63    // If no pacScript url is specified the system will attempt to autodetect one
 64    bool autoDetectProxy(const URI &uri, const std::string &pacScript,
 65                         std::vector<URI> &proxyList);
 66
 67    // Depending on the settings the proxyFromUserSettings() method
 68    // may attempt to autodetect a proxy.
 69    // This autodetection can be slow, so the results are cached.
 70    // This method should be called if network configuration changes are
 71    // detected to force a new discovery
 72    static void resetDetectionResultCache();
 73
 74private:
 75    HINTERNET m_hHttpSession;
 76
 77    // The follow members are static so that the cache state can be shared by
 78    // all of the ProxyCache instances. This cache is invalided by calling
 79    // resetDetectionResultCache(), defined above.
 80    //
 81    // The lock held when accessing the static member variables.
 82    static boost::mutex s_cacheMutex;
 83
 84    // True if WPAD failed.
 85    static bool s_failedAutoDetect;
 86
 87    // The list of failed PAC file URLs.
 88    static std::set<std::string> s_invalidConfigURLs;
 89};
 90
 91#elif defined (OSX)
 92
 93class ProxyCache
 94{
 95public:
 96    ProxyCache(boost::shared_ptr<RequestBroker> requestBroker);
 97    ~ProxyCache();
 98
 99    std::vector<URI> proxyFromSystemConfiguration(const URI &uri);
100
101private:
102    ScopedCFRef<SCDynamicStoreRef> m_dynamicStore;
103        boost::shared_ptr<RequestBroker> m_requestBroker;
104    std::map<URI, ScopedCFRef<CFStringRef> > m_cachedScripts;
105
106    struct PacMessage {
107        ScopedCFRef<CFStringRef> pacScript;
108        ScopedCFRef<CFURLRef> targeturl;
109        ScopedCFRef<CFArrayRef> result;
110        bool processed;
111    };
112
113    boost::thread m_pacThread;
114    boost::condition_variable m_pacCond;
115    boost::mutex m_pacMut;
116    std::queue<PacMessage*> m_pacQueue;
117    bool m_pacThreadCancelled;
118
119    void runPacWorker();
120
121    std::vector<URI> proxyFromPacScript(CFURLRef cfurl, ScopedCFRef<CFURLRef> targeturl,
122        RequestBroker::ptr requestBroker,
123        std::map<URI, ScopedCFRef<CFStringRef> > &cachedScripts);
124    std::vector<URI> proxyFromCFArray(CFArrayRef proxies, ScopedCFRef<CFURLRef> targeturl,
125        RequestBroker::ptr requestBroker,
126        std::map<URI, ScopedCFRef<CFStringRef> > &cachedScripts);
127};
128#endif
129
130/// Establish a tunnel via an HTTPS proxy
131///
132/// @note This is *broken* if the ConnectionCache this RequestBroker is using
133///       attempts to re-use the connection.  We can't set forceNewConnection,
134///       because that would break NTLM authentication, and ConnectionCache
135///       hasn't been improved yet to do allowPipelining instead of
136///       forceNewConnection
137boost::shared_ptr<Stream>
138tunnel(boost::shared_ptr<RequestBroker> requestBroker, const URI &proxy,
139    const URI &target);
140
141}}
142
143#endif