proxygen
ClientBootstrap.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
25 
27 
28 namespace wangle {
29 
30 /*
31  * A thin wrapper around Pipeline and AsyncSocket to match
32  * ServerBootstrap. On connect() a new pipeline is created.
33  */
34 template <typename Pipeline>
35 class ClientBootstrap : public BaseClientBootstrap<Pipeline>,
36  public folly::DestructorCheck {
38  public:
41  ClientBootstrap* bootstrap,
42  std::shared_ptr<folly::AsyncSocket> socket,
44  : promise_(std::move(promise)),
45  bootstrap_(bootstrap),
46  socket_(socket),
47  safety_(*bootstrap),
49  std::move(sslSessionEstablishedCallback)) {}
50 
51  void connectSuccess() noexcept override {
52  if (!safety_.destroyed()) {
53 
55  AsyncSSLSocket* sslSocket =
56  dynamic_cast<AsyncSSLSocket*>(socket_.get());
57  if (sslSocket && !sslSocket->getSSLSessionReused()) {
58  sslSessionEstablishedCallback_->onEstablished(
59  sslSocket->getSSLSession());
60  }
61  }
63  if (bootstrap_->getPipeline()) {
65  }
66  promise_.setValue(bootstrap_->getPipeline());
67  }
68  delete this;
69  }
70 
71  void connectErr(const folly::AsyncSocketException& ex) noexcept override {
72  promise_.setException(
73  folly::make_exception_wrapper<folly::AsyncSocketException>(ex));
74  delete this;
75  }
76  private:
79  std::shared_ptr<folly::AsyncSocket> socket_;
82  };
83 
84  public:
86  }
87 
89  std::shared_ptr<folly::IOThreadPoolExecutor> group) {
90  group_ = group;
91  return this;
92  }
93 
94  ClientBootstrap* bind(int port) {
95  port_ = port;
96  return this;
97  }
98 
100  const folly::SocketAddress& address,
101  std::chrono::milliseconds timeout =
102  std::chrono::milliseconds(0)) override {
103  auto base = (group_)
104  ? group_->getEventBase()
106  folly::Future<Pipeline*> retval((Pipeline*)nullptr);
107  base->runImmediatelyOrRunInEventBaseThreadAndWait([&](){
108  std::shared_ptr<folly::AsyncSocket> socket;
109  if (this->sslContext_) {
110  auto sslSocket = folly::AsyncSSLSocket::newSocket(
111  this->sslContext_, base, this->deferSecurityNegotiation_);
112  if (!this->sni_.empty()) {
113  sslSocket->setServerName(this->sni_);
114  }
115  if (this->sslSession_) {
116  sslSocket->setSSLSession(this->sslSession_, true);
117  }
118  socket = sslSocket;
119  } else {
120  socket = folly::AsyncSocket::newSocket(base);
121  }
123  retval = promise.getFuture();
124  socket->connect(
125  new ConnectCallback(
126  std::move(promise),
127  this,
128  socket,
130  address,
131  timeout.count());
132  });
133  return retval;
134  }
135 
136  ~ClientBootstrap() override = default;
137 
138  protected:
139  int port_;
140  std::shared_ptr<folly::IOThreadPoolExecutor> group_;
141 };
142 
144  : public BaseClientBootstrapFactory<BaseClientBootstrap<>> {
145  public:
147 
149  return std::make_unique<ClientBootstrap<DefaultPipeline>>();
150  }
151 };
152 
153 } // namespace wangle
std::unique_ptr< SSLSessionEstablishedCallback > SSLSessionEstablishedCallbackUniquePtr
SSLSessionEstablishedCallbackUniquePtr sslSessionEstablishedCallback_
EventBase * getEventBase() const
std::shared_ptr< folly::IOThreadPoolExecutor > group_
BaseClientBootstrap * sslSessionEstablishedCallback(SSLSessionEstablishedCallbackUniquePtr sslSessionEstablishedCallback)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
ClientBootstrap * bind(int port)
folly::Future< Pipeline * > connect(const folly::SocketAddress &address, std::chrono::milliseconds timeout=std::chrono::milliseconds(0)) override
requires E e noexcept(noexcept(s.error(std::move(e))))
void connectErr(const folly::AsyncSocketException &ex) noexceptoverride
static EventBaseManager * get()
static std::shared_ptr< AsyncSSLSocket > newSocket(const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, int fd, bool server=true, bool deferSecurityNegotiation=false)
std::enable_if<!std::is_same< T, folly::Unit >::value >::type transportActive()
Definition: Pipeline-inl.h:205
BaseClientBootstrap::Ptr newClient() override
~ClientBootstrap() override=default
std::shared_ptr< folly::AsyncSocket > socket_
Future< T > getFuture()
Definition: Promise-inl.h:97
NetworkSocket socket(int af, int type, int protocol)
Definition: NetOps.cpp:412
virtual bool getSSLSessionReused() const
static std::shared_ptr< AsyncSocket > newSocket(EventBase *evb)
Definition: AsyncSocket.h:281
folly::Promise< Pipeline * > promise_
SSL_SESSION * getSSLSession()
virtual void makePipeline(std::shared_ptr< folly::AsyncTransportWrapper > socket)
std::unique_ptr< BaseClientBootstrap > Ptr
folly::DestructorCheck::Safety safety_
ClientBootstrap * group(std::shared_ptr< folly::IOThreadPoolExecutor > group)
ConnectCallback(folly::Promise< Pipeline * > promise, ClientBootstrap *bootstrap, std::shared_ptr< folly::AsyncSocket > socket, SSLSessionEstablishedCallbackUniquePtr sslSessionEstablishedCallback)