| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2007 The WebRTC Project Authors. All rights reserved. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license | |
| 5 * that can be found in the LICENSE file in the root of the source | |
| 6 * tree. An additional intellectual property rights grant can be found | |
| 7 * in the file PATENTS. All contributing project authors may | |
| 8 * be found in the AUTHORS file in the root of the source tree. | |
| 9 */ | |
| 10 | |
| 11 #include <memory> | |
| 12 | |
| 13 #include "webrtc/base/autodetectproxy.h" | |
| 14 #include "webrtc/base/checks.h" | |
| 15 #include "webrtc/base/httpcommon.h" | |
| 16 #include "webrtc/base/httpcommon-inl.h" | |
| 17 #include "webrtc/base/socketadapters.h" | |
| 18 #include "webrtc/base/ssladapter.h" | |
| 19 #include "webrtc/base/sslsocketfactory.h" | |
| 20 | |
| 21 namespace rtc { | |
| 22 | |
| 23 /////////////////////////////////////////////////////////////////////////////// | |
| 24 // ProxySocketAdapter | |
| 25 // TODO: Consider combining AutoDetectProxy and ProxySocketAdapter. I think | |
| 26 // the socket adapter is the more appropriate idiom for automatic proxy | |
| 27 // detection. We may or may not want to combine proxydetect.* as well. | |
| 28 /////////////////////////////////////////////////////////////////////////////// | |
| 29 | |
| 30 class ProxySocketAdapter : public AsyncSocketAdapter { | |
| 31 public: | |
| 32 ProxySocketAdapter(SslSocketFactory* factory, int family, int type) | |
| 33 : AsyncSocketAdapter(NULL), factory_(factory), family_(family), | |
| 34 type_(type), detect_(NULL) { | |
| 35 } | |
| 36 ~ProxySocketAdapter() override { | |
| 37 Close(); | |
| 38 } | |
| 39 | |
| 40 int Connect(const SocketAddress& addr) override { | |
| 41 RTC_DCHECK(NULL == detect_); | |
| 42 RTC_DCHECK(NULL == socket_); | |
| 43 remote_ = addr; | |
| 44 if (remote_.IsAnyIP() && remote_.hostname().empty()) { | |
| 45 LOG_F(LS_ERROR) << "Empty address"; | |
| 46 return SOCKET_ERROR; | |
| 47 } | |
| 48 Url<char> url("/", remote_.HostAsURIString(), remote_.port()); | |
| 49 detect_ = new AutoDetectProxy(factory_->agent_); | |
| 50 detect_->set_server_url(url.url()); | |
| 51 detect_->SignalWorkDone.connect(this, | |
| 52 &ProxySocketAdapter::OnProxyDetectionComplete); | |
| 53 detect_->Start(); | |
| 54 return SOCKET_ERROR; | |
| 55 } | |
| 56 int GetError() const override { | |
| 57 if (socket_) { | |
| 58 return socket_->GetError(); | |
| 59 } | |
| 60 return detect_ ? EWOULDBLOCK : EADDRNOTAVAIL; | |
| 61 } | |
| 62 int Close() override { | |
| 63 if (socket_) { | |
| 64 return socket_->Close(); | |
| 65 } | |
| 66 if (detect_) { | |
| 67 detect_->Destroy(false); | |
| 68 detect_ = NULL; | |
| 69 } | |
| 70 return 0; | |
| 71 } | |
| 72 ConnState GetState() const override { | |
| 73 if (socket_) { | |
| 74 return socket_->GetState(); | |
| 75 } | |
| 76 return detect_ ? CS_CONNECTING : CS_CLOSED; | |
| 77 } | |
| 78 | |
| 79 private: | |
| 80 // AutoDetectProxy Slots | |
| 81 void OnProxyDetectionComplete(SignalThread* thread) { | |
| 82 RTC_DCHECK(detect_ == thread); | |
| 83 Attach(factory_->CreateProxySocket(detect_->proxy(), family_, type_)); | |
| 84 detect_->Release(); | |
| 85 detect_ = NULL; | |
| 86 if (0 == AsyncSocketAdapter::Connect(remote_)) { | |
| 87 SignalConnectEvent(this); | |
| 88 } else if (!IsBlockingError(socket_->GetError())) { | |
| 89 SignalCloseEvent(this, socket_->GetError()); | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 SslSocketFactory* factory_; | |
| 94 int family_; | |
| 95 int type_; | |
| 96 SocketAddress remote_; | |
| 97 AutoDetectProxy* detect_; | |
| 98 }; | |
| 99 | |
| 100 /////////////////////////////////////////////////////////////////////////////// | |
| 101 // SslSocketFactory | |
| 102 /////////////////////////////////////////////////////////////////////////////// | |
| 103 | |
| 104 SslSocketFactory::SslSocketFactory(SocketFactory* factory, | |
| 105 const std::string& user_agent) | |
| 106 : factory_(factory), | |
| 107 agent_(user_agent), | |
| 108 autodetect_proxy_(true), | |
| 109 force_connect_(false), | |
| 110 logging_level_(LS_VERBOSE), | |
| 111 binary_mode_(false), | |
| 112 ignore_bad_cert_(false) { | |
| 113 } | |
| 114 | |
| 115 SslSocketFactory::~SslSocketFactory() = default; | |
| 116 | |
| 117 Socket* SslSocketFactory::CreateSocket(int type) { | |
| 118 return CreateSocket(AF_INET, type); | |
| 119 } | |
| 120 | |
| 121 Socket* SslSocketFactory::CreateSocket(int family, int type) { | |
| 122 return factory_->CreateSocket(family, type); | |
| 123 } | |
| 124 | |
| 125 AsyncSocket* SslSocketFactory::CreateAsyncSocket(int type) { | |
| 126 return CreateAsyncSocket(AF_INET, type); | |
| 127 } | |
| 128 | |
| 129 AsyncSocket* SslSocketFactory::CreateAsyncSocket(int family, int type) { | |
| 130 if (autodetect_proxy_) { | |
| 131 return new ProxySocketAdapter(this, family, type); | |
| 132 } else { | |
| 133 return CreateProxySocket(proxy_, family, type); | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 | |
| 138 AsyncSocket* SslSocketFactory::CreateProxySocket(const ProxyInfo& proxy, | |
| 139 int family, | |
| 140 int type) { | |
| 141 AsyncSocket* socket = factory_->CreateAsyncSocket(family, type); | |
| 142 if (!socket) | |
| 143 return NULL; | |
| 144 | |
| 145 // Binary logging happens at the lowest level | |
| 146 if (!logging_label_.empty() && binary_mode_) { | |
| 147 socket = new LoggingSocketAdapter(socket, logging_level_, | |
| 148 logging_label_.c_str(), binary_mode_); | |
| 149 } | |
| 150 | |
| 151 if (proxy.type) { | |
| 152 AsyncSocket* proxy_socket = 0; | |
| 153 if (proxy_.type == PROXY_SOCKS5) { | |
| 154 proxy_socket = new AsyncSocksProxySocket(socket, proxy.address, | |
| 155 proxy.username, proxy.password); | |
| 156 } else { | |
| 157 // Note: we are trying unknown proxies as HTTPS currently | |
| 158 AsyncHttpsProxySocket* http_proxy = | |
| 159 new AsyncHttpsProxySocket(socket, agent_, proxy.address, | |
| 160 proxy.username, proxy.password); | |
| 161 http_proxy->SetForceConnect(force_connect_ || !hostname_.empty()); | |
| 162 proxy_socket = http_proxy; | |
| 163 } | |
| 164 if (!proxy_socket) { | |
| 165 delete socket; | |
| 166 return NULL; | |
| 167 } | |
| 168 socket = proxy_socket; // for our purposes the proxy is now the socket | |
| 169 } | |
| 170 | |
| 171 if (!hostname_.empty()) { | |
| 172 std::unique_ptr<SSLAdapter> ssl_adapter(SSLAdapter::Create(socket)); | |
| 173 if (!ssl_adapter) { | |
| 174 LOG_F(LS_ERROR) << "SSL unavailable"; | |
| 175 delete socket; | |
| 176 return NULL; | |
| 177 } | |
| 178 | |
| 179 ssl_adapter->set_ignore_bad_cert(ignore_bad_cert_); | |
| 180 if (ssl_adapter->StartSSL(hostname_.c_str(), true) != 0) { | |
| 181 LOG_F(LS_ERROR) << "SSL failed to start."; | |
| 182 return NULL; | |
| 183 } | |
| 184 socket = ssl_adapter.release(); | |
| 185 } | |
| 186 | |
| 187 // Regular logging occurs at the highest level | |
| 188 if (!logging_label_.empty() && !binary_mode_) { | |
| 189 socket = new LoggingSocketAdapter(socket, logging_level_, | |
| 190 logging_label_.c_str(), binary_mode_); | |
| 191 } | |
| 192 return socket; | |
| 193 } | |
| 194 | |
| 195 /////////////////////////////////////////////////////////////////////////////// | |
| 196 | |
| 197 } // namespace rtc | |
| OLD | NEW |